技能|离线隔离逻辑验证法
适用场景
需要验证后端某个接口的业务逻辑,但无法在线实跑:
- 默认口令已被用户改拿不到,鉴权中间件拦截所有需登录端点;
- 运行态是冻结 EXE,起第二个实例会轮换 token 把用户踢下线;
- 本机 Python 环境缺
fastapi,无法 import 整个 app。
此时既不要索要密码,也不要重启服务,用本法在不碰运行态的前提下拿到可信结论。
操作步骤
-
AST 抽取真实函数源码(不手抄,避免抄错版本):
python import ast tree = ast.parse(open(APP, encoding="utf-8", errors="ignore").read()) for n in ast.walk(tree): if isinstance(n, ast.FunctionDef) and n.name == "api_calendar_day": src = ast.unparse(n) -
构造最小命名空间桩(只补函数真正依赖的名字):
python ns = { "re": re, "os": os, "json": json, "app": type("A", (), {"get": lambda *a, **k: (lambda f: f), "post": lambda *a, **k: (lambda f: f)}), "append_log": lambda *a, **k: None, "vault_graph": lambda *a, **k: (...5元组...), } exec(src, ns) -
同步/异步自适应调用:
python import asyncio, inspect def callit(fn, *a, **k): if inspect.iscoroutinefunction(fn): return asyncio.run(fn(*a, **k)) return fn(*a, **k) -
写操作指向临时目录,绝不碰真实数据目录:
把WB_DIR桩成tempfile.gettempdir(),验证落盘后再os.remove。 -
报告里如实声明局限:写明「鉴权受限,本次为隔离逻辑验证,非在线实跑」,并建议移交后在客户环境补一次在线回归。
注意边界
- 只对无副作用或可指向临时目录的函数做隔离执行;有副作用的写接口不要在真实库上跑。
- 桩只补真正用到的名字,不要把整个 app 的依赖都搬进来(会掩盖真实缺失)。
- 路由装饰器
@app.get(...)需要app桩,否则exec时NameError。
反例避雷(本轮三次踩坑)
| 错误做法 | 现象 | 正解 |
|---|---|---|
把源码路径字符串传给 ast.parse |
静默取不到目标,报「未能提取」 | 必须传 open(path).read() 的内容 |
用文本 in 断言源码含某正则 |
ast.unparse 会把 raw 串 r"^\d{4}…" 还原成转义形式,匹配必失败 |
直接从 AST 取 ast.Constant.value 再 re.match 实测 |
JSONResponse 桩的 __init__ 返回元组 |
属性赋值不生效,status_code 恒为默认 |
桩函数返回 None(Python 构造器不能 return 值) |
缺 vault_graph 等重依赖桩 |
合法入参路径直接抛 NameError 被记成 FAIL |
按需补齐,或该项改用源码级断言 |