Length-extension attacks are still a thing

23 points by fanf


olliej

[edit: sigh, Oliver uses wall of text. is it super effective? who knows!]

This article is actually quite a bit better than most articles like this which essentially focus on "don't roll your own crypto", as it not only discusses how BunnyCDN got it wrong, but actually includes information about how this should have been done, and then how BunnyCDN was able to mitigate the problem given their existing ABI requirements, and why that mitigation works.

In general I don't like "don't roll your own crypto" articles because they are not at all like this one.

There are a bunch of problems with the general "don't roll your own crypto" refrain, but most of them boil down to it being ineffective and unhelpful statement and leads to many different problems. The first is a developer misunderstanding: in general it seems like developers - at least those inexperienced with the joy of writing anything crypto adjacent - interpret "don't roll your own crypto" as "don't implement the primitives yourself". The problem however is that "don't roll your own crypto" includes the cryptographic construction that makes use of those primitives, similarly DRYOC comes across as being specifically about encryption, rather than the entirely family of operations including hashing, authentication, etc[1]. This leads to the next problem: the vast majority of cryptographic libraries provide only the primitive operations (hash, encrypt/decrypt), leaving developers to decide how to combine or use them, without it being reasonable to assume that they have the requisite understanding of the threat models involved[2].

Over the last few years (decade now?) there have been a number of libraries produced that provide moderately simple APIs that provide just the functions that developers actually need: create a safely and correctly authenticatable signature for unencrypted data, and encrypt data in a way that is not attackable, but most DRYOC articles aren't interested in really communicating anything but the errors that were made, and why those errors were bad. Some may mention "use a library to do this correctly for you", but don't given any pointers, or even what "this" actually is, so developers don't know what they should be looking for.

These problems keep happening for a few reasons: education about cryptography still focuses just on the primitives, and not the risks or considerations necessary when using those primitives. Articles about cryptographic failures have a tendency to focus on flaws in the primitives (e.g. articles talk about timing attacks in various primitives, and how you should only use the implementations from good libraries - reinforcing "roll your own crypto" meaning just the primitives). Many cryptographic libraries consider themselves to be backend libraries to be used by higher level wrappers, but general developers have no real way to know that - it's just a library that says it implements encryption or what have you.

In the world of these libraries we run into the crypto community throwing many different oddly named primitives for each given purpose (hashing being particularly guilty of this), and a non-expert has no real way to know which option is best - this is often then combined with libraries that require the developer to make a choice that they lack the ability to make[3], rather than having the simplest interface just make a robust and generally safe selection, even if it may have specific weaknesses in some cases.

The last problemI'm going to complain about today is simply "don't roll your own crypto". It gets repeated endlessly, and it comes across as (depending on who is saying it) elitist, or insulting (e.g random commenter saying "don't roll your own crypto" comes across as "you idiot"). The statement on its own is often followed up with a discussion of what someone did wrong, and why it was wrong. But seldom provide an actually useful and helpful "there are many subtleties in cryptography, so it's not difficult even for experts to make mistakes. In this case you should have done X instead, but a much safer choice is not to use the primitives yourself, but instead use libraries/tools like X,Y,x that have been examined thoroughly and are designed such that they provide the most secure implementations of the functionality you need".

This article was a welcome exception to the normal DRYOC themes, and I appreciate the author's writing it.

[1] Coupled with the widespread use of "here is a hash of this file so you know it is correct", the mental model is that hashing is not subject to the same degree of subtle errors as encryption/decryption.

[2] This is not an attack on the developers - everyone has different expertise, and unless you are routinely dealing with cryptography there is no reason that you should have to learn everything there is to know. There's another issue I've encountered: because RSA is "based on exponentiation" developers keep using it because they "understand it" while ECC is more complicated, and complicated == bad. This is mercifully less present nowadays, but the problem with the idea, is that they don't actually know how RSA works, they don't have familiarity with CRT, they don't understand how or why it works, but because they understand the core primitive it feels like they understand it.

[3] And simply searching the internet doesn't help, because all of the options will have pages saying why X is the best and the rest are bad, and again developers have no way to know which is actually safe, or reasonable for their use. I recall having to encrypt things many many years ago and every program basically listing all of the current options (Blowfish, Twofish, DES, 3DES, AES, ...).