Blob Blame History Raw
commit 78e2b7cc0897de3eb2a8cdc0f5efe49a34402f9d
Author: Andy Lutomirski <luto@amacapital.net>
Date:   Mon Aug 11 17:50:56 2014 -0700

    webconfig: Use a constant-time token comparison
    
    This prevents a linear-time attack to recover the auth token.

diff --git a/share/tools/web_config/webconfig.py b/share/tools/web_config/webconfig.py
index 2a103eb..452f771 100755
--- a/share/tools/web_config/webconfig.py
+++ b/share/tools/web_config/webconfig.py
@@ -471,6 +471,14 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
                 # Ignore unreadable files, etc
                 pass
         return result
+
+    def secure_startswith(self, haystack, needle):
+        if len(haystack) < len(needle):
+            return False
+        bits = 0
+        for x,y in zip(haystack, needle):
+            bits |= ord(x) ^ ord(y)
+        return bits == 0
         
     def font_size_for_ansi_prompt(self, prompt_demo_ansi):
         width = ansi_prompt_line_width(prompt_demo_ansi)
@@ -489,7 +497,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
         p = self.path
 
         authpath = '/' + authkey
-        if p.startswith(authpath):
+        if self.secure_startswith(p, authpath):
             p = p[len(authpath):]
         else:
             return self.send_error(403)
@@ -528,7 +536,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
         p = self.path
 
         authpath = '/' + authkey
-        if p.startswith(authpath):
+        if self.secure_startswith(p, authpath):
             p = p[len(authpath):]
         else:
             return self.send_error(403)