Files
fangke/server/tracker/tests/test_validation.py
T
浅念 f2a5f7611a fix: 校验加固(嵌套敏感键/naive时间防御)
- _depth_ok 与敏感键扫描合并为单次递归 _walk_props,dict 所有层级键均过
  _SENSITIVE(此前嵌套键不扫描,utm 白名单内可夹带敏感键)
- occurred_at 为 naive datetime 时返回 invalid_occurred_at(原为 TypeError 500)
- 删除未使用的 timedelta 导入
- 深度超限即停止下探,10 万层嵌套不爆栈

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-15 12:04:40 +08:00

50 lines
2.0 KiB
Python

from datetime import datetime, timedelta
from django.utils import timezone
from tracker.services.validation import validate_event, sanitize_url
NOW = timezone.now()
def _ev(**kw):
base = dict(event_id="e1", event_name="page_view",
occurred_at=NOW, path="/p", title="t", properties={})
base.update(kw)
return base
def test_ok_event():
assert validate_event(_ev()) is None # None = 通过
def test_unknown_event_name():
assert validate_event(_ev(event_name="xxx")) == "event_name_not_allowed"
def test_sensitive_property_rejected():
r = validate_event(_ev(properties={"user_password": "1"}))
assert "sensitive" in r
def test_shape_type_and_whitelist():
assert validate_event(["x"]) == "event_invalid_shape"
assert validate_event(_ev(event_id=123)) == "invalid_event_id"
assert validate_event(_ev(properties={"foo": "bar"})) == "property_not_allowed"
def test_too_many_props_and_long_string():
r = validate_event(_ev(properties={f"k{i}": "v" for i in range(40)}))
assert "properties" in r
r = validate_event(_ev(properties={"referrer": "x" * 600}))
assert "properties" in r
def test_future_and_stale_time():
r = validate_event(_ev(occurred_at=NOW + timedelta(days=2)))
assert "occurred_at" in r # 超窗拒绝
assert validate_event(_ev(occurred_at=NOW - timedelta(hours=2))) is None # 窗内迟到可收
def test_sanitize_url_drops_sensitive_params():
u = sanitize_url("/p?email=a@b.com&token=x&id=3&utm_source=google&monkey=1")
assert "email=" not in u and "token=" not in u and "utm_source=google" in u
assert "monkey=1" in u # fullmatch:含 key 子串的正常参数不误伤
def test_nested_sensitive_key_rejected():
r = validate_event(_ev(properties={"utm": {"utm_a": 1, "user_password": "x"}}))
assert "sensitive" in r # utm 在 page_view 白名单内,嵌套敏感键仍须命中
def test_naive_datetime_rejected():
assert validate_event(_ev(occurred_at=NOW.replace(tzinfo=None))) == "invalid_occurred_at"