Repository: mesos
Updated Branches:
  refs/heads/master fd362da76 -> 2c282f197


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/2c282f19
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2c282f19
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2c282f19

Branch: refs/heads/master
Commit: 2c282f19755ea7518caf6f43e729524b1c6bdb23
Parents: fd362da
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:28:42 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/2c282f19/3rdparty/libprocess/src/jwt.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/jwt.cpp b/3rdparty/libprocess/src/jwt.cpp
index 4477ddd..f2e4a7d 100644
--- a/3rdparty/libprocess/src/jwt.cpp
+++ b/3rdparty/libprocess/src/jwt.cpp
@@ -159,6 +159,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 {
 
 
@@ -250,9 +268,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