Repository: mesos
Updated Branches:
  refs/heads/1.4.x 509443ecc -> f6b2a0433


Added constant time comparison of JWT signatures.

A vulnerability in our JWT implementation allows an unauthenticated
remote attacker to execute to execute timing attacks [1].

This patch removes the vulnerability by adding a constant time
comparison of hashes, where the whole message is visited during
the comparison instead of returning at the first failure.

[1] https://codahale.com/a-lesson-in-timing-attacks/

Review: https://reviews.apache.org/r/67357


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f6b2a043
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f6b2a043
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f6b2a043

Branch: refs/heads/1.4.x
Commit: f6b2a0433b1030c3f6bd55b674e4e36a7882ea4b
Parents: 509443e
Author: Alexander Rojas <alexan...@mesosphere.io>
Authored: Tue May 29 16:07:51 2018 +0200
Committer: Alexander Rojas <alexan...@mesosphere.io>
Committed: Wed Jun 6 16:35:12 2018 +0200

----------------------------------------------------------------------
 3rdparty/libprocess/src/jwt.cpp | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/f6b2a043/3rdparty/libprocess/src/jwt.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/jwt.cpp b/3rdparty/libprocess/src/jwt.cpp
index 921031e..6fd2a09 100644
--- a/3rdparty/libprocess/src/jwt.cpp
+++ b/3rdparty/libprocess/src/jwt.cpp
@@ -154,6 +154,24 @@ Try<JSON::Object> parse_payload(const string& component)
   return payload;
 }
 
+
+// Implements equality between strings which run in constant time by either
+// comparing the sizes, and thus ignoring their content, or checking the whole
+// content of them, thus avoiding timing attacks when comparing hashes.
+bool constantTimeEquals(const string& left, const string& right)
+{
+  if (left.size() != right.size()) {
+    return false;
+  }
+
+  unsigned valid = 0;
+  for (size_t i = 0; i < left.size(); ++i) {
+    valid |= left[i] ^ right[i];
+  }
+
+  return valid == 0;
+}
+
 } // namespace {
 
 
@@ -245,9 +263,7 @@ Try<JWT, JWTError> JWT::parse(const string& token, const 
string& secret)
         JWTError::Type::UNKNOWN);
   }
 
-  const bool valid = hmac.get() == signature.get();
-
-  if (!valid) {
+  if (!constantTimeEquals(hmac.get(), signature.get())) {
     return JWTError(
         "Token signature does not match",
         JWTError::Type::INVALID_TOKEN);

Reply via email to