fix(server): 契约正则锚点\Z闭合——尾换行脏值不再放行
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -12,9 +12,10 @@ _URL_DROP_KEY = re.compile("|".join(C.URL_PARAM_DROP_PATTERNS), re.I)
|
||||
_BIZ_CHANNEL = {"whatsapp", "phone", "email"}
|
||||
_BIZ_RESULT = {"mail_sent", "mail_failed"}
|
||||
_BIZ_ERROR = {"invalid", "spam", "other"}
|
||||
_SUBMIT_RE = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$|^$") # uuid4,可空
|
||||
_FORM_RE = re.compile(r"^cf7-\d{1,10}$") # CF7 表单 DOM id(f{n}-p{m} → 服务端规范化为 cf7-{form_id})
|
||||
_PROD_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$") # slug ≤100
|
||||
# 锚点一律 \Z 而非 $:Python `$` 匹配串尾换行前,"cf7-156\n" 等脏值会被放行(collect 端点公开)
|
||||
_SUBMIT_RE = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\Z|\Z") # uuid4,可空
|
||||
_FORM_RE = re.compile(r"^cf7-\d{1,10}\Z") # CF7 表单 DOM id(f{n}-p{m} → 服务端规范化为 cf7-{form_id})
|
||||
_PROD_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,99}\Z") # slug ≤100
|
||||
|
||||
def _biz_props_ok(name, props) -> bool:
|
||||
"""业务事件属性逐键校验(spec §2 枚举/格式表;全部非自由文本)。
|
||||
|
||||
@@ -124,6 +124,9 @@ def _biz(name, **props):
|
||||
(_biz("form_submit_result", form_id="cf7-156", submission_id="", result_code="ok"), "property_not_allowed"),
|
||||
(_biz("product_view", product_id="byd-equation-leopard-5", inferred=True, rule_version="v1"), None),
|
||||
(_biz("product_view", product_id="x"*101, inferred=True, rule_version="v1"), "property_not_allowed"),
|
||||
# 尾换行脏值:$ 锚匹配串尾换行前,\Z 才是真正串尾——collect 端点公开,须拒
|
||||
(_biz("form_start", form_id="cf7-156\n"), "property_not_allowed"),
|
||||
(_biz("form_submit", form_id="cf7-156", submission_id="9c8b7a6d-1111-4222-8333-444455556666\n"), "property_not_allowed"),
|
||||
])
|
||||
def test_biz_event_validation(ev, expect_reason):
|
||||
assert validate_event(ev, v2=True, batch_site_id=SITE_ID, batch_visitor_id="v1") == expect_reason
|
||||
|
||||
Reference in New Issue
Block a user