Showing posts with label firefox. Show all posts
Showing posts with label firefox. Show all posts

Tuesday, March 19, 2019

[🌐💧💥] HTTP Cache Cross-Site Leaks

In this blog post I want to talk about a cool type of attacks (XSLeaks) that are cooler than what most developers and security researchers might realize.

Almost 10 years ago, Chris Evans described an attack against Yahoo! Mail in which a malicious website could search the email inbox of a visitor to his website, and know if the search had returned results or not. This essentially could have allowed him to search the emails of the user word for word, and get to know a lot about the emails received by the user, from who, and when.

Chris did that by simply checking how long the server would take to respond to a search query (done through the victim's browser so it includes cookies), and it concluded that if it took longer to return, it must have been because the search query had results, and if it returned faster, it probably had no results.

the server has at least a 40ms difference in minimum latency between a query for a word not in the index, and a query for a word in the index
The attack was cool, but since it was based on network timing, it was a bit hard to pull off. Six years later, Nethanel Gelernter and Amir Herzberg went a bit deeper into this attack and named it XSSearch (and used statistics to make it more reliable). In the years that followed, the attacks steadily improved, going beyond timing, to browser "misfeatures" and bugs that made the attacks a lot more stable up to near-perfection. In other words, detecting if a search query has results or not is now almost trivial to accomplish through a variety of tricks.

Today I want to bring attention to one of the tricks, a very reliable mechanism to query the HTTP Cache in all browsers (with caveats). As far as I know, previous attacks in this area relied on timing (cached resources load faster than non-cached resources), and were mostly used for figuring out the victim's browser historygeographic location or fingerprinting.

However, while those attacks were interesting, an interesting variation is:
  1. Delete the cache for a specific resource (or list of resources).
  2. Force the browser to render a website (navigation, or prerender).
  3. Check if the browser cached the resource deleted at (1).
Note that what this variation gives you, is that it allows you to figure out if a website loads a specific resource (image, script, stylesheet, etc) or not. In other words, you can just ask the browser a question like:
When the user opens this website: https://www.facebook.com/me/friends will the profile picture of Chris Evans be requested? Or, in other words, am I friends with Chris Evans on Facebook?
Fortunately, Facebook seems to sign their URLs, so you probably can't do this attack so simply, but how about this instead?
When the user opens this website: https://www.facebook.com/groups/bugbountygroup/about will this script https://static.xx.fbcdn.net/rsrc.php/v3/yb/r/xxx.js be requested? Or in other words, do I have access to the Facebook bugbounty group?
This other attack would be more interesting, as long as there is a resource that loads if the user has access, but doesn't load if the user doesn't have access, then you can figure out if a user has access to something or not.

Again, fortunately Facebook actually preloads all scripts and images regardless of whether the user has access to private groups or not.

Now, the same technique applies to search results! You can query the browser and ask:
When the user opens this website: https://www.facebook.com/messages/?qa=indonesia will this script be requested? Or in other words, has the user talked about visiting Indonesia?
Again, fortunately Facebook actually doesn't issue search queries on messages and requires the user to "confirm" the search query :-).


As you can see, some websites have deployed protection against Cross-Site Leaks in the past year, some more effective than others, and I think that this is one of those few attacks that only large websites try to protect against, but most of the internet is still vulnerable to.

So, now that I've described the attack, here's how to do it! The summary of the trick is that it allows you to do two things:
  1. Delete the HTTP Cache for a specific resource or URL
  2. Query the HTTP Cache to see if the browser cached it
To delete the HTTP Cache, you just have to either issue a POST request to the resource, or use the fetch API with cache: "reload" in a way that returns an error on the server (eg, by setting an overlong HTTP referrer), which will lead to the browser not caching the response, and invalidating the previous cached response.

Then after you navigate the user to the site you want to query (either through link rel=prerender, or by navigating another window or frame), you check if the resource was cached or not. You can check if the resource was cached or not by doing the same trick with the overlong HTTP referrer, because if the resource was cached, it will load successfully, and if not, it'll fail. You can see an example of this attack here (that terjanq was nice enough to setup :-).

Here's a nicer explanation of the attack (with a happy cloud and everything):

Depending on who you are, you might either be excited about this, depressed, angry, or ambivalent, here are some suggestions on how to deal with this:
  1. If you are a website author, you might want to think about whether you have any of these leaks, and maybe try to protect against them (see defenses below).
  2. If you are a security researcher, you might want to check the websites you use to see if they are vulnerable (check caveats below).
  3. If you are a browser vendor, you might want to consider implementing double keyed cache (see caveats below).
You probably are wondering what are these caveats that I've been talking about, so here we go:
  • The attack is "complicated" for Safari users, the reason is because Safari has this thing called "Verified Partitioned Cache", which is a technique for preventing user tracking, but that also accidentally helps with this. The way it works is by keying the cache entries to their origin and to the site that loaded the resource. The attack is still possible (because the caching behavior is based on heuristics), but the details of this are probably worth a different blog post.
  • Chrome will hopefully not be vulnerable anymore - the reason is because Chrome is experimenting with "Split Disk Cache", which is somewhat different from Safari's, but has the side-effect of protecting against this attack. Note that this feature is currently behind a flag in Chrome (--enable-features=SplitCacheByTopFrameOrigin), so test it out and send feedback to Chrome =).
  • Firefox users are vulnerable, but they have a preference they can enable to get similar behavior - this is called "First Party Isolation", and is available as an add-on and as a pref (privacy.firstparty.isolate=true). It takes a similar approach to the one implemented in Chrome a few steps further, and splits not only cache but several other things (such as permissions!), so test it out too, and send feedback to Firefox.
And if you are a web developer and are thinking about ways to defend against this, well, I have good news and bad news:
  • You can just disable HTTP cache. This has some bandwidth and performance consequences, though, so maybe don't do that.
  • You can add CSRF tokens to everything. This breaks all bookmarks that your users might have set, so maybe don't do that.
  • You can use SameSite=strict cookies to authenticate users. This is actually quite surprisingly very well supported across browsers, and doesn't break bookmarks. Note, however, that there are some known bypasses (eg, if the site has some types of open redirects, as well as browser implementation bugs).
  • You can use COOP to slow down attackers (so every attack requires a click). Note however that it is only implemented in Firefox, and even in Firefox is behind a pref (browser.tabs.remote.useCrossOriginOpenerPolicy), so test it out and send feedback to Firefox =).
  • You can do all the crazy things that Facebook apparently tries to do to protect against this! Or take a look at this page with some more ideas.
🌐💧💥

I want to end this blog post by saying that HTTP cache is not the only leak there is, there are a ton more! So protecting against Cache is not enough, you can also detect the length of the page, the JS execution cycles, the content-type, the number of TCP sockets, and many more. if you are a security researcher, please contribute! The XSLeaks wiki is a joint effort among several security researchers (terjanq, lbherrera_, ronmasas, _tsuro, arthursaftnes, kkotowicz, and me) trying to explore the limits of cross-site leaks, and hopefully by working together we can come up with better attacks :-). Contact me on twitter if you want to contribute (DMs are open).

