Archive for the XSS Category

NSA++, NoScript on Android

NSA++ (NoScript Anywhere Plus Plus, or NoScript 3.5 alpha for Android Native) has been in the works for a while now, and it’s finally ready for prime time, thanks also to the continuous help of the NLNet Foundation.

Even if it’s not as complete as its legacy Electrolysis-orphaned obsolete predecessor (NSA, designed for the now discontinued XUL Fennec, AKA Firefox 4 Mobile) yet, NSA++ already provides the best security you can get in any mobile browser: beside its trademark flexible script blocking facility, it features the first ever and still strongest XSS filter available, plus partial but functional portings of the unique ClearClick anti-Clickjacking technology and ABE’s firewall/LAN CSRF protection.

You can read more or try it with a recent Firefox Nightly (mobile or desktop, too!) on the NSA project page.

Universal XSS 0day in Adobe Flash controlled users’ Web accounts:

As useful as sandboxes are in restricting potentially buggy code to a small part of the operating system, they do nothing to minimize the damage that can be done by attacks that exploit universal XSS flaws, researchers said.

I was already preaching this four years ago: the more our assets move “in the cloud”, the less traditional security measures, meant to protecting just your local system, suffice.

The battlefield is the web now, and there’s no coming back…

ClearClick anti-Clickjacking on Android

NoScript 3.0a3 for Firefox Mobile is out, bringing three of the major “classic” NoScript features to your Android smartphones:

  1. Easy per-site active content permissions management.
  2. The first and most powerful anti-XSS (cross-site scripting) filter available in a web browser.
  3. ClearClick, the one and only effective client-side protection against Clickjackings available on the client side.

Still some road ahead for convergence between the desktop and the mobile versions, but we’re already past the biggest challenges…

A huge thanks to the NLNet foundation, and to many individuals, institutions and companies using NoScript, for their generous support to this project.

Classic ASP is the old server-side web scripting technology based on VBScript, now superseded by ASP.NET, which lots of developers, including myself, learned to hate in the nineties when, for mysterious reasons, a certain customer decided he needed the whole “Enterprise” Microsoft 3-tiers stack (IIS/COM+/SQL Server). Luckily enough, nobody asks you to build anything new using ASP these days (even though there’s always some insanely unmaintainable VBScript code out there which badly needs maintenance), but this technology, albeit agonizing, yet found a way to come back and make me sad again.

Some days ago this blog post, talking about a bypass method for NoScript’s Anti-XSS filter, called for my attention (not thanks to its author).

Even though it’s not very clear from that piece of writing, the issue at hand is quite simple but, in my opinion, outrageously stupid and annoying. I’m gonna call it “HomoXSSuality” (even though most LGBT people I know is neither simple, nor stupid nor annoying), because homoglyps and homophones conspire to make XSS (and SQL injection) attacks easier to pull.

Like any other server-side web programming framework, ASP gives developers some means to extract “parameters” (name/value pairs) from the HTTP requests, stored either in the query string or in the POST data. For instance, if an ASP script is invoked using the URL http://some.site.com/my_heroes.asp?name=Giorgio%20Maone&hero=%E1%BD%99%CF%80%CE%B1%CF%84%CE%AF%CE%B1, parameters can be extracted by code like this:

Dim Name, Hero
Name = Request("name")
Hero = Request("hero")

At runtime, the Name variable will contain “Giorgio Maone”, while Hero will be set to “Ὑπατία“. This contrived example show also how “special” characters, such as space or Greek alphabet letters, are escaped by standard percent encoding, i.e. by taking the UTF-8 hexadecimal representation of the string and prefixing each byte with a “%” character: specifically, “ ” translates to “%20”, and “Ὑπατία” to “%E1%BD%99%CF%80%CE%B1%CF%84%CE%AF%CE%B1″. This is the translation you can obtain from the encodeURIComponent() ECMAScript function, and the recommended way of escaping URLs.
An older and never standardized method, implemented by the now deprecated JavaScript escape() function, produces more or less the same output for ASCII strings, but uses the UTF-16 representation prefixed with “%u” for higher (beyond ASCII) Unicode strings: for instance, “ ” still stays “%20”, but “Ὑπατία” becomes “%u1F59%u03C0%u03B1%u03C4%u03AF%u03B1″.

