Monday, December 23, 2013

Regexp Groups "Overflow" in Firefox

TL;DR: In Firefox regexps with 999 998+ groups  return false, no matter was the given string valid or not. It seems like a performance optimization, but theoretically can lead to security issues. I believe it should raise an exception instead of fooling the code.

Unrelated prehistory: Few weeks ago I was trying to XSS m.facebook.com location.hash validation with a timing attack.
(/^#~?!(?:\/?[\w\.-])+\/?(?:\?|$)/).test(location.hash)&&location.replace(...
I was trying to craft *long enough* regexp argument so I could get a spare second to replace the location.hash just before location.replace happens.
I'm no browser expert and don't comprehend how it works on low level - it didn't work out anyway, because it is single-threaded (with setTimeout timing attack works fine - try to XSS this page.)

The side-research is more interesting!

pic unrelated.

When I was testing FF i did notice, for huge payloads JS simply returns "false". For "/a/a..N times" it still was true but for N+1 times all of a sudden - false
Yeah, JS was like saying "TL;DR, hopefully it's false".

Wait, what?! Regexp can't just return a wrong result only because of the argument's length! Let's double check:

In Chrome

z=Array(999999).join('a');
console.log(/^([\w])+$/.test(z),z.length);
//true 999998

z=Array(999999+1).join('a');
console.log(/^([\w])+$/.test(z),z.length);
//true 999999


In FF

z=Array(999999).join('a');
console.log(/^([\w])+$/.test(z),z.length);
//true 999998

z=Array(999999+1).join('a');
console.log(/^([\w])+$/.test(z),z.length);
//false 999999

Apparently, thing is, after catching 999 998 regexp ([\w]) groups FF "gets tired" and returns false instead of finishing the work or raising an exception like Chrome does (RangeError: Maximum call stack size exceeded).

To turn it into an exploitable vulnerability you would need a JS regexp leading to something bad in "false" case - totally unlikely. But good place to start FF regexp "quirks" investigation.

P.S. Please fix me if I did not correctly understand the issue.

Saturday, December 14, 2013

How to send DM on Twitter w/o permission

I just recalled "SMS commands" feature and tried to send a DM (private, direct message) with "Share on Twitter"-button. It works!

But you know what's really cool? ANY app can send a DM on behalf of your account, by sending to API "d NAME TEXT". I just tested with Twitpic, as you can see it doesn't require any DM permissions.


Another guy claims he reported it before and twitter refused to fix.

Why is it a bug?
1) App is supposed to have Read & Write permission to access DMs. With this shortcut you can bypass that protection
2) DMs are easier to use for spam. User will barely notice it.
3) Also DMs don't show if it was sent with official client or a 3rd party OAuth client. Which is great for phishing.

API docs:
[no permission] https://dev.twitter.com/docs/api/1.1/post/direct_messages/new
[warns about permission] https://dev.twitter.com/docs/api/1.1/get/direct_messages/show