Hacker News new | ask | show | jobs
by cstone 6012 days ago
I can tell you're pushing for terseness in the signed text (every character does count), but I'd definitely consider explicitly describing the cryptosystem and version you're using in each cookie.

Also, is there some code elsewhere ensuring that the separator character is always escaped during signing? I don't see anything explicit, but I could definitely be missing something; I haven't messed with Django internals much..

2 comments

This is a pointless feature and Django shouldn't implement it.

If Django-signed messages are being persisted long-term in something other than an HTTP cookie, Django developers are abusing the feature. The sliver of code that's been published is not sufficient to protect long-term persisted data.

If Django-signed messages are simply being used for cookies and token URLs, then it doesn't matter whether they're forward/backward compatible. They have no long-term value. Applications should fail gracefully when unintelligible messages are presented. In 99.999% of proper cases, this simply means bouncing the user back to the login prompt to get a new cookie.

This isn't just pedantry. A fair subset of all cryptosystems have failed in later revisions because of negotiation vulnerabilities. Along with the "automatic key rotation" misfeature, this idea is as likely to burn you as it is to protect you.

You're right that it should just fail gracefully, and that people shouldn't use the data for anything long-lived. I'm not so sure the latter won't happen often enough for compatibility to become an expected feature, though.

What I'm afraid of is the future hypothetical case where the scheme changes in the future and a Django developer decides to add in backward compatibility anyway--by having the verifier check the presented text against both the old scheme and the new one.

If your main point is "don't reinvent the wheel, use an established system," though, I totally agree.

Negotiation in cryptosystems is usually a bad idea. It's a bad idea here. Anything that would make that feature useful would be an abuse or a threat.

One of the worst ideas Simon is getting from Reddit right now is that he needs to make this system more sophisticated. Version the cryptosystem! Use truncated SHA256! Revoke messages on MAC failures! Use random sleeps! Automatically expire keys! Look at this NIST standard I found!

What they need to do is what every other web framework does, because every other framework has been inspected already.

"Applications should fail gracefully when unintelligible messages are presented. In 99.999% of proper cases, this simply means bouncing the user back to the login prompt to get a new cookie."

Consider a load balancing pool where a fraction of the servers accidentally get stuck on the old cryptosuite, or a few get prematurely upgraded to a new cryptosuite. Blindly bouncing to the login prompt a few percent of the time would be painfully difficult to debug.

Idea: the plaintext shall include a version number, and possibly an identifier like an IP address for the server that generated it. If the version number mismatches, log an explanation and the identifier it on the server then bounce to a login prompt.

To expand on the first part: with something up front saying "this key is signed using system FOO", you'll be able to support multiple systems in the future. This means that you'll be able to handle multiple systems (and upgrades) easily.
If the server can handle keys that are signed by either system FOO or system BAR, and the keys themselves don’t provide any clue about how they were signed, the server can just try to verify the signature using FOO and, if that system doesn’t return a “signature valid” response, fall back to BAR.

Obviously if you’re permitting ten different signature-verification algorithms then this technique starts putting a significant load on the server, but if your protocol allows for ten different signature-verification algorithms, then you have bigger problems, right?