Introducing: SafeURL - A set of SSRF Protection Libraries

Datetime:2016-08-23 03:22:50          Topic:          Share

Introducing: SafeURL - A set of SSRF Protection Libraries

Code by IncludeSec team, with contributions by our Intern Mohammad Al Amin

At Include Security, we believe that a reactive approach to security can fall short when it's not backed by proactive roots. We see new offensive tools for pen-testing and vulnerability analysis being created and released all the time. In regards to SSRF vulnerabilities, we saw an opportunity to release code for developers to assist in protecting against these sorts of security issues. So we're releasing a new set of language specific libraries to help developers effectively protect against SSRF issues. In this blog post, we'll introduce the concept of SafeURL; with details about how it works, as well as how developers can use it, and our plans for rewarding those who find vulnerabilities in it!

Overview

  1. Preface: Server Side Request Forgery
  2. Our Proposed Solution
  3. Installation
  4. Usage
  5. Demo and Bug Bounty Contest

Preface: Server Side Request Forgery

Server Side Request Forgery (SSRF) is a vulnerability that gives an attacker the ability to create requests from a vulnerable server. SSRF attacks are commonly used to target not only the host server itself, but also hosts on the internal network that would normally be inaccessible due to firewalls.

SSRF allows an attacker to:

  • Scan and attack systems from the internal network that are not normally accessible
  • Enumerate and attack services that are running on these hosts
  • Exploit host-based authentication services
As is the case with many web application vulnerabilities, SSRF is possible because of a lack of user input validation. For example, a web application that accepts a URL input in order to go fetch that resource from the internet can be given a valid URL such as http://google.com

But the application may also accept URLs such as:

  • http://localhost
  • http://10.0.0.1
  • file:///localhost/example.txt
  • 127.0.0.1:22

When those kinds of inputs are not validated, attackers are able to access internal resources that are not intended to be public.

Our Proposed Solution

SafeURL is a library, originally conceptualized as "SafeCURL" by Jack Whitton (aka @fin1te ), that protects against SSRF by validating each part of the URL against a white or black list before making the request. SafeURL can also be used to validate URLs. SafeURL intends to be a simple replacement for libcurl methods in PHP and Python as well as java.net.URLConnection in Scala.

The source for the libraries are available on our Github:

  1. SafeURL for PHP - Primarily developed by @fin1te
  2. SafeURL for Python - Ported by @nicolasrod
  3. SafeURL for Scala - Ported by @saelo

Other Mitigation Techniques

Our approach is focused on protection on the application layer. Other techniques used by some Silicon Valley companies to combat SSRF include:

  • Setting up wrappers for HTTP client calls which are forwarded to a single-purposed proxy that prevents it from talking to any internal hosts based on firewall rules as the HTTP requests are proxied
  • At the application server layer, hijack all socket connections to ensure they meet a developer configured policy by enforcing iptables rules or more advanced interactions with the app server's networking layer

Installation

PHP

SafeURL can be included in any PHP project by cloning the repository on our Github and importing it into your project.

Python

SafeURL can be used in Python apps by cloning the repository on our Github and importing it like this:

from safeurl import safeurl

Scala

To use SafeURL in Scala applications, clone the repository and store in the app/ folder of your Play application and import it.

import com.includesecurity.safeurl._

Usage

PHP

SafeURL is designed to be a drop-in replacement for the curl_exec() function in PHP. It can simply be replaced with SafeURL::execute() wrapped in a try {} catch {} block.

try { $url = "http://www.google.com"; $curlHandle = curl_init(); //Your usual cURL options curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (SafeURL)"); //Execute using SafeURL $response = SafeURL::execute($url, $curlHandle); } catch (Exception $e) { //URL wasn"t safe } Options such as white and black lists can be modified. For example:

$options = new Options(); $options->addToList("blacklist", "domain", "(.*)\.fin1te\.net"); $options->addToList("whitelist", "scheme", "ftp"); //This will now throw an InvalidDomainException $response = SafeURL::execute("http://example.com", $curlHandle, $options); //Whilst this will be allowed, and return the response $response = SafeURL::execute("ftp://example.com", $curlHandle, $options);

Python

SafeURL serves as a replacement for PyCurl in Python.

try: su = safeurl.SafeURL() res = su.execute("https://example.com";) except: print "Unexpected error:", sys.exc_info()

Example of modifying options:

try: sc = safeurl.SafeURL() opt = safeurl.Options() opt.clearList("whitelist") opt.clearList("blacklist") opt.setList("whitelist", [ "google.com" , "youtube.com"], "domain") su.setOptions(opt) res = su.execute("http://www.youtube.com") except: print "Unexpected error:", sys.exc_info()

Scala

SafeURL replaces the JVM Class URLConnection that is normally used in Scala.

try { val resp = SafeURL.fetch("http://google.com") val r = Await.result(resp, 500 millis) } catch { //URL wasnt safe }

Options:

SafeURL.defaultConfiguration.lists.ip.blacklist ::= "12.34.0.0/16" SafeURL.defaultConfiguration.lists.domain.blacklist ::= "example.com"

Demo, Bug Bounty Contest, and Further Contributions

An important question to ask is: Is SafeURL really safe? Don't take our word for it. Try to hack it yourself! We're hosting live demo apps in each language for anyone to try and bypass SafeURL and perform a successful SSRF attack. On each site there is a file called key.txt on the server's local filesystem with the following .htaccess policy:

<Files key.txt>
  Order deny,allow
  Deny from allow
  Allow from 127.0.0.1

  ErrorDocument 403 /oops.html
</Files>

If you can read the contents of the file through a flaw in SafeURL and tell us how you did it (patch plz?), we will contact you about your reward. As a thank you to the community, we're going to reward up to one Bitcoin for any security issues. If you find a non-security bug in the source of any of our libraries, please contact us as well you'll have our thanks and a shout-out.

The challenges are being hosted at the following URLs:

PHP: safeurl-php.excludesecurity.com

Python: safeurl-python.excludesecurity.com

Scala: safeurl-scala.excludesecurity.com

If you can contribute a Pull Request and port the SafeURL concept to other languages (such as Java, Ruby, C#, etc.) we could throw you you some Bitcoin as a thank you.

Good luck and thanks for helping us improve SafeURL!