|
31 | 31 | from ipaddress import ip_address, ip_network
|
32 | 32 | from flask import Flask, request, abort
|
33 | 33 |
|
| 34 | +# Python prior to 2.7.7 does not have hmac.compare_digest |
| 35 | +if hexversion >= 0x020707F0: |
| 36 | + def constant_time_compare(val1, val2): |
| 37 | + return hmac.compare_digest(val1, val2) |
| 38 | +else: |
| 39 | + def constant_time_compare(val1, val2): |
| 40 | + if len(val1) != len(val2): |
| 41 | + return False |
| 42 | + result = 0 |
| 43 | + for x, y in zip(val1, val2): |
| 44 | + result |= ord(x) ^ ord(y) |
| 45 | + return result == 0 |
34 | 46 |
|
35 | 47 | application = Flask(__name__)
|
36 | 48 |
|
@@ -84,16 +96,8 @@ def index():
|
84 | 96 | # HMAC requires the key to be bytes, but data is string
|
85 | 97 | mac = hmac.new(str(secret), msg=request.data, digestmod='sha1')
|
86 | 98 |
|
87 |
| - # Python prior to 2.7.7 does not have hmac.compare_digest |
88 |
| - if hexversion >= 0x020707F0: |
89 |
| - if not hmac.compare_digest(str(mac.hexdigest()), str(signature)): |
90 |
| - abort(403) |
91 |
| - else: |
92 |
| - # What compare_digest provides is protection against timing |
93 |
| - # attacks; we can live without this protection for a web-based |
94 |
| - # application |
95 |
| - if not str(mac.hexdigest()) == str(signature): |
96 |
| - abort(403) |
| 99 | + if not constant_time_compare(str(mac.hexdigest()), str(signature)): |
| 100 | + abort(403) |
97 | 101 |
|
98 | 102 | # Implement ping
|
99 | 103 | event = request.headers.get('X-GitHub-Event', 'ping')
|
|
0 commit comments