Hacker News new | ask | show | jobs
by sarciszewski 4042 days ago
Node.js example:

    return new Buffer(sig).toString('base64') == signature;
PHP example:

    return hash_hmac("sha512", $string_to_verify, $shared_secret) == $signature;
Yeah, like fdomig said: timing attacks. The Python example included a mitigation. PHP includes hash_equals() and a constant time comparison in Javascript isn't difficult to write.

Possibly also, the Ruby example:

    return OpenSSL::HMAC.digest('sha512', shared_secret, string_to_verify) == signature
(I don't write Ruby so I don't know if this is overloadable somewhere.)
4 comments

> (I don't write Ruby so I don't know if this is overloadable somewhere.)

Ruby allows overriding the == operator[1], but OpenSSL::HMAC.digest returns an instance of String[2], rather than returning a special subclass of string or some other kind of special HMAC-representing class overloading ==.

[1] http://docs.ruby-lang.org/en/2.2.0/syntax/methods_rdoc.html#...

[2] http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL...

To be pedantic, in Ruby, the fact that an object is of class String is not sufficient evidence that a method has not been overloaded (they can be overloaded via the objects eigenclass), though you're probably right.
Even if it did (and it doesn't, I checked), you're probably still better off doing it explicitly since it's easier to audit, less likely to differ across implementations, and less error prone (e.g. swap the order of the comparison and you're back to plain old String#==).
Yes, that Ruby version is also insecure.
Okay, so only the Python version was acceptable. :(

(And maybe Golang?)

The Golang example looks fine but I didn't read it carefully and do not vouch for it.
> The Python example included a mitigation.

Unnecessarily so too, Python provides hmac.compare_digests since Python 3.3 and it was backported to Python 2.7.7, which was released almost a year ago.

For Ruby you should be using ActiveSupport::SecurityUtils.secure_compare or similar.

In theory openssl could return a String-like object with an overridden ==, but it doesn't.