NoScript’s Anti-XSS filter, while processing HTTP requests, does recognizes and properly handle both these encoding styles, and many more. Any web security filter should be able to do it, because web applications usually consume data that has been automatically decoded by their runtime environment.

But Classic ASP adds a perverse twist to its parameter decoding routines. The Request() API apparently assumes that developers and/or browsers and/or users are too stupid to handle non-ASCII Unicode characters (e.g. greek alphabet letters) by themselves, thus it tries to protect them from such execrable things by automatically translating any non-ASCII character into the ASCII counterpart which resembles it the most; when no suitable replacement can be picked, with either “?” or “�” (arbitrarily, it seems). So “%u1F59%u03C0%u03B1%u03C4%u03AF%u03B1″, rather than “Ὑπατία”, becomes a quite ugly “?pat?a”. As you can see, while the replacement choice is mainly homoglyphic (α→a, τ→t), it may also follow homophonic criteria (π→p).

To figure out the whole range of Unicode-ASCII transliterations performed by ASP, I needed to write an ad hoc program mixing VBScript and JavaScript, and I also used it to automatically generate the ASPIdiocy.js mappings file that can be found in recent NoScript packages.

A short essay here, to give you just a taste of this madness:

(0x100) ~= A(0x41)
ā(0x101) ~= a(0x61)
Ă(0x102) ~= A(0x41)
ă(0x103) ~= a(0x61)
Ą(0x104) ~= A(0x41)
ą(0x105) ~= a(0x61)
Ć(0x106) ~= C(0x43)
ć(0x107) ~= c(0x63)
Ĉ(0x108) ~= C(0x43)
ĉ(0x109) ~= c(0x63)
Ċ(0x10a) ~= C(0x43)
ċ(0x10b) ~= c(0x63)
Č(0x10c) ~= C(0x43)
č(0x10d) ~= c(0x63)
Ď(0x10e) ~= D(0x44)
ď(0x10f) ~= d(0x64)
Đ(0x110) ~= �(0xfffd)
đ(0x111) ~= d(0x64)
Ē(0x112) ~= E(0x45)
ē(0x113) ~= e(0x65)
Ĕ(0x114) ~= E(0x45)
ĕ(0x115) ~= e(0x65)
Ė(0x116) ~= E(0x45)
ė(0x117) ~= e(0x65)
Ę(0x118) ~= E(0x45)
ę(0x119) ~= e(0x65)
Ě(0x11a) ~= E(0x45)
ě(0x11b) ~= e(0x65)
Ĝ(0x11c) ~= G(0x47)
ĝ(0x11d) ~= g(0x67)
Ğ(0x11e) ~= G(0x47)
ğ(0x11f) ~= g(0x67)
Ġ(0x120) ~= G(0x47)
ġ(0x121) ~= g(0x67)
Ģ(0x122) ~= G(0x47)
ģ(0x123) ~= g(0x67)
Ĥ(0x124) ~= H(0x48)
ĥ(0x125) ~= h(0x68)
Ħ(0x126) ~= H(0x48)
ħ(0x127) ~= h(0x68)
Ĩ(0x128) ~= I(0x49)
ĩ(0x129) ~= i(0x69)
Ī(0x12a) ~= I(0x49)
ī(0x12b) ~= i(0x69)
Ĭ(0x12c) ~= I(0x49)
ĭ(0x12d) ~= i(0x69)
Į(0x12e) ~= I(0x49)
į(0x12f) ~= i(0x69)
İ(0x130) ~= I(0x49)
ı(0x131) ~= i(0x69)
Ĵ(0x134) ~= J(0x4a)
ĵ(0x135) ~= j(0x6a)
Ķ(0x136) ~= K(0x4b)
ķ(0x137) ~= k(0x6b)
ĸ(0x138) ~= ?(0x3f)
Ĺ(0x139) ~= L(0x4c)
ĺ(0x13a) ~= l(0x6c)
Ļ(0x13b) ~= L(0x4c)
ļ(0x13c) ~= l(0x6c)
Ľ(0x13d) ~= L(0x4c)
ľ(0x13e) ~= l(0x6c)
Ł(0x141) ~= L(0x4c)
ł(0x142) ~= l(0x6c)
Ń(0x143) ~= N(0x4e)
ń(0x144) ~= n(0x6e)
Ņ(0x145) ~= N(0x4e)
ņ(0x146) ~= n(0x6e)
Ň(0x147) ~= N(0x4e)
ň(0x148) ~= n(0x6e)
Ō(0x14c) ~= O(0x4f)
ō(0x14d) ~= o(0x6f)
Ŏ(0x14e) ~= O(0x4f)
ŏ(0x14f) ~= o(0x6f)
Ő(0x150) ~= O(0x4f)
ő(0x151) ~= o(0x6f)
Ŕ(0x154) ~= R(0x52)
ŕ(0x155) ~= r(0x72)
Ŗ(0x156) ~= R(0x52)
ŗ(0x157) ~= r(0x72)
Ř(0x158) ~= R(0x52)
ř(0x159) ~= r(0x72)
Ś(0x15a) ~= S(0x53)
ś(0x15b) ~= s(0x73)
Ŝ(0x15c) ~= S(0x53)
ŝ(0x15d) ~= s(0x73)
Ş(0x15e) ~= S(0x53)
ş(0x15f) ~= s(0x73)
Ţ(0x162) ~= T(0x54)
ţ(0x163) ~= t(0x74)
Ť(0x164) ~= T(0x54)
ť(0x165) ~= t(0x74)
Ŧ(0x166) ~= T(0x54)
ŧ(0x167) ~= t(0x74)
Ũ(0x168) ~= U(0x55)
ũ(0x169) ~= u(0x75)
Ū(0x16a) ~= U(0x55)
ū(0x16b) ~= u(0x75)
Ŭ(0x16c) ~= U(0x55)
ŭ(0x16d) ~= u(0x75)
Ů(0x16e) ~= U(0x55)
ů(0x16f) ~= u(0x75)
Ű(0x170) ~= U(0x55)
ű(0x171) ~= u(0x75)
Ų(0x172) ~= U(0x55)
ų(0x173) ~= u(0x75)
Ŵ(0x174) ~= W(0x57)
ŵ(0x175) ~= w(0x77)
Ŷ(0x176) ~= Y(0x59)
ŷ(0x177) ~= y(0x79)
Ÿ(0x178) ~= �(0xfffd)
Ź(0x179) ~= Z(0x5a)
ź(0x17a) ~= z(0x7a)
Ż(0x17b) ~= Z(0x5a)
ż(0x17c) ~= z(0x7a)
〈(0x2329) ~= <(0x3c)
〈(0x3008) ~= <(0x3c)
<(0xff1c) ~= <(0x3c)
ʹ(0x2b9) ~= '(0x27)
ʼ(0x2bc) ~= '(0x27)
ˈ(0x2c8) ~= '(0x27)
′(0x2032) ~= '(0x27)
'(0xff07) ~= '(0x27)

