This construct can (crudely) protect against a length extension attack, which in particular affects hashes built using the Merkle-Damgård construction (such as MD5, SHA-1, and the SHA-2 family).
The gist of the attack is that an attacker who knows H(s || m)
and m
for a hash H
, secret s
, and message m
can trivially forge a hash of the form H(s || m || p || a)
where p
is the internal padding used by the hash function and a
is an attacker-controlled string. This may seem difficult to exploit in practice, as p
is typically raw bytes such as \x04\x04\x04\x04
. However, consider a message such as a set of HTTP query parameters: username=x&admin=false
. With this attack, you can forge a "signed" message for username=x&admin=false\x02\x02&admin=true
. Depending on how the parameters are parsed, the URL parser could easily use the latter value of admin
rather than the former.
Hashing the secret at the end of the message is, presumably, an attempt to defend against this type of attack. Since the attacker doesn't know the secret, they can't use a length extension attack since they have no way of forging H(s || m || p || a || s)
without knowing s
.
That said, there are existing cryptographic constructs that are proven secure for use as message authentication codes. In this case, HMAC is probably the cryptographic primitive they want to use, as it has a strong proof of security.
This type of home-grown construct is evidence that the authors of this service are not well-versed in cryptography. If they were, an HMAC would be a natural and obvious choice for such a situation. If they are comfortable publishing these kinds of embarrassing home-grown constructs in their public documentation, I would personally worry about the cryptography they deploy and use internally.