Filtering outbound requests

To mitigate the risk of data loss and exposure, Tuleap filters outbound requests. The goal is to protect against a class of attack called Server Side Request Forgery (SSRF).

Any outbound requests made on information provided by a user is filtered, this notably includes:
  • webhooks

  • retrieval of continuous integration job status

  • import of JIRA projects and issues

What is filtered by default?

Tuleap filters all requests that are not directed to a public IP range by default:
  • for IPv6 requests that are not directed to a global unicast address is rejected (2000::/3)

  • for IPv4 requests that are not directed to a public network range are rejected. This includes the following IP ranges:

  • Broadcast addresses

  • Multicast addresses (224.0.0.0/4)

  • Loopback addresses (127.0.0.0/8)

  • Link local addresses (169.254.0.0/16)

  • Private-use addresses (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16)

How to add exceptions to the filters?

They are two ways to add exceptions to the filtering of outbound requests:
  • use your own proxy, in this case Tuleap will not attempt to filter the outbound requests and it will be your responsability

  • adjust the allow and deny lists to fit your needs

Defining an HTTP proxy for outbound requests

Tuleap allows you to define your own proxy via the sys_proxy setting. Note that in this case Tuleap will not attempt to do any filtering as it cannot know the transformations your own proxy might do.

You can set it using the Tuleap CLI on your server (replace proxy.example.com:3128 with your own value):

tuleap config-set sys_proxy proxy.example.com:3128

Adjusting the allow and deny filter lists

To determine if an outbound request is allowed Tuleap resolves the address and apply the following strategy:
  1. If the resolved address is present the allow list defined by the adminstrators, request is allowed

  2. If the resolved address is present the deny list defined by the adminstrators, request is rejected

  3. If the resolved address is present the default deny list, request is rejected

  4. If the request was not rejected by the previous filters, the request is allowed

The allow and deny lists defined by the administrators expect address ranges defined using the CIDR notation.

The allow and deny lists can be defined using the settings http_outbound_requests_allow_ranges and http_outbound_requests_deny_ranges.

For example, if you want to let outbound requests access the 172.16.100.0/24 and 192.168.50.0/24 ranges which are filtered by default:

tuleap config-set http_outbound_requests_allow_ranges '172.16.100.0/24,192.168.50.0/24'

If you want to have a stricter approach with a deny-all by default to let outbound requests only access the network ranges you have explicitly defined:

tuleap config-set http_outbound_requests_allow_ranges '172.16.100.0/24,192.168.50.0/24'
tuleap config-set http_outbound_requests_deny_ranges '0.0.0.0/0,::/0'

Changes made to the allow and deny lists requires to restart the tuleap service to be taken into account:

systemctl restart tuleap

If you are using a container, restart it.

How to detect a filtered outbound request?

Filtered outbound requests are logged with the reason explaining why they have been blocked. The information is logged into /var/log/tuleap/codendi_syslog or you log sink depending on your log configuration. The logs look like this:

A possible SSRF attempt was blocked: https://example.com/api/xml (Egress proxying is denied to host '192.0.2.1:443': The destination address (192.0.2.1) was denied by rule 'Deny: Not Global Unicast'. destination address was denied by rule, see error.)

Warnings are displayed in the site administration, you can hide them using the Tuleap CLI on the server:

tuleap config-set http_outbound_requests_filtered_alert 'never'
The filtering proxy will give you the following HTTP status code when a request is rejected:
  • 407: for requests that tries to access a not allowed address

  • 502: any network related errors that are a timeout when establishing the connection (e.g. a DNS resolution failure)

  • 504: a timeout when establishing the connection

Metrics about outbound requests can also be collected using Prometheus to give you the possibility to create alerts whenever a request is filtered.