As you can see in the end, I could list 3 different homoglyphs for < (less than, ASCII 0×27) and 5 for ' (apostrophe, ASCII 0×3c). Anybody with a bit of familiarity with XSS or SQL injection has already guessed where I’m going…

Classic ASP translates the query string parameter value %u3008scr%u0131pt%u3009%u212fval(%uFF07al%u212Frt(%22XSS%22)%u02C8)%u2329/scr%u0131pt%u232A to

<script>eval('alert("XSS")')</script>

which, if echoed back, is executed as a JavaScript block by web browsers.

Any “sane” web server runtime (either a recent IIS with ASP.NET or Apache with PHP/Python/Ruby, or a Java Servlet Container, or you pick yours) either leaves the %u… stuff alone (because this escaping style is deprecated), or translates the whole into

〈scrıpt〉ℯval('alℯrt(”XSS”)ˈ)〈/scrıpt〉

which obviously has no other meaning than “funny text”, to any decent web browser.

This undocumented (AFAIK) Classic ASP “feature” (which was sooo good and smart that Microsoft itself dropped it in ASP.NET) can severely screw up with any anti-XSS filter. It does with Google Chrome’s, it does not with Microsoft IE8’s (unsurprisingly, since the original mess came from Redmond), it does not anymore with NoScript’s, since version 2.0.2rc2.

Of course, it may also be used to bypass Web Application Firewalls (WAFs), which, ironically enough, are often deployed to “virtually patch” XSS and SQL injection bugs in hardly maintainable applications, just like the ones developed with Classic ASP: this blog had been just created when it witnessed a tragicomic case involving the United Nations.

So, how many WAFs out there can actually resist when HomoXSSuality calls?

Senior NoScript community contributor Grumpy Old Lady finally sent me a link to these notes, taken live at BlackHat USA during Graig Heffner’s “How to Hack Millions of Routers” talk, and to the tool he released, allowing to remotely control the many models of routers found vulnerable to a specific kind of DNS Rebinding attack.

Since I couldn’t attend the L.A. conference, I’ve been anxiously in search of something like that to confirm al_9x’s speculative forecast, i.e. that the exploited vulnerability was about routers exposing their administrative interface to the LAN on their WAN IP (even if remote administration is explicitly disabled), and now I’m delighted to find he was entirely correct!

Of course I must be happy, because I don’t need to rush out another ABE feature like the WAN IP protection which I baked inside NoScript 2.0 last week, and because my own home router had been vulnerable as well :)

