Mercurial > p > roundup > code
diff roundup/configuration.py @ 5201:a9ace22e0a2f
issue 2550690 - Adding anti-csrf measures to roundup following
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
and
https://seclab.stanford.edu/websec/csrf/csrf.pdf
Basically implement Synchronizer (CSRF) Tokens per form on a page.
Single use (destroyed once used). Random input data for the token
includes:
system random implementation in python using /dev/urandom
(fallback to random based on timestamp as the seed. Not
as good, but should be ok for the short lifetime of the
token??)
the id (in cpython it's the memory address) of the object
requesting a token. In theory this depends on memory layout, the
history of the process (how many previous objects have been
allocated from the heap etc.) I claim without any proof that for
long running processes this is another source of randomness. For
short running processes with little activity it could be guessed.
last the floating point time.time() value is added. This may
only have 1 second resolution so may be guessable.
Hopefully for a short lived (2 week by default) token this is
sufficient. Also in the current implementation the user is notified when
validation fails and is told why. This allows the roundup admin to find
the log entry (at error level) and try to resolve the issue. In the
future user notification may change but for now this is probably best.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sat, 18 Mar 2017 16:59:01 -0400 |
| parents | 7aebd892b600 |
| children | d4cc71beb102 |
line wrap: on
line diff
--- a/roundup/configuration.py Sat Mar 18 15:12:39 2017 -0400 +++ b/roundup/configuration.py Sat Mar 18 16:59:01 2017 -0400 @@ -293,6 +293,19 @@ else: raise OptionValueError(self, value, self.class_description) +class CsrfSettingOption(Option): + + """How should a csrf measure be enforced: required, yes, logfailure, no""" + + class_description = "Allowed values: required, yes, logfailure, no" + + def str2value(self, value): + _val = value.lower() + if _val in ("required", "yes", "logfailure", "no"): + return _val + else: + raise OptionValueError(self, value, self.class_description) + class EmailBodyOption(Option): """When to replace message body or strip quoting: always, never or for new items only""" @@ -633,6 +646,98 @@ "variables supplied by your web server (in that order).\n" "Set this option to 'no' if you do not wish to use HTTP Basic\n" "Authentication in your web interface."), + (CsrfSettingOption, 'csrf_enforce_token', "yes", + """How do we deal with @csrf fields in posted forms. +Set this to 'required' to block the post and notify + the user if the field is missing or invalid. +Set this to 'yes' to block the post and notify the user + if the token is invalid, but accept the form if + the field is missing +Set this to 'logfailure' to log a notice to the roundup + log if the field is invalid or missing, but accept + the post. +Set this to 'no' to ignore the field and accept the post. + """), + (IntegerNumberOption, 'csrf_token_lifetime', "20160", + """csrf_tokens have a limited lifetime. If they are not +used they are purged from the database after this +number of minutes. Default (20160) is 2 weeks."""), + (CsrfSettingOption, 'csrf_enforce_token', "yes", + """How do we deal with @csrf fields in posted forms. +Set this to 'required' to block the post and notify + the user if the field is missing or invalid. +Set this to 'yes' to block the post and notify the user + if the token is invalid, but accept the form if + the field is missing +Set this to 'logfailure' to log a notice to the roundup + log if the field is invalid or missing, but accept + the post. +Set this to 'no' to ignore the field and accept the post. + """), + (CsrfSettingOption, 'csrf_enforce_header_X-REQUESTED-WITH', "yes", + """This is only used for xmlrpc requests. This test is +done after Origin and Referer headers are checked. It only +verifies that the X-Requested-With header exists. The value +is ignored. +Set this to 'required' to block the post and notify + the user if the header is missing or invalid. +Set this to 'yes' is the same as required. +Set this to 'logfailure' is the same as 'no'. +Set this to 'no' to ignore the header and accept the post."""), + (CsrfSettingOption, 'csrf_enforce_header_referer', "yes", + """Verify that the Referer http header matches the +tracker.web setting in config.ini. +Set this to 'required' to block the post and notify + the user if the header is missing or invalid. +Set this to 'yes' to block the post and notify the user + if the header is invalid, but accept the form if + the field is missing +Set this to 'logfalure' to log a notice to the roundup + log if the header is invalid or missing, but accept + the post. +Set this to 'no' to ignore the header and accept the post."""), + (CsrfSettingOption, 'csrf_enforce_header_origin', "yes", + """Verify that the Origin http header matches the +tracker.web setting in config.ini. +Set this to 'required' to block the post and notify + the user if the header is missing or invalid. +Set this to 'yes' to block the post and notify the user + if the header is invalid, but accept the form if + the field is missing +Set this to 'logfailure' to log a notice to the roundup + log if the header is invalid or missing, but accept + the post. +Set this to 'no' to ignore the header and accept the post."""), + (CsrfSettingOption, 'csrf_enforce_header_x-forwarded-host', "yes", + """Verify that the X-Forwarded-Host http header matches +the host part of the tracker.web setting in config.ini. +Set this to 'required' to block the post and notify + the user if the header is missing or invalid. +Set this to 'yes' to block the post and notify the user + if the header is invalid, but accept the form if + the field is missing +Set this to 'logfailure' to log a notice to the roundup + log if the header is invalid or missing, but accept + the post. +Set this to 'no' to ignore the header and accept the post."""), + (CsrfSettingOption, 'csrf_enforce_header_host', "yes", + """"If there is no X-Forward-Host header, verify that +the Host http header matches the host part of the +tracker.web setting in config.ini. +Set this to 'required' to block the post and notify + the user if the header is missing or invalid. +Set this to 'yes' to block the post and notify the user + if the header is invalid, but accept the form if + the field is missing +Set this to 'logfailure' to log a notice to the roundup + log if the header is invalid or missing, but accept + the post. +Set this to 'no' to ignore the header and accept the post."""), + (IntegerNumberOption, 'csrf_header_min_count', "1", + """Minimum number of header checks that must pass +to accept the request. Set to 0 to accept post +even if no header checks pass. Usually the Host header check +always passes, so setting it less than 1 is not recommended."""), (BooleanOption, 'use_browser_language', "yes", "Whether to use HTTP Accept-Language, if present.\n" "Browsers send a language-region preference list.\n"