Thanks for reading!

Wednesday, January 25, 2017

Fighting XSS with 🛡 Isolated Scripts

TL;DR: Here's a proposal for a new way to fight Cross-Site Scripting vulnerabilities called Isolated Scripts. You have an open-source prototype to play with the idea. Please let me know what you think!

Summary

In the aftermath of all the Christmas' CSP bypasses, a discussion came up with @mikewest and @fgrx on the merits of using the Isolated Worlds concept (explained below) as a security mitigation to fight XSS. It seemed like an interesting problem, so I spent some time looking into it.

The design described below would allow you (a web developer) to defend some of your endpoints against XSS with just two simple steps:
  1. Set a new cookie flag (isolatedScript=true).
  2. Set a single HTTP header (Isolated-Script: true).
And that's it. With those two things you could defend your applications against XSS. It is similar to Suborigins but Isolated Scripts defends against XSS even within the same page!

And that's not it, another advantage is that it also mitigates third-party JavaScript code (such as Ads, Analytics, etcetera). Neat, isn't it?

Design

The design of Isolated Scripts consists of three components that work together to deliver the Isolated Scripts proposal.
  1. Isolated Worlds
  2. Isolated Cookies
  3. Secret HTML
I describe each one of them below and then show you the demo.

🌍 Isolated Worlds


Isolated Worlds is a concept most prominently used today in Chrome Extensions user scripts, and Greasemonkey scripts in Firefox - essentially, they allow JavaScript code to get a "view" over the document's DOM but in an isolated JavaScript runtime. Let me explain:

Let's say that there is a website with the following code:


The Isolated World will have access to document.getElementById("text") but it will not have access to window.variable. That is, the only thing that both scripts share is an independent view of the HTML's DOM. This isolation is very important, because user scripts have elevated privileges, for example, they can trigger XMLHttpRequests requests to any website and read their responses.

If it wasn't for the Isolated World, then the page could do something like this to execute code in the user script, and attack the user:
document.getElementById = function() {
    arguments.callee.caller.constructor("attack()")();
};
In this way, the Isolated World allows us to defend our privileged execution context from the hostile user execution context. Now, the question is: Can we use the same design to protect trusted scripts from Cross-Site Scripting vulnerabilities?

