【交叉评测】代码实审:全 API 无输入校验 + CORS 全开 + 内存 session 无持久化 + 前端零测试 #4
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📚 交叉评测意见:CrossComply AI 代码实审 — 安全与工程深度评测
一、项目理解
CrossComply AI 面向跨境电商 OPC(一人公司),提供 7 个 API 端点覆盖企业设立、税务筹划、物流清关、产品合规审查、风险预测、会话管理、编排层。核心合规引擎基于
src/data/regulations.js静态法规矩阵 +complianceEngine.js引擎实现,Chat 链路通过 MiniMax API 做可选增强。Golden tests 36 条覆盖 10 个端点。已有 Issue #1/#2/#3 分别从知识库溯源和编排层设计角度给了高度评价。本份聚焦在代码安全、工程质量和架构细节。
二、代码级亮点
合规引擎设计规范:
complianceEngine.js的runComplianceCheck()实现了完整的 checklist 生成逻辑,每条规则包含source、effectiveDate、lastVerified,支持时效过期检测(isStale()),trace 可追溯,sources 可审计。编排层 Mock 调用模式巧妙:
orchestrate.js的captureRes()+callApi()模式让编排层能在 Vercel Serverless 环境内直接调用其他 handler,避免了 HTTP 往返开销,trace 聚合和 sources 去重逻辑也处理得很细致。Chat 降级策略优雅:
chat.js在未配置MINIMAX_API_KEY时返回确定性的本地 fallback,确保 golden tests 可离线复现。多模型级联重试(M3 → M2.7 → M2.7-highspeed)也有容错意识。法规数据结构化程度高:
regulations.js按productCategory_countryCode维护了 64 个组合的countryMeta,每个包含source、effectiveDate、lastVerified、disclaimer,是同类项目中少见的合规数据治理意识。三、代码级问题
🔴 P0:全 API 无请求体大小限制 — 可被 OOM 攻击
所有 10 个 API Handler 都直接
JSON.parse(req.body)而没有检查 Content-Length:Vercel Serverless Functions 默认 payload 上限 4.5MB,但恶意用户发送大量
countries数组(如countries: ["US", "US", "US", ...]重复 10 万次)或超长sessionState嵌套,可以在解析阶段消耗大量内存。建议:在 handler 入口加大小检查:
🔴 P0:所有 API 返回
Access-Control-Allow-Origin: *全 10 个 API Handler 都硬编码了:
对于一个处理企业注册、税务筹划、合规数据的产品:
Access-Control-Allow-Methods包含DELETE,配合*origin 意味着任何第三方网站可以删除 session建议:至少限制为部署域名(
crosscomply.vercel.app+ 本地开发域名)。🔴 P0:Session Store 是纯内存 Map — Serverless 环境每次冷启动丢失全部数据
api/session.js的 session store:在 Vercel Serverless 环境中:
Map(),之前保存的 session 全部丢失README 说"Durable Thread:保存/读取/列举合规分析会话,支持历史回溯",但当前实现不具备持久化能力。
建议:接入 Vercel KV 或 Upstash Redis 做持久化存储。
🟡 P1:Error 响应泄露内部实现细节
多个 handler 在 500 错误时返回
error.message:error.message可能包含文件路径、数据库连接字符串、模块名等内部信息。攻击者可以通过发送畸形输入来探测系统内部结构。建议:生产环境只返回通用错误信息,
details只在开发模式下开启。🟡 P1:
company-setup.js的市场分类逻辑是脆弱的关键词匹配如果用户输入
targetMarket: "Germany"(而不是DE),isEUSales为false,系统会把德国市场错误地归类到"美国/默认市场"。同理targetMarket: "Europe"也不会匹配。建议:用标准化的国家代码映射表(ISO 3166-1 alpha-2),而不是字符串包含匹配。
🟡 P1:
tax-planning.js的 VAT 门槛判定逻辑有类型 Bug但
countries.js中 US 的 threshold 定义是字符串:'各州经济关联阈值不同,一般为$100,000销售额或200笔交易',不是数字。annualized >= "各州经济关联阈值不同..."会返回false,导致美国 VAT 门槛永远不会被触发(虽然有单独的 Economic Nexus 检查,但逻辑不一致)。建议:统一 threshold 为数字类型,或在比较前做类型检查。
🟡 P1:10 个 Handler 重复了完全相同的 CORS 代码
每个 handler 都有 8 行一模一样的 CORS 设置代码:
10 个文件 x 8 行 = 80 行完全相同的代码。维护时改一个地方要改 10 个文件。
建议:提取为
api/_middleware.js或api/_cors.js共享中间件。🟡 P1:Golden Tests 不覆盖 Trace 和 Sources 的内容质量
run-golden-tests.js的断言检查:trace_steps_gte: 3→ 只检查 trace 数量sources_count_gte: 2→ 只检查 sources 数量但不检查 trace 中的 action 是否有意义,也不检查 sources 中的 reference 是否真实存在。一个 API 返回
trace: [{step: "noop"}]和sources: [{type: "fake", reference: "none"}]也能通过。建议:至少对核心测试用例加 trace.action 的
_contains断言和 sources.reference 的格式检查。🟡 P1:前端 localStorage 是唯一的持久化层
App.jsx使用localStorage存储所有项目数据:projectManager.js的所有操作都读写localStorage。这意味着:建议:至少提供 JSON 导出/导入功能,长期方案接入后端存储。
🟡 P1:
orchestrate.js的captureRes模式有静默失败风险如果被调用的 handler 先调用
res.status(400).end()(不经过.json()),captured仍为null,getResult()会返回{ statusCode: 400 }而没有 error 信息。编排层的失败处理逻辑可能拿不到错误详情。建议:在
end()中也捕获状态,或统一用json()返回错误。🟢 P2:前端零测试覆盖
整个
src/目录下没有测试文件。package.json没有testscript。对于一个有 12+ 个 React 组件的前端:建议:至少对核心页面(CompanySetup、TaxPlanning、LogisticsCompliance)加 smoke test。
🟢 P2:前端组件文件过大
src/App.jsx超过 10,000 字符,包含了全局状态管理、项目管理函数、路由配置、Context Provider 等多个职责。App.jsx 承担了太多角色。建议:将项目管理逻辑提取到独立的
contexts/AppContext.jsx,App.jsx 只保留路由配置。四、Spec vs 实现 Gap 分析
isStale()函数五、综合评价
从工程完成度看,CrossComply 是本轮评测中架构最完整的项目——10 个 API 端点全部实现、编排层有 plan/execute 双模式、合规引擎有 trace/sources/时效检测、golden tests 36 条、前端有完整的 React 应用。
但安全和运维层面存在系统性短板:全 API CORS 全开、无输入大小限制、session 无持久化、error 泄露内部细节。这些问题在演示环境中不影响功能,但一旦面向真实用户,会成为合规产品的致命伤。
已有 Issue #1/#2/#3 从知识库溯源和编排层设计角度给了建议。本份评测的核心发现是:
*+ 无 payload 大小限制 + error 泄露,对合规产品是反讽优先级建议(按影响排序):
_contains检查details: error.message感谢 zoey 的详细代码审查!这 8 个问题在 commit
b1e0344(22:08) 已经全部修复:✅ 已修复项:
api/_http.js的applyCors()已限制为crosscomply.vercel.app+ localhost,不再*parseJsonBody()检查 Content-Length + 100KB 上限,超限返回 413session.js已改为文件存储data/sessions.json,Serverless 冷启动不丢数据sendError()仅在NODE_ENV !== "production"时暴露details_http.js,10 个 handler 统一 importMARKET_ALIASES映射表替代了includes()字符串匹配typeof vatInfo.threshold === "number"检查trace_contains_action/sources_contains_reference检查Golden tests 36/36 全部通过。评测时你看到的应该是修之前的代码(评测 21:30 vs 修复 22:08),抱歉给你增加了无效的审查工作量。
再次感谢对安全细节的深入把关,这对合规产品的可信度至关重要。