I use Oracle Cloud for my personal projects because of their generous free tier[1] which includes 4x Ampere A1 cores, 24 GB of RAM, and 10 TB of outbound data transfer per month.
I was ready to jump ship if they changed the terms, but I was not expecting a security incident.
I just wanted to say that we've adopted many of your projects at $DAYJOB, and it has been one of the best technical decisions we've made. So far I've used the Go crypto package, age, and more recently xwing. It all works flawlessly, and at every turn we have happy surprises (smooth cross-compilation, the Age plugin framework, typage, fast xwing revisions, your blog posts).
Sending emails at specific user times, billing (be careful with this one!), scheduling events in the future, reporting it to other users (Microsoft Teams' "it's 20:39 in this user's Timezone").
> So they’ve arranged to make things like runways, to put fires along the sides of the runways, to make a wooden hut for a man to sit in, with two wooden pieces on his head like headphones and bars of bamboo sticking out like antennas—he’s the controller—and they wait for the airplanes to land.
(note no mention of fake airplanes)
And here are historical instances from the actual article:
> They hacked airstrips in the rain forest, but no planes came.
...
> They created mock radio antennas of bamboo and rope to receive news of the millennium.
...
> The leader remains in communication with John Frum through a tall pole said to be a radio mast, and an unseen radio. (The "radio" consisted of an old woman with electrical wire wrapper around her waist, who would speak gibberish in a trance.)
That looks to me like cargo cult in the pop culture sense.
At some point the fake airplane illustrations were inaccurately tacked on, but if anything they give the cults too much credit because they depict high-quality replicas.
You can shift characters between adjacent fields without changing the hash. Maybe you cannot compromise the system directly, but you could poison the cache with a broken image, or induce a downgrade.
Not quite. HMAC helps to prevent length extensions attacks (if the underlying hash was vulnerable in the first place), and the secret prevents attackers from predicting the hash value (like OP did).
But HMAC doesn't help against ambiguously encoded inputs:
hmac(key, 'aa'+'bb') == hmac(key, 'aab'+'b')
You want a way to unambiguously join the values. Common solutions are:
- prepending the length of each field (in a fixed number of bytes);
- encoding the input as JSON or other structured format;
- padding fields to fixed lengths;
- hashing fields individually, then hashing their concatenation;
> When I saw this, I wondered why it has several inner hashes instead of using the raw string.
The inner hash constrains the alphabet on that portion of the input to the outer hash, thus easily letting you use a separator like "," or "|" without having to deal with the alphabet of the inner input, since it gets run through a hash. That is, for a very simplistic use case of two inputs a & b:
sha256(','.join(
[sha256(a), sha256(b)]
))
If one is familiar with a git tree or commit object, this shouldn't be unfamiliar.
Now … whether that's why there was an inner hash at that point in TFA's code is another question, but I don't think one should dismiss inner hashes altogether.
I could see an attack vector here based on file/directory names or the full path. Different inputs could lead to the same order of enumerated checksums.
I'm not dismissing them, inner hashes returning a hexadecimal string fulfills the "the separator should not be able to show up in the inputs" constraint.
Thanks—that makes sense. I was struggling to come up with an example that would fail but I was just unconsciously assuming the separator wasn’t showing up naturally in the individual parts instead of explicitly considering that as a prerequisite.
What do you mean by "incremental hashing"? Note that the Init-Update-Finalize API provided by many cryptography libraries doesn't protect against this - calling Update multiple times is equivalent to hashing a concatenated string.
That page includes an example that shows PHP's incremental hashing is what you describe as "dysfunctional". It hashes "The quick brown fox jumped over the lazy dog." in 1 part, and in 2 parts, and shows that the resulting hashes are equal.
For anyone curious PHP ultimately uses this definition in their introduction portion of the hash extension:
> This extension provides functions that can be used for direct or incremental processing of arbitrary length messages using a variety of hashing algorithms, including the generation of HMAC values and key derivations including HKDF and PBKDF2.
I've worked with many cryptography libraries and have never seen an Init-Update-Finalize API that works the way you think it does. It does not protect against canonicalization attacks unless you're using something like TupleHash.
If the core API is just functions, how do stateful applications handle connections to this persistent storage? Can you still have a connection pool, or does every request pay the extra latency to start a new connection and re-authenticate?
i think they do now but originally one of the reasons people use mysql with languages that are connection per request was that mysql connections were very cheap.
And why pgbouncer used to be considered an essential part of a Postgres web-app-backend deployment — if your business layer didn’t pool and reuse connections, then having an external shim component that pools and reuses connections would solve a lot of the impedance mismatch.
I'm not sure. I was confused for years thinking that "big-endian" meant "the big number is at the end". It was only after reading Gulliver's Travels that it clicked.
I'm all for silly names, but I think this one went a little too much into obscure references and metaphors.
reply