From be0b53bce4d2ace92d08e922cb57301a6fe72e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Fri, 18 Sep 2026 22:24:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(server):=20=E5=A5=91=E7=BA=A6=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E9=94=9A=E7=82=B9\Z=E9=97=AD=E5=90=88=E2=80=94?= =?UTF-8?q?=E2=80=94=E5=B0=BE=E6=8D=A2=E8=A1=8C=E8=84=8F=E5=80=BC=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E6=94=BE=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Code --- server/tracker/services/validation.py | 7 ++++--- server/tracker/tests/test_validation.py | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/server/tracker/services/validation.py b/server/tracker/services/validation.py index cffdff5..bd30de7 100644 --- a/server/tracker/services/validation.py +++ b/server/tracker/services/validation.py @@ -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 枚举/格式表;全部非自由文本)。 diff --git a/server/tracker/tests/test_validation.py b/server/tracker/tests/test_validation.py index 86ae9bc..e5f1d6d 100644 --- a/server/tracker/tests/test_validation.py +++ b/server/tracker/tests/test_validation.py @@ -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