diff --git a/aspen/http/baseheaders.py b/aspen/http/baseheaders.py index 29d3e6b..9793d87 100644 --- a/aspen/http/baseheaders.py +++ b/aspen/http/baseheaders.py @@ -9,11 +9,22 @@ from aspen.backcompat import CookieError, SimpleCookie - from aspen.http.mapping import CaseInsensitiveMapping from aspen.utils import typecheck +def _check_for_CRLF(value): + """CRLF injection allows an attacker to insert arbitrary headers. + + http://www.acunetix.com/websitesecurity/crlf-injection/ + https://github.com/gratipay/security-qf35us/issues/1 + + """ + if b'\r' in value or b'\n' in value: + from aspen.exceptions import CRLFInjection + raise CRLFInjection() + + class BaseHeaders(CaseInsensitiveMapping): """Represent the headers in an HTTP Request or Response message. http://stackoverflow.com/questions/5423223/how-to-send-non-english-unicode-string-using-http-header @@ -54,16 +65,13 @@ def genheaders(): def __setitem__(self, name, value): - """Extend to protect against CRLF injection: - - http://www.acunetix.com/websitesecurity/crlf-injection/ - - """ - if b'\n' in value: - from aspen.exceptions import CRLFInjection - raise CRLFInjection() + _check_for_CRLF(value) super(BaseHeaders, self).__setitem__(name, value) + def add(self, name, value): + _check_for_CRLF(value) + super(BaseHeaders, self).add(name, value) + def raw(self): """Return the headers as a string, formatted for an HTTP message.