feat(server): URL清洗三轨制+共享测试向量(D08)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-18 10:15:42 +08:00
parent 73af568c3f
commit 5881046a2d
4 changed files with 63 additions and 9 deletions
+17 -4
View File
@@ -17,11 +17,24 @@ def _utf8_ok(s: str) -> bool:
return False
def sanitize_url(url: str) -> str:
"""按参数名整键删除(fullmatch 防止误伤 monkey 这类含 key 子串的参数)。"""
"""三轨制清洗(spec §2.4):黑名单参数名删 + 归因白名单提 + 其余按值判别。
另:userinfo 剥离、fragment 删除。规则版本 SANITIZE_RULE_VERSION。"""
p = urlparse(url)
kept = [(k, v) for k, v in parse_qsl(p.query, keep_blank_values=True)
if not _URL_DROP_KEY.fullmatch(k)]
return p._replace(query=urlencode(kept)).geturl()
kept = []
for k, v in parse_qsl(p.query, keep_blank_values=True):
if _URL_DROP_KEY.fullmatch(k):
continue
if k.lower() in C.ATTRIBUTION_PARAM_WHITELIST or k.lower().startswith("utm_"):
kept.append((k, v)); continue
if C._SAFE_VALUE.match(v or ""):
kept.append((k, v))
netloc = p.hostname or ""
try:
if p.port:
netloc = f"{netloc}:{p.port}"
except ValueError:
pass # 非法端口(如 :abc)——剥离端口降级,不让入口清洗抛异常
return p._replace(netloc=netloc, query=urlencode(kept), fragment="").geturl()
def _walk_props(v, depth=0):
"""单次递归同时做深度检查、敏感键扫描与字符串超长检查。