29

I have been reading about cross-subdomain cookie attacks here.

A quick overview of how it works (from Wikipedia):

  1. A web site www.example.com hands out subdomains to untrusted third parties
  2. One such party, Mallory, who now controls evil.example.com, lures Alice to her site
  3. A visit to evil.example.com sets a session cookie with the domain .example.com on Alice's browser
  4. When Alice visits www.example.com, this cookie will be sent with the request, as the specs for cookies states, and Alice will have the session specified by Mallory's cookie.
  5. If Alice now logs on, Mallory can use her account.

We are building a web app where customers will have their own subdomains: subdomain.ourapp.com.

Each customer will be able to upload template files which can contain javascript (for client side interaction).

Since javascript can be used to read/write cookies, how can we prevent the session fixation attack above? Note that we are only storing the session id in the cookie.

Sites like squarespace.com also allows users to inject their own javascript into their on pages on their own subdomain. Since it would be next to impossible to try and filter out javascript statements that set/read cookies in uploaded template files, how can we mitigate this attack vector?

F21
  • 501
  • 1
  • 4
  • 10
  • It's also worth reading about "CNAME cloaking" - https://blog.lukaszolejnik.com/large-scale-analysis-of-dns-based-tracking-evasion-broad-data-leaks-included/ – Tim Abell Apr 11 '21 at 07:15

5 Answers5

11

The specific scenario can be prevented easily: Create a new sessionid on login.

Please note that the issues exists across domains, if the sessionid is an url-parameter.

Generating a new sesionid, however, not be sufficient to prevent other kinds of attack: Once Alice is logged in and visits Mallory's subdomain, will the cookie be transmitted?

It is common practice to use a completely different domain for all trusted activity. For example Google uses google.com for trusted activities and *.googleusercontent.com for untrusted sites.

Hendrik Brummermann
  • 27,118
  • 6
  • 79
  • 121
  • 4
    +1 for _"use a completely different domain for all trusted activity."_ It's the only way, and this problem the question is presenting is just another nail in the coffin of shared-domain hosting IMO. – TildalWave Apr 06 '13 at 17:13
  • 1
    I am currently forcing session ids to be stored in cookies. All session data is stored on the server and we are regenerating the id when the user logs on and logs off. The idea of something like `*.googleusercontent.com` is interesting. But in this case, wouldn't `a.googleusercontent.com` still be able to attack `b.googleusercontent.com`? – F21 Apr 06 '13 at 23:49
  • While this may prevent the attacker from logging in as the victim, it does not prevent the opposite (login CSRF attacks): http://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests – Gili Jun 05 '14 at 19:24
10

The safest answer is to use entirely different domains.

If you use subdomains of the same domain, start by learning about the details of the possible attacks. There's a lot already written about this, on this site. See, e.g.,

If you use subdomains of the same domain, here are some steps you can take to protect yourself: store all state on the server side (do not use cookies to store state on the client; instead, the only cookie you use should be a session ID); create a new session ID on login and logout; make sure the cookie is scoped to the subdomain (e.g., its scope should be foo.ourapp.com, not .ourapp.com); check at the server side to make sure you don't receive multiple cookies with the name; make sure to protect yourself against session fixation; if you use CORS, be very careful with your cross-domain policy to make sure you don't allow cross-subdomain requests.

D.W.
  • 98,420
  • 30
  • 267
  • 572
9

Public Suffix has a list of domains that all vendors (Chrome/Firefox/IE/Safari/Opera) use to avoid this problem of stealing cookies from other subdomains (along side other features). The list is updated daily and is maintained on Github.

I got this information from Heroku's blog.

I have verified that Google's googleusercontent.com domain is included in the list along with herokuapp.com , herokussl.com domains.

Sairam
  • 693
  • 1
  • 9
  • 15
  • 2
    Amazing project, I hope my private dynamic DNS will be accepted. It's quite sad that there's no standard for cookie permissions on the web server level (e.g. https://domain.tld could answer a cookie request, similar to CORS, to determine if the origin is allowed). – Florian Wendelborn Oct 02 '16 at 11:38
  • ouch. i just wasted literally *hours* trying to figure out why i couldn't set a cookie on one of my dyndns sites in the parent domain so i could access it from another (complex multi-homed solution which *requires* this), and now i find out that the browser is *deliberately* blocking me as a security measure due to some public black-hole list??? – Michael Jul 22 '18 at 07:45
  • @Dodekeract What do you mean by "my private dynamic DNS will be accepted", is there some place you can submit your sub-domains to bypass this block? – Michael Jul 22 '18 at 07:49
  • @michael I’m not talking about any particular subdomain. I’m operating a small dynamic DNS provider. – Florian Wendelborn Jul 23 '18 at 10:53
0

I managed to solve this issue by storing exact subdomain in Session data on Server. And sending exact subdomain in cookie domain setting.

If user visit dom1.website.com first time I will store it in Session, and check in all future request that it match else reset session on server.

So if user using managed to trick browser and managed to send same cookie for dom2.website.com code will check the domain name value stored in Session will not match the domain it submitted against. so it will reset session on server.

Only side effect is that session on dom1.website.com will be cleared as well.

Faraz
  • 101
  • 2
0

I just had an idea. We can borrow an idea from the Encrypted Token Pattern: encrypt the cookie value!

If the cookie is only accessed by the server, you can use cheap symmetric encryption. Otherwise, use the more expensive public-key encryption.

This will allow you to detect when malicious subdomains delete your cookie and/or detect their attempts to write fake cookies.

Gili
  • 2,149
  • 3
  • 23
  • 41
  • 1
    This wouldn't really help if we store only the session id in the cookie and store session data on the server. – F21 Jun 10 '14 at 23:11
  • 1
    @F21: You're right. You can play all kind of tricks (such as binding each session ID to an IP address) but ultimately http://security.stackexchange.com/a/33854/5002 is a safer solution. That being said, it is still vulnerable to login CSRF attacks. – Gili Jun 11 '14 at 20:02