That is, instead of focusing on preventing script execution as a mitigation (which we've found out to be somewhat error prone), why don't we instead focus on differentiating trusted scripts from untrusted scripts?

The idea of having privileged and unprivileged scripts running in the same DOM is not new, in fact, there are a few implementations out there (such as Mario Heiderich's Iceshield, and Antoine Delignat-Lavaud Defensive JS), but their implementation required rewriting code to overcome the hostile attacker. In Isolated Worlds, normal JavaScript code just works.

So, that is the idea behind Isolated Scripts - provide a mechanism for a web author to mark a specific script as trusted, which the browser will then run in an Isolated World.
An easy way to implement this in a demo is by actually reusing the Isolated Worlds implementation in Chrome Extensions, and simply install a user script for every script with the right response header.

🍪 Isolated Cookies


Now that we have a script running in a trusted execution context, we need a way for the web server to identify requests coming from it. This is needed because the server might only want to expose some sensitive data to Isolated Scripts.

The easiest way to do so would be simply by adding a new HTTP request header similar to the Origin header (we could use Isolated-Script: foo.js for example). Another alternative is to create a new type of cookie that is only sent when the request comes from a Isolated Script. This alternative is superior to the HTTP header for two reasons:
  1. It is backwards compatible, browsers that don't implement it will just send the cookie as usual.
  2. It can work in conjunction with Same-site cookies (which mitigates CSRF as well).
To clarify, the web server would do this:
Set-Cookie: SID=XXXX; httpOnly; secure; SameSite=Strict; isolatedScript

And the browser will then process the cookie as usual, except that it will only include it in requests if they are made by the Isolated Script. And browsers that don't understand the new flag will always include them.

An easy way to implement this in a demo is to instead of using flags, using a special name in the cookie, and refuse to send the cookie except for cases when the request comes from the isolated script.
One idea that Devdatta proposed was to make use of cookie prefixes, which could also protect the cookies from clobbering attacks.

🙈 Secret HTML


What we have now is a mechanism for a script to have extra privileges, and be protected from hostile scripts by running in an isolated execution context, however, the script will, of course want to display the data to the user, and if the script writes it to the DOM, the malicious script would immediately be able to read it. So, for that, we need a way for the Isolated Script to write HTML that the hostile scripts can't read.

While this primitive might sound new, it actually already exists today! It's already possible for JavaScript code to write HTML that is visible to the user, but unavailable to the DOM. There are at least two ways to do this:
  1. Creating an iframe and then navigating the iframe to a data:text/html URL (it doesn't work in Firefox because they treat data: URLs as same-origin).
  2. Creating an iframe with a sandbox attribute without the allow-same-origin flag (works in Chrome and Firefox).
So, to recap, we can already create HTML nodes that are inaccessible to the parent page. The only issue left is perhaps how to make it easily backwards compatible. So we have two problems left:
  • CSS wouldn't be propagated down to the iframe, but to solve this problem we can propagate the calculated style down to the iframe's body, which will allow us to ensure that the text would look the same as if it was in the parent page (note, however that selectors wouldn't work inside it).
  • Events wouldn't propagate to the parent page, but to solve that problem we could just install a simple script that forwards all events from the iframe up to the parent document.
With this, the behavior would be fairly similar to the secret HTML but without providing a significant information leak on to the hostile script. 
An easy way to implement this in a demo is to create a setter function on innerHTML, and whenever the isolated script tries to set innerHTML we instead create a sandboxed iframe with the content, to which we postMessage the CSS and the HTML and a message channel that can be used to propagate events up the iframe. To avoid confusing other code dependencies, we could create this iframe inside of a closed Shadow DOM.
One potential concern for the design of this feature that Malte brought up was that depending on the implementation this could potentially mess up with developer experience, as some scripts most likely assume that code in the DOM is reachable (eg, via querySelector, getElementsByTagName or otherwise). This is very important, and possibly the most valuable lesson to take - rather than having security folks like me design APIs with weird restrictions, we should also be asking authors what they need to do their work.

Demo

Alright! So now that I explained the concept and how it was implemented in the demo, it's time for you to see it in action.

First of all, to emulate the browser behavior you need to install a chrome extension (don't worry, no scary permissions), and then just go to the "vulnerable website" and try to steal the contents of the XHR response! If you can steal them, you win a special Isolated Scripts 👕 T-Shirt my eternal gratitude 🙏 (and, of course 🎤 fame & glory).

So, let's do it!
  1. Install Chrome Extension
  2. Go to Proof of Concept website
There are XSS everywhere on the page (both DOM and reflected), and I disabled the XSS filter to make your life easier. I would be super interested to learn about different ways to break this!

Note that there are probably implementation bugs that wouldn't be an issue in a real browser implementation, but please let me know about them anyway (either on twitter or on the comments below), as while they don't negate the design, they are nevertheless something we should keep in mind and fix for the purpose of making this as close to reality as possible.

In case you need it, the source code of the extension is here and the changes required to disable CSP and enable Isolated Scripts instead is here.

🔍 Analysis

Now, I'm obviously biased on this, since I already invested some time on this idea, but I think it's at least promising and has some potential. That said, I want to do an analysis on it's value and impact to avoid over-promising. I will use the framework to measure web security mitigations that I described in my previous blog post (but if you haven't read it, don't worry, I explain this below).

Moderation

Moderation stands for: How much are we limiting the impact of the problem?

In this case, the impact is extremely easy to measure (modulo implementation flaws).
Any secret data that is protected with Isolated Cookies is only exposed to Isolated Scripts. And any data touched by Isolated Scripts is hidden from XSS. So, the web author gets to decide the degree of moderation it requires.
One interesting caveat to this that Mario brought up, is that conducting phishing attacks using XSS would still be possible, and is very likely to result in compromise with a tiny bit of social engineering.

Minimization

Minimization stands for: How much are we minimizing the number of problems?

We can also measure this. Most XSS, including content sniffing and plugin-based SOP bypasses (even some types of universal XSS bugs!) can be mitigated with Isolated Scripts, but some types of DOM XSS aren't.
The DOM XSS that are not mitigated by Isolated Scripts, are, for example, Angular Template Injections, and eval()-based XSS - that is because they still inherit the capabilities of the Isolated Script.
I would love to hear of any other types of bugs that wouldn't be mitigated by Isolated Scripts.

Substitution

Substitution stands for: How much are we replacing risks with safer alternatives?

We can also quickly measure how much we are replacing the current risks with Isolated Scripts. In particular, adoption seems very easy although it has some problems:
  1. JavaScript code hosted in CDNs can't run in the Isolated World. This is working as intended, but also might limit the ease of deployment. One easy way to fix this is to use ES6 import statements.
  2. Code that expects to have access to "secret content" (like advertising, for example) won't be able to do so anymore and might fail in unexpected ways (note, however that in a browser implementation it might make sense to actually give access to the secret HTML to the Isolated script, if possible).
I would be super interested to hear any other problems you think developers might find in adoption.

Simplification

Simplification stands for: How much are we removing problems, rather than adding complexity?

Generally, we are adding complexity and removing complexity, and it's somewhat subjective to decide whether they cancel each other out or not.
  • On one hand, we are removing complexity by requiring all interactions with secret data to happen through a single funnel.
  • On the other hand, by adding yet another cookie flag and a new condition for script execution, and a new type of DOM isolation we are making the web platform more difficult to understand.
I honestly think that we are making this a bit more complicated. Not as much as other mitigations, but slightly so. I would be interested to hear any arguments on how "bad" this complexity would be for the web platform.

Conclusion

Thank you so much for reading so far, and I hope you found reading this as interesting as I found writing it.

I think a good next step from here is to hear more feedback on the proposal (from both, authors, browsers and hackers!), and perhaps identify ways we can simplify it further, ways to break it, and ways to make it more developer friendly.

If you have any ideas, please leave comments below or on twitter (or you can also email me).

Until next time 😸

Tuesday, December 27, 2016

How to bypass CSP nonces with DOM XSS 🎅

TL;DR - CSP nonces aren't as effective as they seem to be against DOM XSS. You can bypass them in several ways. We don't know how to fix them. Maybe we shouldn't.

Thank you for visiting. This blog post talks about CSP nonce bypasses. It starts with some context, continues with how to bypass CSP nonces in several situations and concludes with some commentary. As always, this blog post is my personal opinion on the subject, and I would love to hear yours.

My relationship with CSP, "it's complicated"

I used to like Content-Security-Policy. Circa 2009, I used to be really excited about it. My excitement was high enough that I even spent a bunch of time implementing CSP in JavaScript in my ACS project (and to my knowledge this was the first working CSP implementation/prototype). It supported hashes, and whitelists, and I was honestly convinced it was going to be awesome! My abstract started with "How to solve XSS [...]".

But one day one of my friends from elhacker.net (WHK) pointed out that ACS (and CSP by extension) could be trivially circumvented using JSONP. He pointed out that if you whitelist a hostname that contains a JSONP endpoint, you are busted, and indeed there were so many, that I didn't see an easy way to fix this. My heart was broken.💔

Fast-forward to 2015, when Mario Heiderich made a cool XSS challenge called "Sh*t, it's CSP!", where the challenge was to escape an apparently safe CSP with the shortest payload possible. Unsurprisingly, JSONP made an appearance (but also Angular and Flash). Talk about beating a dead horse.

And then finally in 2016 a reasonably popular paper called "CSP Is Dead, Long Live CSP!" came out summarizing the problems highlighted by WHK and Mario after doing an internet-wide survey of CSP deployments, performed by Miki, Lukas, Sebastian and Artur. The conclusion of the paper was that CSP whitelists were completely broken and useless. At least CSP got a funeral , I thought.

However, that was not it. The paper, in return, advocated for the use of CSP nonces instead of whitelists. A bright future for the new way to do CSP!

When CSP nonces were first proposed, my concern with them was that their propagation seemed really difficult. To solve this problem, dominatrixss-csp back in 2012 made it so that all dynamically generated script nodes would work by propagating the script nonces with it's dynamic resource filter. This made nonce propagation really simple. And so, this exact approach was proposed in the paper, and named strict-dynamic, now with user-agent support, rather than a runtime script as dominatrixss-csp was. Great improvement. We got ourselves a native dominatrixss!

This new flavor of CSP, proposed to ignore whitelists completely, and rely solely on nonces. While the deployment of CSP nonces is harder than whitelists (as it requires server-side changes on every single page with the policy), it nevertheless seemed to propose real security benefits, which were clearly lacking on the whitelist-based approach. So yet again, this autumn, I was reasonably optimistic of this new approach. Perhaps there was a way to make most XSS actually *really* unexploitable this time. Maybe CSP wasn't a sham after all!

But this Christmas, as-if it was a piece of coal from Santa, Sebastian Lekies pointed out what in my opinion, seems to be a significant blow to CSP nonces, almost completely making CSP ineffective against many of the XSS vulnerabilities of 2016.

A CSS+CSP+DOM XSS three-way

While CSP nonces indeed seem resilient against 15-years-old XSS vulnerabilities, they don't seem to be so effective against DOM XSS. To explain why, I need to show you how web applications are written now a days, and how that differs from 2002.

Before, most of the application logic lived in the server, but in the past decade it has been moving more and more to the client. Now a days, the most effective way to develop a web application is by writing most of the UI code in HTML+JavaScript. This allows, among other things for making web applications offline-ready, and provides access to an endless supply of powerful web APIs.

And now, newly developed applications still have XSS, the difference is that since a lot of code is written in JavaScript, now they have DOM XSS. And these are precisely the types of bugs that CSP nonces can't consistently defend against (as currently implemented, at least).

Let me give you three examples (non-exhaustive list, of course) of DOM XSS bugs that are common and CSP nonces alone can't defend against:
  1. Persistent DOM XSS when the attacker can force navigation to the vulnerable page, and the payload is not included in the cached response (so need to be fetched).
  2. DOM XSS bugs where pages include third-party HTML code (eg, fetch(location.pathName).then(r=>r.text()).then(t=>body.innerHTML=t);)
  3. DOM XSS bugs where the XSS payload is in the location.hash (eg, https://victim/xss#!foo?payload=).
To explain why, we need to travel back in time to 2008 (woooosh!). Back in 2008, Gareth Heyes, David Lindsay and I made a small presentation in Microsoft Bluehat called CSS - The Sexy Assassin. Among other things, we demonstrated a technique to read HTML attributes purely with CSS3 selectors (which was coincidentally rediscovered by WiSec and presented with kuza55 on their 25c3 talk Attacking Rich Internet Applications a few months later).

The summary of this attack is that it's possible to create a CSS program that exfiltrates the values of HTML attributes character-by-character, simply by generating HTTP requests every time a CSS selector matches, and repeating consecutively. If you haven't seen this working, take a look here. The way it works is very simple, it just creates a CSS attribute selector of the form:

*[attribute^="a"]{background:url("record?match=a")}
*[attribute^="b"]{background:url("record?match=b")}
*[attribute^="c"]{background:url("record?match=c")}
[...]

And then, once we get a match, repeat with:
*[attribute^="aa"]{background:url("record?match=aa")}
*[attribute^="ab"]{background:url("record?match=ab")}
*[attribute^="ac"]{background:url("record?match=ac")}
[...]

Until it exfiltrates the complete attribute.

The attack for script tags is very straightforward. We need to do the exact same attack, with the only caveat of making sure the script tag is set to display: block;.

So, we now can extract a CSP nonce using CSS and the only thing we need to do so is to be able to inject multiple times in the same document. The three examples of DOM XSS I gave you above permit exactly just that. A way to inject an XSS payload multiple times in the same document. The perfect three-way.

Proof of Concept

Alright! Let's do this =)

First of all, persistent DOM XSS. This one is troubling in particular, because if in "the new world", developers are supposed to write UIs in JavaScript, then the dynamic content needs to come from the server asynchronously.

What I mean by that is that if you write your UI code in HTML+JavaScript, then the user data must come from the server. While this design pattern allows you to control the way applications load progressively, it also makes it so that loading the same document twice can return different data each time.

Now, of course, the question is: How do you force the document to load twice!? With HTTP cache, of course! That's exactly what Sebastian showed us this Christmas.

A happy @slekies wishing you happy CSP holidays! Ho! ho! ho! ho!
Sebastian explained how CSP nonces are incompatible with most caching mechanisms, and provided a simple proof of concept to demonstrate it. After some discussion on twitter, the consequences became quite clear. In a cool-scary-awkward-cool way.

Let me show you with an example, let's take the default Guestbook example from the AppEngine getting started guide with a few modifications that add AJAX support, and CSP nonces. The application is simple enough and is vulnerable to an obvious XSS but it is mitigated by CSP nonces, or is it?

The application above has a very simple persistent XSS. Just submit a XSS payload (eg, <H1>XSS</H1>) and you will see what I mean. But although there is an XSS there, you actually can't execute JavaScript because of the CSP nonce.

Now, let's do the attack, to recap, we will:

  1. with CSS attribute reader.
  2. with the CSP nonce.

Stealing the CSP nonce will actually require some server-side code to keep track of the bruteforcing. You can find the code here, and you can run it by clicking the buttons above.

If all worked well, after clicking "Inject the XSS payload", you should have received an alert. Isn't that nice? =). In this case, the cache we are using is the BFCache since it's the most reliable, but you could use traditional HTTP caching as Sebastian did in his PoC.

Other DOM XSS

Persistent DOM XSS isn't the only weakness in CSP nonces. Sebastian demonstrated the same issue with postMessage. Another endpoint that is also problematic is XSS through HTTP "inclusion". This is a fairly common XSS vulnerability that simply consists on fetching some user-supplied URL and echoing it back in innerHTML. This is the equivalent of Remote File Inclusion for JavaScript. The exploit is exactly the same as the others.

Finally, the last PoC of today is one for location.hash, which is also very common. Maybe the reason is because of IE quirks, but many websites have to use the location hash to implement history and navigation in a single-page JavaScript client. It even has a nickname "hashbang". In fact, this is so common that every single website that uses jQuery Mobile has this "feature" enabled by default, whether they like it or not.

Essentially, any website that uses hashbang for internal navigation is as vulnerable to reflected XSS as if CSP nonces weren't there to being with. How crazy is that! Take a look at the PoC here (Chrome Only - Firefox escapes location.hash).

Conclusion

Wow, this was a long blog post.. but at least I hope you found it useful, and hopefully now you will be able to understand a bit better the real effectiveness of CSP, maybe learn a few browser tricks, and hopefully got some ideas for future research.

Is CSP preventing any vulns? Yes, probably! I think all the bugs reported by GOBBLES in 2002 should be preventable with CSP nonces.

Is CSP a panacea? No, definitely not. It's coverage and effectiveness is even more fragile than we (or at least I) originally thought.

Where do we go from here?
  • We could try to lock CSP at runtime, as Devdatta proposed.
  • We could disallow CSS3 attribute selectors to read nonce attributes.
  • We could just give up with CSP. 💩
I don't think we should give up.. but I also can't stop wondering whether all this effort we spend on CSP could be better used elsewhere - specially since this mechanism is so fragile it runs the real risk of creating an illusion of security where it does not exist. And I don-t think I'm alone in this assessment.. I guess time will tell.

Anyway, happy holidays, everyone! and thank you for reading. If you have any feedback, or comments please comment below or on Twitter!

Hasta luego!

Monday, May 25, 2015

[Service Workers] New APIs = New Vulns = Fun++


Just came back from another great HackPra Allstars, this time in the beautiful city of Amsterdam. Mario was kind enough to invite me to ramble about random security stuff I had in mind (and this year it was Service Workers). The presentation went OK and it was super fun to meet up with so many people, and watch all those great presentations.

In any case, I promised to write a blog post to repeat the presentation but in a written form, however I was hoping to watch the video to see what mistakes I might have made and correct them in the blog post, and the video is not online yet. Anyway, so, until then, today this post is about something that wasn't mentioned in the talk.

This is about what type of vulnerabilities applications using Service Workers are likely to create. To start, I just want to say that I totally love Service Workers! It's APIs are easy to use and understand and the debugging tools in Chrome are beautiful and well done (very important since tools such as Burp or TamperChrome wouldn't work as well with offline apps as no requests are actually done.) You can clearly see that a lot of people have thought a lot about this problem, and there is some serious effort around making offline application development possible.

The reason this blog post content wasn't part of the presentation is because I thought it already had too much content, but if you don't know how Service Workers work, you might want to see the first section of the slides (as it's an introduction) or you can read this article or this video.

Anyway, so back to biz.. Given that there aren't many "real" web applications using Service Workers, I'll be using the service-worker samples from the w3c-webmob, but as soon as you start finding real service worker usage take a look and let me know if you find these problems too!

There are two main categories of potential problems I can see:
  1. Response and Caching Issues
  2. Web JavaScript Web Development

Response and Caching Issues

The first "category" or "family" of problems are response and caching issues. These are issues that are present because of the way responses are likely to be handled by applications.

Forever XSS

The first problem, that is probably kind-of bad, is the possibility of making a reflected XSS into a persistent XSS. We've already seen this type of problems based on APIs like localStorage before, but what makes this difference is that the Cache API is actually designed to do exactly that!

When the site is about to request a page from the web, the service worker is consulted first. The service worker at this point can decide to respond with a cache response (it's logic is totally delegated to the Service Worker). One of the main use-cases for service workers is to serve a cached-up copy of the request. This cache is programmatic and totally up-to the application to decide how to handle it.

One coding pattern for Service Workers is to respond with whatever is in the cache, if available or, to make a request if not (and cache the response). In other words, in those cases, no request is ever made to the server if the request matches a cached response. Since this Cache database is accessible to any JS code running in the same origin, an attacker can pollute the Cache with whatever it wants, and let the client serve the malicious XSS for ever!

If you want to try this out, go here:

Then fake an XSS by typing this to the console:
caches.open('prefetch-cache-v1').then(function(cache){cache.put(new Request('index.html', {mode: 'no-cors'}), new Response('\x3cscript>alert(1)\x3c/script>', {headers: {'content-type': 'text/html'}}))})

Now whenever you visit that page you will see an alert instead! You can use Control+Shift+R to undo it, but when you visit the page again, the XSS will come back. It's actually quite difficult to get rid of this XSS. You have to manually delete the cache :(.

This is likely to be an anti-pattern we'll see in new Service-Workers enabled applications often. To prevent this, one of the ideas from Jake Archibald is to simply check the "url" property of the response. If the URL is not the same as the request, then simply not use it, and discard it from the cache. This idea is quite important actually, and I'll explain why below.

When Secure Open Redirects become XSS

A couple years ago in a presentation with thornmaker we explained how open redirects can result in XSS and information leaks, and they were mostly limited to things such as redirecting to insecure protocols (like javascript: or data:). Service Workers, however, and in specific some of the ways that the Cache API is likely to be used, introduce yet another possibility, and one that is quite bad too.

As explained before, the way people seem to be coding over the Cache API is by reading the Request, fetching it, and then caching the Response. This is tricky, because when a service worker renders a response, it renders it from the same origin it was loaded from.

In other words.. let's say you have a website that has an open redirect..
  • https://www.example.com/logout?next=https://www.othersite.com/
And you have a service worker like this one:
  • https://googlechrome.github.io/samples/service-worker/read-through-caching/service-worker.js
What that service worker does, as the previous one, is simply cache all requests that go through by refetching and the service worker will cache the response from evilwebsite.com for the other request!

That means that next time the user goes to:
  • https://www.example.com/logout?next=https://www.evilwebsite.com
The request will be cached and instead of getting a 302 redirect, they will get the contents of evilwebsite.com.

Note that for this to work, evilwebsite.com must include Access-Control-Allow-Origin: * as a response header, as otherwise the request won't be accepted. And you need to make the request be cors enabled (with a cross origin image, or embed request for example).

This means that an open redirect can be converted to a persistent XSS and is another reason why checking the url property of the Response is so important before rendering it (both from Cache and on code like event.respondWith(fetch(event.request))). Because even if you have never had an XSS, you can introduce one by accident. If I had to guess, almost all usages of Service Workers will be vulnerable to one or another variation of these types of attacks if they don't implement the response.url check.

There's a bunch of other interesting things you can do with Service Workers and Requests / Responses, mentioned in the talk and that I'll try to blog about later. For now though, let's change subject.

Web JavaScript Web Development

This will sound weird to some, but the JavaScript APIs in the browser don't actually include any good web APIs for building responses. What this means is that because Service Workers will now be kind-of like Web Servers, but are being put there without having any APIs for secure web development, then it's likely they will introduce a bunch of cool bugs.

JavaScript Web APIs aren't Web Service APIs


For starters, the default concerns are things that affect existing JS-based server applications (like Node.js). Things from RegExp bugs because the JS APIs aren't secure by default to things like the JSON API lack of encoding.

But another more interesting problem is that the lack of templating APIs in Service Workers means people will write code like this which of course means it's gonna be full of XSS. And while you could import a templating library with strict contextual auto-escaping, the lack of a default library means people are just likely to use insecure alternatives or just default to string concatenation (note things like angular and handlebars won't work here, because they work at the DOM level and the Service Workers don't have access to the DOM as they run way before the DOM is created).

It's also worth noting that thanks to the asynchronous nature of Service Workers (event-driven and promise-based) mixed with developers that aren't used to this, is extremely likely to introduce concurrency vulnerabilities in JS if people abuse the global scope, which while isn't the case today, is very likely to be the case soon.

Cross Site Request Forgery


Another concern is that CSRF protection will have to behave differently for Service Workers. In specific, Service Workers will most likely have to depend more on referrer/origin based checks. This isn't bad in and off itself, but mixing this with online web applications will most likely pose a challenge to web applications. Funnily, none of the demos I found online have CSRF protection, which remarks the problem, but also makes it hard for me to give you examples on why it's gonna be hard.

To give a specific example, if a web application is meant to work while offline, how would such application keep track of CSRF tokens? Once the user comes online, it's possible the CSRF tokens won't be valid anymore, and the offline application will have to handle that gracefully. While handling the fallback correctly is possible by simply doing different checks depending on the online state of the application, it's likely more people will get it wrong than right.

Conclusion

I'm really excited to see what type of web applications are developed with Service Workers, and also about what type of vulnerabilities they introduce :). It's too early to know exactly, but some anti-patterns are clearly starting to emerge as a result of the API design, or of the existing mental models on developers' heads.

Another thing I wanted to mention, before closing up is that I'll start experimenting writing some of the defense security tools I mentioned in the talk, if you want to help out as well, please let me know!

Sunday, September 22, 2013

[Matryoshka] - Wrapping Overflow Leak on Frames

(Update Feb 25, 2018: Google Drive deprecated web hosting, so the PoCs below don't currently work. I'll fix them soon, in the meantime you can see the source code here)

I just came back from a very fun trip around Europe. Among other places, I visited Hamburg, to attend HackPra 2013, which was hosted in AppSec Europe. In there I gave the presentation Matryoshka - titled after the famous Russian dolls.

Today I'm blogging about one of the subjects of that presentation, an information leak introduced by a "side channel" present in iframes. I didn't give much detail in the presentation since I was afraid I was gonna run out of time (this was just one part of the presentation). This blogpost is meant to add more detail, as well as give a couple more details I wasn't sure worked at the time of the presentation.

A quick summary of the problem is that, under certain circumstances, it is possible to know when text inside an iframe wraps to the next line. Text wrapping is when a line is longer than the width of the area it can be displayed into, so it needs to wrap to a second line.

Being able to detect text wrapping is an interesting problem, as it allows us to learn some information about the framed website, which might be particularly dangerous under some circumstances.

To show a small example, the following iframe is hosted in a different domain than this blog post:


We are disallowed to know what the contents are because of the Same Origin Policy. It's important to understand this, we can iframe anything, including third party sites to which you are authenticated to. This might include sites that contain secret information, like your email inbox, or your bank statements.

Now, let's see what we can do:

  • We can, change the width and height of this iframe at our will.
  • We can navigate the inner iframes from that page.
  • We can change the style of your scrollbars or detect their presence.
To clarify, changing the width and height of the iframe will allow us to force some content to wrap on to the next line. To exploit this we need to know whether the content wrapped or not.

Navigating Child Iframes

By navigating child iframes, we can change an otherwise innocuous iframe (such as a Facebook like button), to a domain we control. We can do this by design, even on cross-domain iframes, look:




The reason for this is because the window.frames[] property is exposed cross-origin, and it's allowed by the Same Origin Policy to navigate child frames, even those that are cross domain.

The reason this matters, is because once we control a child iframe in our target page, we can know the position of the iframe relative to the browser/screen. This will let us know if the content of the page wrapped, as we'll discuss later on.

Detecting when the text wraps to the next line is the corner stone of this attack.

Detecting Iframe Screen Coordinates

In Trident and Gecko based browsers, it is possible to detect the position of an iframe relative to the screen. This is interesting, as it allows us to know exactly when an iframe moves down because of text wrapping.

We detect this with one of two properties, either window.screenTop for Trident based browsers, or window.mozInnerScreenY for Gecko based browsers (and mouse events in general). These properties are only readable from within the target iframe, but as we explained before, it is perfectly possible to navigate our target site child iframes, and once we do that, we can reduce the width of our iframe until text doesn't fit in the line anymore, and moves the rest of the line to the next line, displacing our iframe.

Please note this proof of concept doesn't work in all browsers (notably, it only works in firefox/ie), so it might not work for you, but feel free to give it a try.

Detecting Scrollbars Presence

This is interesting, in some browsers, it is possible to apply CSS to the scrollbars of the iframe. This is important because this would leak whether the text wrapped contains a background-image, which would be requested when the scrollbar is shown. In some browsers you need to change the backgroundImage after the creation of the iframe for the image to be requested.

Please note this proof of concept doesn't work in all browsers (notably, this only only works webkit-based browsers), so it might not work for you, but feel free to give it a try.



What will happen when you click that button is:
  • The width of the iframe will be slowly reduced pixel by pixel.
  • When the word "dusk" wraps to the next line, it will display the vertical scrollbar.
  • When the vertical scrollbar is shown, the background image will be requested.
  • We detect when such requests happen by checking document.cookie.

Measuring Word Width

So far we found out a way to find when text wraps to the next line, either by detecting the presence of a scrollbar, or navigating a child iframe and detecting it's position relative to the screen monitor.

To measure a specific word width, we will follow the following steps:
  1. Resize the target iframe to:
    • width: 9999999px
    • height: smallest-without-scrollbar;
  2. Slowly reduce the width until the text wraps. (You can reduce in fraction of pixels).
    • If you are detecting a scrollbar, ensure to increase the height to make the scrollbar disappear.
    • If you are detecting text wrapped from a child iframe, detect changes from the new current position.
  3. Repeat
    • Record the exact width at which text wrapping happened.
We will actually learn things in a bit of an odd order. For this particular example, we will get the length of the following:
  • First wrapping:       hello, my name is bond, james bond.
  • Second wrapping:   the secret is on the island!
  • Third wrapping:      bond, james bond.
  • Fourth wrapping:    name is bond,
  • Fifth wrapping:       bond, james
  • Sixth wrapping:      the secret
  • Seventh wrapping:  my name
  • Eighth wrapping:    secret is
  • Ninth wrapping:      name is
  • Tenth wrapping:      is on
The exact fraction of pixel in which the line wraps (which by practice I've seen some times needs to be as accurate as 1E-10 pixels), tells us the length of the line.

By calculating the difference between different lines, we can also get the length of other sequence of words:
  1. hello, my name is
  2. hello, my james bond.
  3. hello, my name is bond.
  4. hello, is bond, james bond.
  5. hello, my bond, james bond.
  6. ...
And we can also get "bond" by subtracting (1) to (3). We can also get "james" by subtracting (3) to the first wrapping, etc..  We might not always get specific word length, and rather groups of two words, but the attack works to both cases.

The question now is.. how hard is it to go from the width of the word (or sequence of words) to the actual contents of them?

Turns out that usually, all letters have a different width, and as long as such width is unique, it's almost trivial to calculate which letters are in each wrapping (although we don't get the order of such letters).

The solution to this problem is the classic knapsack problem which I won't go into details of. While we won't be able to get the order of the letters, we can get which letters to a reasonable degree of accuracy, which should be sufficient to have a very good guess of the value.

It's unclear what's the best solution to this problem. This information leak isn't a vulnerability per-se in browsers, but rather a well known and understood feature. This blog post will hopefully trigger some discussion around this subject and we can come up with solutions.

One challenge is that if we stopped providing mozInnerScreenY / screenTop, then it would be significantly harder to detect and protect against clickjacking. So whichever solution we come up with needs to take that into consideration.

It's also worth mentioning what happens when our iframe is so small that a word doesn't even fit. Well, the answer is that individual characters wrap to the next line, and we can then extract the width of each individual character (rather than each word). This, unfortunately, doesn't work that well in normal websites, as by default they don't break words (unless overridden by CSS's break-word). If we are able to get this, however, it would be possible for us to obtain the order of the characters in each word (and completely read the contents of the iframe without having to guess).

And that was it! This attack allows you to steal contents from websites that don't use X-Frame-Options (or have a fixed CSS width) in all major browsers with browser standard functionality (no vuln up my sleeve!). I felt inclined to use an acronym for this attack (WOLF) since Thai Duong/Juliano Rizzo's attacks (POET, BEAST, CRIME) sound better than "cross-BLAH-jacking", and I like wolves (although, not as much as cats), specially since it kind of feels like insanity wolf to me.

Thursday, October 15, 2009

A couple of unicode issues on PHP and Firefox

Well, here I am developing ACS, finding that this project resembles at some degree the creation of a browser.. but anyway, it's close to a working beta (yay!).

In any case, a couple of bugs came to my attention, some of them are public, some of them are not.

First of all, I want to describe the PHP vulnerability I made public on my presentation with David Lindsay, at Blackhat USA 2009, that apparently only Chris Weber, Giorgio Maone (creator of NoScript), Mario Heiderich (creator of PHP-IDS) and the Acunetix security team have realized the danger of it.

It has been reported, well, more than enough times to the PHP team (I made another attempt today, hoping this will get fixed in some time soon.. if at all). This issue affects all PHP versions Mario Heiderich and me could test, and endangers practically all PHP programs that use the utf8_decode() function for decoding (as recommended by OWASP guidelines).

The disclosure timeline follows:
* Reported by root@80sec.com: May 11 2009
* Discovered by webmaster@lapstore.de: June 19 2009
* Discovered by Giorgio Maone / Eduardo Vela: July 14 2009
* Reported and Fixed on PHPIDS: July 14 2009
* Microsoft notified of a XSS Filter bypass: July 14 2009
* Fixed XSS Filter bypass on NoScript 1.9.6:  July 20 2009
* Vulnerability disclosed on BlackHat USA 2009: July 29 2009
* Added signature to Acunetix WVS: August 14 2009
* Re-reported by sird@rckc.at: September 27 2009
* Vendor claims it was fixed on 5.2.11: September 29 2009
* Re-re-reported by sird@rckc.at after checking 5.2.11: October 16 2009
* Published sirdarckcat.blogspot.com: October 16 2009

You can check the bug here:
http://bugs.php.net/bug.php?id=49687

In reality there are several vulns in just a couple of lines, so I'll describe them here:
1.- Overlong UTF-8:
As REQUIRED by UNICODE 3.1, and noted in the Unicode Technical Report #36, UTF-8 is forbidden to interpretate a character's non-shortest form.
    http://www.unicode.org/reports/tr36/#UTF-8_Exploit

VULN: PHP makes no checks whatsoever on this matter.

Why is this a vulnerability?

A filter (such as addslashes, htmlentities, escapeshellarg, etc.) will NOT be able to detect&escape such byte sequences, and so an application that relies on them for security checks wont be protected at all. Because it allows an attacker to encode "dangerous" chars, such as ', ", <, ;, &, \0 in different ways:

' = %27 = %c0%a7 = %e0%80%a7 = %f0%80%80%a7
" = %22 = %c0%a2 = %e0%80%a2 = %f0%80%80%a2
< = %3c = %c0%bc = %e0%80%bc = %f0%80%80%bc
; = %3b = %c0%bb = %e0%80%bb = %f0%80%80%bb
& = %26 = %c0%a6 = %e0%80%a6 = %f0%80%80%a6
\0= % 00 = %c0%80 = %e0%80%80 = %f0%80%80%80

Use hackvertor to generate them.


Enabling attacks on systems that use addslashes for example (but almost all encoding functions would be vulnerable):

// add slashes!
foreach($_GET as $k=>$v)$_GET[$k]=addslashes("$v");

//  .... some code ...

// $name is encoded in utf8
$name=utf8_decode($_GET['name']);
mysql_query("SELECT * FROM table WHERE name='$name';");

?>


2.- Ill formed sequences:
As REQUIRED by UNICODE 3.0, and noted in the Unicode Technical Report #36, if a leading byte is followed by an invalid successor byte, then it should NOT consume it.
    http://www.unicode.org/reports/tr36/#Ill-Formed_Subsequences

VULN: PHP will consume invalid bytes.

Why is this a vulnerability?

It will allow an attacker to "eat" controll chars. For example:

// htmlentities
foreach($_GET as $k=>$v)$_GET[$k]=htmlentities("$v",ENT_QUOTES);

//  ... some code ...

$name=$_GET['name'];
$url=$_GET['url'];

//  ... some code ...

$profileImage="<img alt=\"Photo of $name\" src=\"http://$url\" />";

// ... some code ...
echo utf8_decode($profileImage);
?>

A request such as:

?name=%90&src=%20onerror=alert(1)%20

Will execute the code "alert(1)" when the page loads.

Note that htmlpurifier does a utf8_decode function call at the end of the decoding, BUT they are safe because of a pre-encoding made by htmlpurifier.. other codes that do the same wont be so lucky.

Bogdan Calin from Acunetix WVS described a couple of other potential attack scenarios:







Where an attacker could fool the filter by doing a request like:
vuln.php?input=%F6%3Cimg+onmouseover=prompt(/xss/)//%F6%3E

And:



Where an attacker could fool the filter by doing a request like:
index.php?username=test%FC%27%27+or+1=1+–+&password=a

3.- Integer overflow:
Unsigned short has a size of 16 bits (2 bytes), that is UNCAPABLE of storing unicode characters of 21 bits, and represented on UTF with 4 bytes (1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx). PHP attempts to sum a 21 bits value to a 16 bits-size variable, and then makes no checks on the value.

The affected code follows:

//  php/ext/xml/xml.c#558
PHPAPI char *xml_utf8_decode(    //  ...
{
    int pos = len;
    char *newbuf = emallo    //  ...
    unsigned short c;          // sizeof(unsigned short)==16 bits
    char (*decoder)(unsig    //  ...
    xml_encoding *enc = x    //  ...
//  ...
//  #580
    c = (unsigned char)(*s);
    if (c >= 0xf0) {         /* four bytes encoded, 21 bits */
        if(pos-4 >= 0) {
            c = ((s[0]&7)<<18) | ((s[1]&63)<<12) | ((s[2]&63)<<6) | (s[3]&63);
        } else {
            c = '?';   
        }
        s += 4;
        pos -= 4;
//  ...

The relevant part of the code is of course, the declaration of c as an unsigned int, the comment specifing that the char is 21 bits, and this:
x= ((s[0]&7)<<18) | ...

s[0]&7<<18 means it will move 3 bits, 18 bits to the right. As we noted before.. c's size is only 16 bits.
(xxxx xxxx & 0000 0111) << 18

Also, this part:
...  ((s[1]&63)<<12) | ...

s[1]&63<<12 means it will move 6 bits, 12 bits to the right. So, 2 bits are going to be lost.
(xxxx xxxx & 0011 1111) << 12

This allows us to make something even more interesting.

Code like this:

%FF%F0%40%FC that is invalid unicode, overlong, and all you want (definatelly NOT valid), will be casted as a "lower than" simbol (<).

http://eaea.sirdarckcat.net/xss.php?unicode&html_xss=%FF%F0%40%FC

This besides the already mentioned problems, and the possibility of bypassing quite a lot of WAFs and Filters.. demonstrate the problem of a bad unicode implementation on PHP.

I hope the PHP development team acknowledges all this issues that have been reported before, and were explained some months ago on Blackhat USA (and the developers were noticed to check the ppt more than once), and now are explained yet another time.

This was fixed on 5.2.11 :) on my birthday!! Sept 17

Anyway.. that's not all, now to finish this post I want to publish a overlong utf-8 exception on Firefox (actually, Mozilla's).

The firefox one


Firefox is supposed to consider the non-shortest form exception (point #1 in the PHP vulnerabilities), and section 3.1 of the Unicode Technical Report #36 but apparently there's a flaw on it. This is specially problematic for the reasons that an overlong unicode sequence not taken into consideration may allow several types of filter bypasses.

Anyway, the severity of this vulnerability is not as high as the PHP ones, but is worth mentioning. The following non-shortest form for the char U+1000:
0xF0 0x81 0x80 0x80

is allowed, as well as the correct shortest form:
0xE1 0x80 0x80

Note that this problem is only present on the 4 bytes representation.

You can track this bug at:
https://bugzilla.mozilla.org/show_bug.cgi?id=522634

Anyway, that's all! Thanks for your time :)

Greetings!!

Tuesday, August 04, 2009

Our Favorite XSS Filters and how to Attack them

So well, Black Hat 2009 and DEFCON 17 are over now, and on Black Hat I presented twice, so I want to
do a quick recap.

If you asisted to them, I would appreciate any feedback, since the blackhat's feedback system about
the passport stuff is like.. not-public, so its completely useless for me.

So, if anyone want's to give feedback, you can use the comments or send me an email at sird@rckc.at

David Lindsay also made a nice write up about the presentation in here:
http://p42.us/?p=42

You can get our slides from here:
http://p42.us/favxss/

I don't know if the CNN and Java.net bugs have been fixed, but they did worked at the stage (we made
a live-demo on how to bypass the IE8 xss filter), and well there's an errata on the NoScript section.

There was a fix I didnt tested regarding the same origin exception, so now instead of using:

http://www.google.com/imgres?imgurl=http://tinyurl.com/ZWZ8Z4&imgrefurl=http://tinyurl.com/ZWZ8Z4

Use:
http://www.google.com/imgres?imgurl=http://pwn&imgrefurl=/search?q=ZWZ8Z4%26btnI=l%23asciifullNameRowId

Since we dont really need TinyURL, it was just an extra, but well, it makes sense for it to get fixed.

And also, the DoS & pwn for NoScript well, apparently because of something related to ABE, now noscript will absolutely kill your browser.  Upgrade to latest NoScript to be protected against the PoC of the presentation.

So, in the talk, david presented about the not-so-filtered html/js tricks we use, the unicode part was a
quick (very quick) recap since Chris Weber was going to have a cool presentation about Unicode the next
day (and it was awesome!!!) but anyway, regarding the unicode section, I made a quick demo on a vuln on
PHP's 4, 5 and 6 utf8_decode function that allows an attacker to do cool filter bypasses.

The PHP-IDS section, I'm not sure if Mario has fixed it, but my bypass was fixed.

Besides that, if you are going to use PHP-IDS, you can be sure that thornmaker and all the slackers crew
is gonna be there to break it and report it waay before a real-life attacker can bypass it, just remember
to keep it updated.

So, the talk was cool, I actually thought I wasn't going to finish on time so I was talking very fast, and
in a matter of fact I actually talked so fast that I actually finished 10 minutes before time.

So well, after that, I spoke with a couple of people about the presentation, and I got quite a lot of biz
cards (I didn't realized untill I got to the hotel and emptied my pockets.. I actually can't rememer to who
all those cards belong to), so if I told you I was going to get back to you later, you should probably send
me an email (sird@rckc.at) since I probably wont recognize your name in your card (my memory sucks!).

So well, the second day I had another talk, that was a solution Im working on, that sort of competes with
Mozilla CSP (could help as a transition to CSP) called ACS -  Active Content Signatures, that will implement
security measures for protecting against XSS on the client-side without the need of an addon on your browser.

I plan to implement some of NoScript features, as well as IE8 XSS Filter, and CSP, so I'll try just to get
the best of the best stuff in there. Inlcuding a JS sandbox that is being made by Gareth Hayes and that sort
of combines the best of Google Caja and Facebook JS sandbox but all in the client side, so you dont need to
do ANYTHING at all in the server :).

The second talk was an epic fail, I lost my document (it was on the Downloads folder, duh!) so there was
like a 5 to 10 minutes gap of me setting up my computer and not-finding the doc..

Thankfully it was a breakout session so it wasn't taped haha, anyway, my audience was small but very
speciallized, the Mozilla security squid and Mozilla securinator were there, as well as david ross, the
author of the super-IE8 XSS filter, a couple of friends and some other people.. The q&a at the end was
very cool :).

I haven't published the details of the .doc of ACS since well, it is still in an early stage but if you
are interested I will send you a draft. I am planing to present it during this month, and I will let you
all guys know in this blog, together with a nice demo.

The HTML Parser of ACS together with the JavaScript sandbox (JSReg) of Gareth can be tried at:
    http://eaea.sirdarckcat.net/testhtml.html

If you can hack it, please do it (and let me now =D). There's a sla.ckers.org thread about it here:
    http://sla.ckers.org/forum/read.php?2,29259

Also, I want to state that I want to do:
    ./pressure.pl -h tra.ckers.org -p /rsnake -p /id

So well, blackhat was a lot of fun, and actually I wasn't planning to stay for defcon, but with a fast
flight change and a lot of luck, I was able to stay more time, and go to defcon.

I want to say that DEFCON is waaaaaaaaaaay too fun, I didn't know it was so cool! BlackHat is like for
CSOs, CTOs, etc.. so vendors were like giving away gifts to everyone so they will buy their stuff, and
well, the talks were more interesting, but anyway, defcon rocks.

The 2wire talk that my friend hakim gave was very cool, we went to war driving in a limousine the night
before, that was fun as hell haha.

It was nice to meet all those slackers in blackhat/defcon, I'm sorry for all those casinos in the strip
that got their wifi-paying system completely bypassed by a very skilled slacker (whose identity prefers to
be kept private), but the hotels include bellagio, mirage, paris, caesars palace, circus circus, riviera
and well probably every hotel in the world that uses COX for providing the service (maybe also Lodgenet).

Ah btw, regarding the last post of Google Analytics, I want to show something I think is very cool. To make
impossible to a user to logout and/or login to any google service (gmail/google reader/google analytics/
adsense/adwords/etc..).

http://google.sirdarckcat.net/?v=https://www.google.com/accounts

If you readed all this post and you are not following me on twitter, then well, there it is!

When your victim gets a "bad request" that means, "you win". Google knows about this since like 4 or 5 months
ago.. and it's still unfixed. If one day you can't access your google account, or can't logout, try deleting
all your cookies.. And either use noscript and mark googleanalitycs.com as untrusted, or point in your hosts
fike googleanalitycs.com to 0.0.0.0 (and if you are a system admin that is not using google analytics you
should probably also do the same, since all websites in the world that use google analytics are vulnerable
to this attack, and you are protecting your user's security AND privacy by doing so..).

Greetz!!

PS. I made this post on notepad so its probably weird on blogspot.