One Line of Code That Compromises Your Server
martinfowler.com
martinfowler.com
There are some use cases this does not cover, such as authentication across multiple systems, where one or more may not have access to the authentication source, but even in that case it'd be preferable to have a separate, internal, private microservice that exchanges tokens for session information.
None of this will stop an attacker that has network access, but that's not what the article is considering, and if somebody is inside your network you might have bigger problems than session hijacking.
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.
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.
This trait constantly appears in threads about JWT. But then how do you handle token invalidation?
I wonder how big IT companies (Google, Microsoft, Amazon) are really doing it...
Google uses interesting approach to handling service accounts: JWT is used as user credential once to get the access token (session credentials) that is reused between requests.
https://developers.google.com/identity/protocols/OAuth2Servi...
If you have any other tip/recommendation I'd be really thankful.
BTW, doesn't SSL/TLS mitigate this a lot? Like, if the user is using SSL then only with physical access to a decrypted device would an attacker be able to impersonate the user, limiting greatly the possible attacks. And if someone has access to your decrypted device then you have bigger problems. Though devs who don't change 'super secret' are probably probably less likely to set up https...
Edit: I almost didn't include the BTW comment because I agree that it is an important part of security, so I didn't want to make it sound less severe, but I am curious about attack possibilities with https enabled.
[2] https://github.com/franciscop/server/blob/master/src/config/...
[3] https://github.com/franciscop/server/issues/3
[4] https://github.com/franciscop/server/blob/master/src/config/...
@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 need to think on the user impersonation a bit.
Of course then it depends on the developer, so statistically speaking there will be a % who do what you suggested and making it secure from the library/framework side would help some users, so I'm all in for it.
What a splendid example of an aptronym! [0]
I'm also found of Rick Wagoner, former CEO of GM, and I often daydream of US Senator Sheldon Whitehouse becoming President.
The cookie data should be signed with the web server's private key.
https://github.com/rack/rack/blob/master/lib/rack/session/co...
https://rdist.root.org/2009/05/28/timing-attack-in-google-ke...
Of course folks are much more likely to misuse their cookie secret than purposefully break a library function. That said you can look at the history of most projects that use HMAC to authenticate data and they did it wrong.
(e.g. https://github.com/rack/rack/commit/0cd7e9aa397f8ebb3b8481d6...)
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.rm -rf /*
brb off to search github for SECRET_KEY =
Only if you generate the key up front and use the same value everywhere.
If you just call os.urandom in your app, then the cost is every restart (and every separate server instance) invalidates the cookies.
Probably not what you want.
What's the recommended minimum number of bytes for an HMAC secret when using SHA1? SHA256?
I'll think about ways to make it more clear! Thanks
The app generator could generate a .gitignore including another dotfile with the secret in it. Or print a message on how important it is to configure the secret properly.
My point was that a framework should not generate a working value that is insecure. And if generating no value and have the app not start without additional configuration is the best way, this should be the way to go.