Facebook HTTP Parameter Renaming (0day) (Unfixable?)

1:57 AM

I have been participating in Facebook bug bounty this week
to find interesting bugs other than XSRF and XSS. Something so uncommon. A turn
out Facebook is full of them. I will blog about some of these bugs Facebook
declines to either payout or fix. One is HPP (HTTP Parameter Pollution); this
one is kind of interesting. Facebook is coded with pure PHP and PHP by itself
suffers from pollution issues by its nature. Facebook’s WAF is designed to
detect and stop HPP, if parameters are duplicate. Now that’s when Parameter
Renaming comes. When URL arguments including POST and Cookies are parsed in PHP
they use the parse_str function – it accepts strings like:

x=1&y=2

Note: Blogger coudnt let me write nullbytes so i write them as %0,0 so take it without a comma.

This function also accepts associative arrays such as:

x[0]=123&x[1]=456&[2]=456

When we specify only one bracket “[“and don’t close it, it will get converted
into an underscore. This means that the two strings below ($s1 and $2) create
identical associative arrays when parsed.

$s1 = “user_id=123”;$s2 = “user[id=123”;

parse_str($s1, $o1); parse_str($s2, $o2);

Now both $o1 & $o2 contain:

array(1){

[“user_id”]=>

string(3) “123” }

You know what that means, we can re-write any parameter
names with underscores on them using a square bracket (in this case the
redirect_uri parameter);

We can also do a similar trick with null bytes (%0,0).
However, in this case anything after the null byte in a parameter name gets
removed so both the strings below are parsed into the same array:

$user = 123

$userpleaseignoreme=123

Furthermore, Facebook’s WAF was filtering the QUERY_STRING
parameter in an attempt to prevent HTTP parameter pollution, now we can turn
requests like (in HPP):

account_ id=123&account_ id=456

into:

account_id=123&account[id=456

{Since PHP by its nature pick the last one to execute, the
second Parameter (account[id=456 which is equivalent to account_ id=456 for
PHP) will be chosen. }

Or into:

account_id=123&account_id%0,0ignoreme=456

and that’s what happened in this case, the redirect_uri (or
any other redirection parameter Facebook hosts) is being checked not to
redirect outside of Facebook, but turns out we can using this technique since
only the first parameter is being checked with that name,

So providing names like “redirect[uri=” or “redirect_uribullshit”
which is equivalent for PHP to redirect_uri, it is possible to perform HTTP
parameter renaming,

That is not an open redirection issue. It however could be a
linkshim evade, not sure. I reported this issue to Facebook and I am very happy
with their response, they were happy I informed them, the thing is the bug
bounty program works if there is at least one exploitation scerio which in this
case isn’t; it’s just an interesting bug. But this can be exploited with XSS or
even Session Fixation (which I don’t have at the moment) (please feel free to re-submit
this bug if you have found exploitation technique that is exploitable, would be
happy to know if you inform me how too :-D )

Fix: the simplest fix I recommend is for your WAF to recheck
the {$parameter} names and block if they contain either [ or %0,0 because
without those there seems to be no parameter renaming. To be honest, I taught
the null byte trick would be noticed by a WAF but It didn’t. More precisely
while submitting parameters, using array based tricks would still might bypass
that since the $_GET, $_POST and even the $_COOKIE global vars take arrays and
concatenates them.

Let’s say the session_id cookie var is set for the current
session, however, session[id is valid for 10 years. As soon as session_id
destroyed by the browser (when it closes the session regenerates or when the
user logs out) we end up with the single session[id in the browser which now
becomes the first cookie in the list,

Set-Cookie: session[id=EVIL;

Which also means session_id=evil; for php since browsers
respond cookie values both session[id=evil and consider them both to be unique,
however php uses one of them to understand who that user is, J.

About Paulos

I am currently specializing in application security and client side offensive exploit research. I really enjoy breaking things. I occasionally do bug bounties, with notable references such as Coinbase, Facebook,Twitter& more.