Merge "Validate L7Rule value and cookie name" into stable/ussuri

This commit is contained in:
Zuul 2022-06-29 19:18:17 +00:00 committed by Gerrit Code Review
commit e1aac84389
5 changed files with 63 additions and 9 deletions

View File

@ -69,8 +69,11 @@ class L7RulePOST(BaseL7Type):
compare_type = wtypes.wsattr(
wtypes.Enum(str, *constants.SUPPORTED_L7RULE_COMPARE_TYPES),
mandatory=True)
key = wtypes.wsattr(wtypes.StringType(max_length=255))
value = wtypes.wsattr(wtypes.StringType(max_length=255), mandatory=True)
key = wtypes.wsattr(wtypes.StringType(max_length=255,
pattern=r'^[^\r\n]*$'))
value = wtypes.wsattr(wtypes.StringType(max_length=255,
pattern=r'^[^\r\n]*$'),
mandatory=True)
invert = wtypes.wsattr(bool, default=False)
admin_state_up = wtypes.wsattr(bool, default=True)
# TODO(johnsom) Remove after deprecation (R series)
@ -90,8 +93,10 @@ class L7RulePUT(BaseL7Type):
compare_type = wtypes.wsattr(
wtypes.Enum(str,
*constants.SUPPORTED_L7RULE_COMPARE_TYPES))
key = wtypes.wsattr(wtypes.StringType(max_length=255))
value = wtypes.wsattr(wtypes.StringType(max_length=255))
key = wtypes.wsattr(wtypes.StringType(max_length=255,
pattern=r'^[^\r\n]*$'))
value = wtypes.wsattr(wtypes.StringType(max_length=255,
pattern=r'^[^\r\n]*$'))
invert = wtypes.wsattr(bool)
admin_state_up = wtypes.wsattr(bool)
tags = wtypes.wsattr(wtypes.ArrayType(wtypes.StringType(max_length=255)))

View File

@ -32,8 +32,11 @@ class SessionPersistencePOST(types.BaseType):
"""Defines mandatory and optional attributes of a POST request."""
type = wtypes.wsattr(wtypes.Enum(str, *constants.SUPPORTED_SP_TYPES),
mandatory=True)
cookie_name = wtypes.wsattr(wtypes.StringType(max_length=255),
default=None)
# pattern of invalid characters is based on
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
cookie_name = wtypes.wsattr(wtypes.StringType(
max_length=255, pattern=r'^[^\s,;\\]+$'),
default=None)
persistence_timeout = wtypes.wsattr(wtypes.IntegerType(), default=None)
persistence_granularity = wtypes.wsattr(types.IPAddressType(),
default=None)
@ -42,8 +45,11 @@ class SessionPersistencePOST(types.BaseType):
class SessionPersistencePUT(types.BaseType):
"""Defines attributes that are acceptable of a PUT request."""
type = wtypes.wsattr(wtypes.Enum(str, *constants.SUPPORTED_SP_TYPES))
cookie_name = wtypes.wsattr(wtypes.StringType(max_length=255),
default=None)
# pattern of invalid characters is based on
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
cookie_name = wtypes.wsattr(wtypes.StringType(
max_length=255, pattern=r'^[^\s,;\\]+$'),
default=None)
persistence_timeout = wtypes.wsattr(wtypes.IntegerType(), default=None)
persistence_granularity = wtypes.wsattr(types.IPAddressType(),
default=None)

View File

@ -67,12 +67,26 @@ class TestL7RulePOST(base.BaseTypesTest):
body)
def test_invalid_value(self):
body = {"type": "notvalid",
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"value": 123}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_value_whitespace(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"value": "12\n3"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_key_whitespace(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"key": "12\n3"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_invert(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
@ -139,6 +153,16 @@ class TestL7RulePUT(base.BaseTypesTest):
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_value_linefeed(self):
body = {"value": "12\n3"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_key_linefeed(self):
body = {"key": "12\n3"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_invert(self):
body = {"invert": "notvalid"}
self.assertRaises(ValueError, wsme_json.fromjson, self._type,

View File

@ -198,7 +198,17 @@ class TestSessionPersistencePOST(base.BaseTypesTest, TestSessionPersistence):
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_app_cookie_name(self):
body = {"cookie_name": "cookie,monster"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
class TestSessionPersistencePUT(base.BaseTypesTest, TestSessionPersistence):
_type = pool_type.SessionPersistencePUT
def test_invalid_app_cookie_name(self):
body = {"cookie_name": "cookie\nmonster"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)

View File

@ -0,0 +1,9 @@
---
fixes:
- |
Fixed validations in L7 rule and session cookie APIs in order to prevent
authenticated and authorized users to inject code into HAProxy
configuration. CR and LF (\r and \n) are no longer allowed in L7 rule
keys and values. The session persistence cookie names must follow the rules
described in
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie.