diff --git a/swift/common/swob.py b/swift/common/swob.py index 26e0bf9..69f4f2f 100644 --- a/swift/common/swob.py +++ b/swift/common/swob.py @@ -1215,7 +1215,7 @@ class Response(object): realm = 'unknown' except (AttributeError, ValueError): realm = 'unknown' - return 'Swift realm="%s"' % realm + return 'Swift realm="%s"' % urllib2.quote(realm) @property def is_success(self): diff --git a/test/unit/common/test_swob.py b/test/unit/common/test_swob.py index b3a0a93..5ced5b6 100644 --- a/test/unit/common/test_swob.py +++ b/test/unit/common/test_swob.py @@ -601,6 +601,28 @@ class TestRequest(unittest.TestCase): self.assertEquals('Me realm="whatever"', resp.headers['Www-Authenticate']) + def test_401_www_authenticate_is_quoted(self): + + def test_app(environ, start_response): + start_response('401 Unauthorized', []) + return ['hi'] + + hacker = 'account-name\n\nfoo
' # url injection test + quoted_hacker = quote(hacker) + req = swift.common.swob.Request.blank('/v1/' + hacker) + resp = req.get_response(test_app) + self.assertEquals(resp.status_int, 401) + self.assert_('Www-Authenticate' in resp.headers) + self.assertEquals('Swift realm="%s"' % quoted_hacker, + resp.headers['Www-Authenticate']) + + req = swift.common.swob.Request.blank('/v1/' + quoted_hacker) + resp = req.get_response(test_app) + self.assertEquals(resp.status_int, 401) + self.assert_('Www-Authenticate' in resp.headers) + self.assertEquals('Swift realm="%s"' % quoted_hacker, + resp.headers['Www-Authenticate']) + def test_not_401(self): # Other status codes should not have WWW-Authenticate in response