Live data from Hacker News

One Line of Code That Compromises Your Server

martinfowler.com

21–30 of 46 posts

Re: One Line of Code That Compromises Your Server

#21

Earlier quoted context omitted.

@AgentME -- correct @franciscop -- keep an eye out for the rest of the article (it's already written and will be released soon). I go over the impacts of an attacker knowing the secret in much more detail. I also have sections on prevention for both application developers and library/framework authors that I think you'll find interesting!

I'll wait for it, because I don't fully understand @AgentME's comment "to generate cookies that authenticate them as other users". Those auth cookies would have a hashed token per user that must be created and validated in the back-end (besides the encryption). So just storing 'user-ID' should not be enough, you'd have to be able to decrypt a real user's cookie to know this token hash (and for this reason just guessi…

Let's say your Python web application pickles your sessions so you can store more than just JSON serializable fields. Unpickling can result in the execution of arbitrary Python code and the only thing normally protecting you is that you MAC your session with the secret key (which was just cracked...)

I need to think on the user impersonation a bit.

Re: One Line of Code That Compromises Your Server

#22
The cookies spec really should be incorporated into the SSL/TLS layer. Right now it's basically performing two encryption/signing steps immediately after each other, one at the web server, and another for the applications server. This is a pain-in-the-ass for the web server framework and adds several milliseconds of redundant latency.

The cookie data should be signed with the web server's private key.

Re: One Line of Code That Compromises Your Server

#23

Earlier quoted context omitted.

@AgentME -- correct @franciscop -- keep an eye out for the rest of the article (it's already written and will be released soon). I go over the impacts of an attacker knowing the secret in much more detail. I also have sections on prevention for both application developers and library/framework authors that I think you'll find interesting!

I'll wait for it, because I don't fully understand @AgentME's comment "to generate cookies that authenticate them as other users". Those auth cookies would have a hashed token per user that must be created and validated in the back-end (besides the encryption). So just storing 'user-ID' should not be enough, you'd have to be able to decrypt a real user's cookie to know this token hash (and for this reason just guessi…

The cookie that the user gets might be something like userid + ":" + HMAC(server secret, userid). The user who gets that cookie can brute-force HMAC(x, userid) with different values of x until they get a match for the string in their cookie, at which point they know the server secret. Then with the server secret, they can generate a valid cookie for any userid.

Re: One Line of Code That Compromises Your Server

#24

I write most of my web apps using Sinatra (as per the article example), but do it using the Padrino [1] framework. Padrino by default sets the Sinatra session secrets to a long hash, which negates the developer from having to remember to do all this housekeeping later to tighten security on the app. [1] - https://www.padrinorb.com

Padrino sets the session secret to a random value on startup if you don't set it yourself. This means that:

1) you can only run a single instance. Multiple instances will generate different secrets and not accept each others' cookies

2) restarting an instance (for instance doing a deploy) generates a new secret and invalidates all previous cookies

Neither of these are desirable, and to avoid it the docs recommend [1] you set the session secret yourself via:

    set :session_secret, 'super secret'
which gives you the exact problem the blog post is addressing, so it does not seem that Padrino does any better here.

[1] - http://padrinorb.com/guides/controllers/sessions/

Re: One Line of Code That Compromises Your Server

#25
I don't know why anyone would ever do this since there is no cost to SECRET_KEY = os.urandom... or even just hammering on the keyboard. It is not like you are ever going to be challenged for that password? You could even say here is another line of code that will compromise your server:

rm -rf /*

brb off to search github for SECRET_KEY =

Re: One Line of Code That Compromises Your Server

#27

This is why I prefer not to pass session information to the client in the first place. Have the session key be just an opaque, cryptographically random token that is then associated with data on the server (via a keystore of some sort). Then the cookie becomes nothing more than a bearer token. There are some use cases this does not cover, such as authentication across multiple systems, where one or more may not have…

The reason is that, at scale, all the little things matter. Having to query your database for _every_ user request, to convert their session token into the server-side underlying data, gets expensive and slow. And it's a centralizing force in the architecture, requiring your session management database to be accessible by all your user facing servers.

So they store the data with the client, who can pass it back to the server with every request. One less DB query.

There are various rebuttals to that approach, even at scale, etc, etc. I'm certainly not advocating for it. But that's what some big applications landed on. Big apps drive most of the development of free tools, libraries, and frameworks. So it's no surprise that a lot of free tools handle this use case, even by default.

In the majority of cases, the not at scale cases, of course it doesn't make sense. Most all the hot new tools don't make sense. But again, that's just an artifact of software economics. The majority of the money is made by the big apps, so most tools are built for the big apps.

It's just a shame that new developers get caught up in these hip tools and base their understanding of the ecosystem on them.

Re: One Line of Code That Compromises Your Server

#28
post #26

What do people here use to store password for servers ? Plain text configuration files ? I have pwd of DB in config files and found no way to put it elsewhere.

Plain text can work, assuming that it is access controlled in a secure environment. Often times, during the build process, a secure secret management system or process will handle the combining of the code with configuration. For example, your developer (with no secret access) could commit code and Jenkins can fetch the configuration file from a secure and access-controlled service. Then the built code has the secrets and the developer does not. There are a lot of approaches to doing it at scale. See https://gist.github.com/maxvt/bb49a6c7243163b8120625fc8ae3f3... for a good overview.

Re: One Line of Code That Compromises Your Server

#30

This is why I prefer not to pass session information to the client in the first place. Have the session key be just an opaque, cryptographically random token that is then associated with data on the server (via a keystore of some sort). Then the cookie becomes nothing more than a bearer token. There are some use cases this does not cover, such as authentication across multiple systems, where one or more may not have…

The reason is that, at scale, all the little things matter. Having to query your database for _every_ user request, to convert their session token into the server-side underlying data, gets expensive and slow. And it's a centralizing force in the architecture, requiring your session management database to be accessible by all your user facing servers. So they store the data with the client, who can pass it back to th…

Session key verification can be a cross cutting concern that is good enough for scale (API gateway, reverse proxy, cross cutting service). And with a verified session key, each service should be able to optimize for restoring data belonging to that session key.

If the data leaves your server, it is considered potentially malicious and you have to verify and validate everything anyway. Also, with client-side stored data you lose control over the client-server state unless you validate against the server state. But then you lose all the advantages of client-side storage. Crypto cannot mitigate that.

Post reply on HN