← Back to team overview

mahara-contributors team mailing list archive

[Bug 1592276] Re: Still SSRF vulnerability in external feed

 

After doing a bit of researching into timing side channel attacks, I've
learned that adding a random sleep() doesn't actually add much security.
An attacker can just run multiple requests and average them out, and see
which ones take longer on average.

More secure is to make your app delay its response for a pre-set amount
of time, by making the request and then waiting out the rest of the pre-
set delay. This can either be done with what's called a "WCET" (worst
case execution time), i.e. pick a value that will be longer than a
successful request; or it can be an unpredictable deterministic value,
i.e. hash the input to an integer, and use that integer as your delay.

In testing, I found there was a dead giveaway when I found a valid DNS
entry with a bad port number -- the block would take the full CURL
timeout delay of 15 seconds to come back. So unfortunately, the only way
to prevent information from leaking via timing, is to make sure that
every unsuccessful request delays for 15 seconds before coming back. The
good news is that at least this won't negatively impact people who enter
a *correct* RSS URL. But it'll be annoying if you enter a URL with a
typo.

-- 
You received this bug notification because you are a member of Mahara
Contributors, which is subscribed to Mahara.
Matching subscriptions: Subscription for all Mahara Contributors -- please ask on #mahara-dev or mahara.org forum before editing or unsubscribing it!
https://bugs.launchpad.net/bugs/1592276

Title:
  Still SSRF vulnerability in external feed

Status in Mahara:
  Confirmed

Bug description:
  While taking another look at Bug 1397736 (SafeCURL) and Bug 1394820
  (SSRF in external feed) I realized there are some problems with the
  patch https://reviews.mahara.org/4029 that I filed for the SSRF bug.

  As a refresher here, the idea is that an attacker can do this:

  1. Log in to Mahara
  2. Create a page
  3. Put an "External Feed" block on the page
  4. Set the "Feed location" to "localhost:389"

  Expected result: This meaningless URL does nothing, and the block
  config harmlessly errors out and asks them for a valid URL.

  Actual result: They see an error message that tells them whether the
  web server has port 389 (unencrypted LDAP) open or not. If the error
  they see ends with "Recv failure: Connection reset by peer", they know
  the web server has a process listening on 389. If they see "Failed to
  connect to... Connection refused" they know it is not.

  It's called an SSRF (Server Side Request Forgery) attack (
  http://www.acunetix.com/blog/articles/server-side-request-forgery-
  vulnerability/ ). As Hugh pointed out on that bug, the biggest problem
  with this vulnerability is that a user can use it to scan the network
  the web server is on, checking for machine names, IP addresses, and
  port numbers.

  My patch 4029 was to add the "CURLOPT_PROTOCOLS" option to our Curl
  requests. This has the main effect of preventing an attacker from
  using an HTTP redirect to make Curl send a request to a non-HTTP
  protocol. But it doesn't at all mitigate all the information-gathering
  attacks, because it only limits the protocol section of the URL (i.e.
  "https://";) and the structure of the request Curl makes. Crucially, it
  does not limit the port of the URL, you can still enter
  "http://localhost:389";.

  As such, it didn't mitigate any of those information-gathering
  attacks.

To manage notifications about this bug go to:
https://bugs.launchpad.net/mahara/+bug/1592276/+subscriptions