Thursday, February 7, 2013

Rethinking Cookies: originOnly

Hacker news, reddit
TL;DR this post is full pain, theory and utopia. Don't mind to read if you don't care about better designed web.


What are Cookies now? This is a custom set of data, sent with every request from Client to Server in HTTP headers, mostly used for authentication purposes. Client-side(javascript) can set cookies, but this is a rare use case. Usually cookies are set on server-side, and it contains a special string to determine who is user: signed session, session_id, whatever.

All client side vulnerabilites in web security are because of cookies.

I repeat:

Cookies. They made web broken.

Problem 0 [solved, unrelated]: tampering. 

You can sign cookie with session_secret or store only random string associated with session to prevent tampering.

Problem 1 [solved]: XSS(Cross Site Scripting) 

It can steal cookies because Javascript has access to cookies. This is why we invented 'httpOnly' flag. This flag disallows reading httpOnly cookie from javascript. There is also similar "secure" flag to transfer cookies only via secure connection(MITM)
We invented httpOnly to make critical auth information inaccessible from client side and XSS. We were too stupid to make everything httpOnly by default and only few, really needed on client side httpAccessible or something.

Problem 2 [worked around] Clickjacking, framing.

Framed website received your cookies. There is nothing bad in framing any website without sending auth cookies.

We invented X-Frame-Options to deny "showing" of actually *received* private information. Cool, huh? Response with message: "don't read it if you're wrong person". And, look at some PoC.
Bonus question: Why ClearClick(checks visibility of frame on click) technology is not built-in? It is so easy, isn't it.. But Google has AdSense. AdSense is multibillion business and they have powerful tools to detect clickjacking - people, bots, data mining. Other companies( newbies in web advertising) are easily clickjackable. It's called competitive advantage

Problem 3 [worked around]: CSRF 

My old articles: CSRF Is Vulnerability in All Browsers and CSRF in 15 Popular Websites
What is CSRF, in a nutshell? Is this just a request from domain1 to domain2? No, if you want such request you can use curl, so core 'benefit' of CSRF is usage of User's cookies for domain2.
This is how cookies work from its creation: you set them once and they are sent automatically, from all hosts/origins and for all kinds of requests(<script>, <img>, <iframe>).

Requests are always sent with your cookies. The very core, key problem.

We invented CSRF Token to make sure that Cookie was sent from proper origin intentionally, not from unknown malicious website. This is just so damn stupid: token to protect another, automatically-sent token.

Auth cookie is "key", CSRF token is "another key", proof that "key" was used intentionally. U MAD

Problem 4: [not solved]: Advanced CSRF

Remember JSON leakings? Discovered 4-5 years ago, it was on Hacker News again yesterday. 
It all happened because information was actually received by malicious website. All it needs is a trick to extract it. Previously people could reload Array constructor. Who knows what's next? Stealing plain text tokens through ECMAScript Proxy object(analog of method_missing)? Through styleSheet definitions? Through <audio>/<video> stream or canvas? about:blank referrer? Yet another flash vuln?

Jesus, I'm tired of this.

Maybe we are doing it all wrong..?
It's never too late to make something right.
Don't use my Cookies until I decide to use it myself.

originOnly flag

with such flag the Cookie will be sent only when request's origin is equal this cookie's domain. If it was set on site.com than it's sent only if element(<img>, <form>, <script>, style, <iframe> etc) or XHR was executed on this domain. Or if user navigated to this website(opened in a new tab or clicked link somewhere else)

Why I wrote this?
I want web to be ideal. I want web to be like Mona Lisa: perfect or close to it (in terms of architecture)

Yes, this post is utopic, I just want more people to think about the problem, not about yet another workaround.
"It will break "like" buttons and sometimes useful cross POST whatever..."
If you don't need this flag - don't set it. Just let other 99% of websites to be safe-by-default, not waiting for yet another 0day "trick".

Would love to discuss it with web security minded people! Please, write your thoughts!

14 comments:

  1. I think this is a lovely idea which is why we've been working on it at mozilla for some time now. See https://bugzilla.mozilla.org/show_bug.cgi?id=795346

    ReplyDelete
    Replies
    1. yes, looks great, is there any progress with chrome and other html5 guys? sameDomain, it could be a standard

      Delete
  2. just looked at your profile.. SameDomain - Preventing CSRF with a cookie attribute (formerly OriginOnly) it was called originOnly too? LOL, it feels like i stole the idea

    ReplyDelete
    Replies
    1. This is more common than you'd think. I remember feeling angry with another researcher years back for "stealing" another idea once until I found out other people had published independently too!

      Delete
  3. this doesn't stop same origin CSRF

    ReplyDelete
    Replies
    1. CSRF works because cookies get sent. no cookies - no session and no malicious impact

      Delete
    2. Strictly speaking, if it's same origin it can't be CSRF (just RF)... but yeah, that's a known limitation.

      Delete
    3. if you actually meant same-origin-csrf known as XSS - there is no cure for it. And never will be. CSP maybe..

      Delete
  4. A lot of sites let users post links/images, and a lot of CSRF can be performed with GET requests.

    ReplyDelete
    Replies
    1. 1. yes, e.g. facebook. they do it via iframe. this is not csrf
      2. no, in godo website GET = read only

      Delete
  5. Great article and a valid point. But why not just have this behavior as default (don't send cookie cross-domain) and have a wildcard policy for domains added like path ?

    Like so:
    Set-Cookie: HITHERE=secret; path=/; domain=*.mysite.com; secure; HttpOnly

    ReplyDelete
    Replies
    1. this is a breaking change, browsers are not gonna do so

      Delete
    2. Sure, but so is an originOnly flag. All I meant was that if a change like this would happen, might as well make it customizable and the people wanting this behavior (like buttons etc) has nothing to complain about.

      Delete
    3. originOnly would not break BC. You'd have to explicitly specify it just like HttpOnly; existing websites would not need to change anything to keep working just like they do today.

      Delete