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
and192.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:
If the resolved address is present the allow list defined by the adminstrators, request is allowed
If the resolved address is present the deny list defined by the adminstrators, request is rejected
If the resolved address is present the default deny list, request is rejected
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.