Mercurial > p > roundup > code
comparison roundup/cgi/client.py @ 5624:b3618882f906
issue2551023: Fix CSRF headers for use with wsgi and cgi. The
env variable array used - separators rather than _. Compare:
HTTP_X-REQUESTED-WITH to HTTP_X_REQUESTED_WITH. The last is
correct. Also fix roundup-server to produce the latter form. (Patch
by Cédric Krier)
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Wed, 27 Feb 2019 21:47:39 -0500 |
| parents | 14e176b5cd90 |
| children | ba67e397f063 |
comparison
equal
deleted
inserted
replaced
| 5623:1c4adab65faf | 5624:b3618882f906 |
|---|---|
| 1072 header_pass = 0 # count of passing header checks | 1072 header_pass = 0 # count of passing header checks |
| 1073 | 1073 |
| 1074 # If required headers are missing, raise an error | 1074 # If required headers are missing, raise an error |
| 1075 for header in header_names: | 1075 for header in header_names: |
| 1076 if (config["WEB_CSRF_ENFORCE_HEADER_%s"%header] == 'required' | 1076 if (config["WEB_CSRF_ENFORCE_HEADER_%s"%header] == 'required' |
| 1077 and "HTTP_%s"%header not in self.env): | 1077 and "HTTP_%s" % header.replace('-', '_') not in self.env): |
| 1078 logger.error(self._("csrf header %s required but missing for user%s."), header, current_user) | 1078 logger.error(self._("csrf header %s required but missing for user%s."), header, current_user) |
| 1079 raise Unauthorised(self._("Missing header: %s")%header) | 1079 raise Unauthorised(self._("Missing header: %s")%header) |
| 1080 | 1080 |
| 1081 # self.base always matches: ^https?://hostname | 1081 # self.base always matches: ^https?://hostname |
| 1082 enforce=config['WEB_CSRF_ENFORCE_HEADER_REFERER'] | 1082 enforce=config['WEB_CSRF_ENFORCE_HEADER_REFERER'] |
| 1108 logger.warning(self._("csrf Origin header check failed for user%s. Value=%s"), current_user, origin) | 1108 logger.warning(self._("csrf Origin header check failed for user%s. Value=%s"), current_user, origin) |
| 1109 else: | 1109 else: |
| 1110 header_pass += 1 | 1110 header_pass += 1 |
| 1111 | 1111 |
| 1112 enforce=config['WEB_CSRF_ENFORCE_HEADER_X-FORWARDED-HOST'] | 1112 enforce=config['WEB_CSRF_ENFORCE_HEADER_X-FORWARDED-HOST'] |
| 1113 if 'HTTP_X-FORWARDED-HOST' in self.env: | 1113 if 'HTTP_X_FORWARDED_HOST' in self.env: |
| 1114 if enforce != "no": | 1114 if enforce != "no": |
| 1115 host = self.env['HTTP_X-FORWARDED-HOST'] | 1115 host = self.env['HTTP_X_FORWARDED_HOST'] |
| 1116 foundat = self.base.find('://' + host + '/') | 1116 foundat = self.base.find('://' + host + '/') |
| 1117 # 4 means self.base has http:/ prefix, 5 means https:/ prefix | 1117 # 4 means self.base has http:/ prefix, 5 means https:/ prefix |
| 1118 if foundat not in [4, 5]: | 1118 if foundat not in [4, 5]: |
| 1119 if enforce in ('required', 'yes'): | 1119 if enforce in ('required', 'yes'): |
| 1120 logger.error(self._("csrf X-FORWARDED-HOST header check failed for user%s. Value=%s"), current_user, host) | 1120 logger.error(self._("csrf X-FORWARDED-HOST header check failed for user%s. Value=%s"), current_user, host) |
| 1157 # header for xmlrpc calls only. | 1157 # header for xmlrpc calls only. |
| 1158 # E.G. X-Requested-With: XMLHttpRequest | 1158 # E.G. X-Requested-With: XMLHttpRequest |
| 1159 # Note we do not use CSRF nonces for xmlrpc requests. | 1159 # Note we do not use CSRF nonces for xmlrpc requests. |
| 1160 # | 1160 # |
| 1161 # see: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Protecting_REST_Services:_Use_of_Custom_Request_Headers | 1161 # see: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Protecting_REST_Services:_Use_of_Custom_Request_Headers |
| 1162 if 'HTTP_X-REQUESTED-WITH' not in self.env: | 1162 if 'HTTP_X_REQUESTED_WITH' not in self.env: |
| 1163 logger.error(self._("csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s."), current_user) | 1163 logger.error(self._("csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s."), current_user) |
| 1164 raise UsageError(self._("Required Header Missing")) | 1164 raise UsageError(self._("Required Header Missing")) |
| 1165 | 1165 |
| 1166 # Expire old csrf tokens now so we don't use them. These will | 1166 # Expire old csrf tokens now so we don't use them. These will |
| 1167 # be committed after the otks.destroy below. Note that the | 1167 # be committed after the otks.destroy below. Note that the |
