SSRF in external feed

Bug #1394820 reported by Hugh Davenport
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Aaron Wells
Aaron Wells
Aaron Wells
Aaron Wells
Aaron Wells

Bug Description

SSRF [1] (Server Side Request Forgery) is a vulnerability allowing requests to be made from the context of the server. This could allow an attacker to gain access to previously unknown data.

The vulnerability is present in the external feeds block. Steps to reproduce:

1. Create a new "External feeds block"
2. Configure the block.
3. Use the "Feed location" input to exploit the vulnerability.
Possible exploits:
- Port scanning, by using http://localhost:1/ through to http://localhost:65535/. Example responses:
  * Port closed: "The feed appears to be invalid. The error reported was: Failed to connect to localhost port 23: Connection refused"
  * Port open, but not HTTP: "The feed appears to be invalid. The error reported was: Recv failure: Connection reset by peer"
  * Port open, but HTTP: "The feed appears to be invalid. The error reported was: Invalid input: this is not valid XML"
- Local network scan, using to and other ranges:
  * Either by one of the above error messages, or timing attacks.
- Local DNS scan, using random dns entries:
  * No dns entry gives: "The feed appears to be invalid. The error reported was: Could not resolve host: ..."
  * valid dns entry would give an output as above.

You could also use this vulnerability to perform attacks on internal systems with
vulnerabilities exploitable only with GET requests, such as SQLi in query strings.

- On demo site, outbound traffic seems to only allow port 80 (maybe more, but not 81 and 22 which I tested). This may not be an issue on other mahara instances.

My recommendations would be:
- Disallow localhost, and any RFC1914 ip's (private LAN)
- Disallow unusual ports
- Rate limit requests
- Don't follow redirects to localhost and/or local LAN IP's, either
via HTTP redirects, or DNS records. (example of <?php header('Location: http://localhost:22'); ?>, or which resolves to

Hope that helps, let me know if there are any questions.




CVE References

Revision history for this message
Aaron Wells (u-aaronw) wrote :

I was just discussing this with Hugh. Limiting the allowed URLs to specific protocols, IP addresses, and ports, is fairly easy.

What's more difficult, is preventing redirection to bad URLs. That's because we use the PHP curl module's "CURLOPT_FOLLOWLOCATION" setting, which automatically follows redirects in the link.

So there are two possible solutions:

1. (Quick and dirty) Disable CURLOPT_FOLLOWLOCATION for RSS blocks. This is less desirable because it will also reduce functionality. A user might, for instance, have an RSS feed at but they're used to entering it as and letting the server redirect it to the right place.

2. We could add some code to be smarter than CURLOPT_FOLLOWLOCATION. One suitable library is the "safecurl" project, which is meant to be a drop-in replacement for the PHP curl_exec() command.

tags: added: externalfeed
Revision history for this message
Aaron Wells (u-aaronw) wrote :

Another thing we need to address is that CURL allows redirects from one protocol to another, via a redirect header. I've pushed a patch to prevent that:

Revision history for this message
Aaron Wells (u-aaronw) wrote :
Robert Lyon (robertl-9)
information type: Private Security → Public Security
Revision history for this message
Aaron Wells (u-aaronw) wrote :

In order to get something out with the 1.10.1 security release, we pushed patch 4029 which mitigates this issue by limiting what protocols CURL will use.

In the longer run we need to switch to the SafeCurl library. So I've spun off a separate bug 1397736 to track that.

Robert Lyon (robertl-9)
Changed in mahara:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public Security information  Edit
Everyone can see this security related information.

Other bug subscribers