Some clarifications are still needed, though.

Among the mitigations reportedly enumerated by Heffner (even if he had previously claimed that NoScript couldn’t help), there’s

Use NoScript (disable javascript?) Maybe not practical to most users

Now, it is true that Heffner’s attack fails if the attacker’s domain, bound on the fly to user’s WAN IP, is not allowed to run JavaScript (very likely, when you use NoScript). This means that most users of older NoScript versions (1.10 and below) were already protected against Heffner’s tool and this kind of “XSS via DNS Rebinding”.

However, like for many other “emerging threats”, NoScript provides a specific protection against this class of vulnerabilities (in this case via its ABE module), completely independent from script blocking: in other words, it just works, no matter if you decide to keep JavaScript, plugins and frames enabled everywhere (”Allow Scripts Globally“). There’no reasonable excuse to renounce this protection, since it does not imply the alleged “non-practicality” of enabling JavaScript selectively.

So, since security experts themselves sometimes seem confused about NoScript’s real “convenience vs security” tradeoffs, taking for granted that all the security it offers depends on and requires script blocking, recapping here a (non exhaustive) list of attacks blocked by NoScript even in “Allow Scripts Globally” mode may be useful:

  1. XSS, thanks to its “Injection Checker”, the first anti-XSS filter ever released in a web browser.
  2. Clickjacking — NoScript’s ClearClick feature is still the only effective protection entirely implemented inside the browser and requiring no server-side cooperation.
  3. CSRF (and especially, by default, cross-zone attacks against intranet resources) via the ABE module.
  4. MITM, courtesy of HSTS and other HTTPS-enhancing features

These are just some of the many additional protections provided by NoScript which do not depend on scripting being disabled. So next time you hear people saying “yes, browsing with NoScript is safer but having to pick trusted sites to run JavaScript is a pain“, point them to these good reasons for running NoScript, even if they give up the extra security provided by plain old script blocking.

Bad Behavior has blocked 35775 access attempts in the last 7 days.