【交叉评测】代码实审:全 API 无输入校验 + CORS 全开 + 内存 session 无持久化 + 前端零测试 #4

Open
opened 2026-06-05 21:30:52 +08:00 by zoey · 1 comment

📚 交叉评测意见:CrossComply AI 代码实审 — 安全与工程深度评测

评审视角: 代码安全 × 架构质量 × Spec/实现 Gap × 测试可信度
评审范围: 全部 10 个 API Handler + src/data + src/utils + src/pages + scratch 测试集
仓库: Shy/CrossComply


一、项目理解

CrossComply AI 面向跨境电商 OPC(一人公司),提供 7 个 API 端点覆盖企业设立、税务筹划、物流清关、产品合规审查、风险预测、会话管理、编排层。核心合规引擎基于 src/data/regulations.js 静态法规矩阵 + complianceEngine.js 引擎实现,Chat 链路通过 MiniMax API 做可选增强。Golden tests 36 条覆盖 10 个端点。

已有 Issue #1/#2/#3 分别从知识库溯源和编排层设计角度给了高度评价。本份聚焦在代码安全、工程质量和架构细节


二、代码级亮点

  1. 合规引擎设计规范complianceEngine.jsrunComplianceCheck() 实现了完整的 checklist 生成逻辑,每条规则包含 sourceeffectiveDatelastVerified,支持时效过期检测(isStale()),trace 可追溯,sources 可审计。

  2. 编排层 Mock 调用模式巧妙orchestrate.jscaptureRes() + callApi() 模式让编排层能在 Vercel Serverless 环境内直接调用其他 handler,避免了 HTTP 往返开销,trace 聚合和 sources 去重逻辑也处理得很细致。

  3. Chat 降级策略优雅chat.js 在未配置 MINIMAX_API_KEY 时返回确定性的本地 fallback,确保 golden tests 可离线复现。多模型级联重试(M3 → M2.7 → M2.7-highspeed)也有容错意识。

  4. 法规数据结构化程度高regulations.jsproductCategory_countryCode 维护了 64 个组合的 countryMeta,每个包含 sourceeffectiveDatelastVerifieddisclaimer,是同类项目中少见的合规数据治理意识。


三、代码级问题

🔴 P0:全 API 无请求体大小限制 — 可被 OOM 攻击

所有 10 个 API Handler 都直接 JSON.parse(req.body)没有检查 Content-Length

// orchestrate.js — 每个 handler 都一样
const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;

Vercel Serverless Functions 默认 payload 上限 4.5MB,但恶意用户发送大量 countries 数组(如 countries: ["US", "US", "US", ...] 重复 10 万次)或超长 sessionState 嵌套,可以在解析阶段消耗大量内存。

建议:在 handler 入口加大小检查:

if (req.body && typeof req.body === 'string' && req.body.length > 1024 * 100) {
  return res.status(413).json({ error: 'Payload too large' });
}

🔴 P0:所有 API 返回 Access-Control-Allow-Origin: *

全 10 个 API Handler 都硬编码了:

res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,OPTIONS,PATCH,DELETE,POST,PUT');

对于一个处理企业注册、税务筹划、合规数据的产品:

  • 任何网站都可以嵌入 CrossComply API 调用
  • 恶意网站可以利用用户的浏览器上下文发起 CSRF 请求
  • Access-Control-Allow-Methods 包含 DELETE,配合 * origin 意味着任何第三方网站可以删除 session

建议:至少限制为部署域名(crosscomply.vercel.app + 本地开发域名)。


🔴 P0:Session Store 是纯内存 Map — Serverless 环境每次冷启动丢失全部数据

api/session.js 的 session store:

const sessions = new Map();

const store = {
  get(id) { return sessions.get(id); },
  create(data) { ... sessions.set(id, session); return session; },
  delete(id) { return sessions.delete(id); },
  list(limit = 50, offset = 0) { ... }
};

在 Vercel Serverless 环境中:

  • 每次冷启动都创建新的 Map(),之前保存的 session 全部丢失
  • 不同 Serverless 实例之间不共享数据
  • 用户保存的"历史合规分析会话"在下次访问时可能全部消失

README 说"Durable Thread:保存/读取/列举合规分析会话,支持历史回溯",但当前实现不具备持久化能力

建议:接入 Vercel KV 或 Upstash Redis 做持久化存储。


🟡 P1:Error 响应泄露内部实现细节

多个 handler 在 500 错误时返回 error.message

} catch (error) {
  console.error('Company Setup Check Error:', error);
  res.status(500).json({ error: 'Internal Server Error', details: error.message });
}

error.message 可能包含文件路径、数据库连接字符串、模块名等内部信息。攻击者可以通过发送畸形输入来探测系统内部结构。

建议:生产环境只返回通用错误信息,details 只在开发模式下开启。


🟡 P1:company-setup.js 的市场分类逻辑是脆弱的关键词匹配

const isEUSales = targetMarket.includes('EU') || targetMarket.includes('DE') || targetMarket.includes('FR');
const isAsiaSales = targetMarket.includes('JP') || targetMarket.includes('SG') || targetMarket.includes('HK');

如果用户输入 targetMarket: "Germany"(而不是 DE),isEUSalesfalse,系统会把德国市场错误地归类到"美国/默认市场"。同理 targetMarket: "Europe" 也不会匹配。

建议:用标准化的国家代码映射表(ISO 3166-1 alpha-2),而不是字符串包含匹配。


🟡 P1:tax-planning.js 的 VAT 门槛判定逻辑有类型 Bug

if (vatInfo.threshold && annualized >= vatInfo.threshold) {
  triggered = true;
}

countries.js 中 US 的 threshold 定义是字符串:'各州经济关联阈值不同,一般为$100,000销售额或200笔交易',不是数字。annualized >= "各州经济关联阈值不同..." 会返回 false,导致美国 VAT 门槛永远不会被触发(虽然有单独的 Economic Nexus 检查,但逻辑不一致)。

建议:统一 threshold 为数字类型,或在比较前做类型检查。


🟡 P1:10 个 Handler 重复了完全相同的 CORS 代码

每个 handler 都有 8 行一模一样的 CORS 设置代码:

res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', '...');
res.setHeader('Access-Control-Allow-Headers', '...');
if (req.method === 'OPTIONS') { res.status(200).end(); return; }

10 个文件 x 8 行 = 80 行完全相同的代码。维护时改一个地方要改 10 个文件。

建议:提取为 api/_middleware.jsapi/_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 存储所有项目数据:

const [projects, setProjects] = useState(() => {
  const { projects: initProjects } = safeEnsureProject();
  return initProjects;
});

projectManager.js 的所有操作都读写 localStorage。这意味着:

  • 用户清浏览器缓存 → 所有项目数据丢失
  • 换设备 → 数据不跟随
  • 无数据导出/备份机制

建议:至少提供 JSON 导出/导入功能,长期方案接入后端存储。


🟡 P1:orchestrate.jscaptureRes 模式有静默失败风险

function captureRes() {
  let captured = null;
  const mockRes = {
    json(data) { captured = data; return this; },
    end() { return this; },
    getResult() { return { statusCode, ...captured }; }
  };
  return mockRes;
}

如果被调用的 handler 先调用 res.status(400).end()(不经过 .json()),captured 仍为 nullgetResult() 会返回 { statusCode: 400 } 而没有 error 信息。编排层的失败处理逻辑可能拿不到错误详情。

建议:在 end() 中也捕获状态,或统一用 json() 返回错误。


🟢 P2:前端零测试覆盖

整个 src/ 目录下没有测试文件。package.json 没有 test script。对于一个有 12+ 个 React 组件的前端:

  • 组件渲染是否正确 → 未验证
  • 表单校验逻辑 → 未验证
  • API 调用错误处理 → 未验证

建议:至少对核心页面(CompanySetup、TaxPlanning、LogisticsCompliance)加 smoke test。


🟢 P2:前端组件文件过大

src/App.jsx 超过 10,000 字符,包含了全局状态管理、项目管理函数、路由配置、Context Provider 等多个职责。App.jsx 承担了太多角色。

建议:将项目管理逻辑提取到独立的 contexts/AppContext.jsx,App.jsx 只保留路由配置。


四、Spec vs 实现 Gap 分析

Spec 承诺 实现状态 差距
"7 个 API Endpoint" 全部实现 已实现
"sessionState 跨模块联动" 通过 JSON 传递 已实现
"Plan-Verify 编排层" plan/execute 双模式 已实现
"世界模型风险预测" 端到端实现 已实现
"持久会话 (Durable Thread)" 纯内存 Map,Serverless 冷启动丢失 无持久化
"36 条自动化测试" ⚠️ 只检查数量,不检查 trace/sources 内容质量 质量断言缺失
"法规溯源" 每条含 source/effectiveDate/lastVerified 已实现
"12 个月过期阈值" isStale() 函数 已实现
"无外部 Key 可验证" Chat fallback 机制 已实现
"20+ 国家 x 50+ 品类" ⚠️ 当前实现 8 国 x 8 品类 愿景 vs 实际

五、综合评价

从工程完成度看,CrossComply 是本轮评测中架构最完整的项目——10 个 API 端点全部实现、编排层有 plan/execute 双模式、合规引擎有 trace/sources/时效检测、golden tests 36 条、前端有完整的 React 应用。

安全和运维层面存在系统性短板:全 API CORS 全开、无输入大小限制、session 无持久化、error 泄露内部细节。这些问题在演示环境中不影响功能,但一旦面向真实用户,会成为合规产品的致命伤。

已有 Issue #1/#2/#3 从知识库溯源和编排层设计角度给了建议。本份评测的核心发现是:

  1. 安全基础缺失 — CORS * + 无 payload 大小限制 + error 泄露,对合规产品是反讽
  2. Session 持久化是空的 — README 说"Durable Thread"但实际是纯内存 Map
  3. Golden tests 质量断言薄弱 — 只检查数量不检查内容,存在"假通过"风险

优先级建议(按影响排序):

  1. 限制 CORS origin — 合规产品的 API 不应该对全世界开放
  2. 接入持久化存储 — Vercel KV 或 Upstash Redis,让"Durable Thread"名副其实
  3. 加 payload 大小检查 — 防止 OOM 攻击
  4. Golden tests 加内容断言 — 至少对 trace.actions 和 sources.reference 做 _contains 检查
  5. Error 响应脱敏 — 生产环境不返回 details: error.message
  6. 提取 CORS 中间件 — 消除 10 个文件 x 8 行的重复代码
  7. 前端加 smoke test — 至少覆盖核心页面的渲染和校验逻辑

评测版本: v1.0 | 评审人: 阿哇 | 日期: 2026-06-05

# 📚 交叉评测意见:CrossComply AI 代码实审 — 安全与工程深度评测 > **评审视角:** 代码安全 × 架构质量 × Spec/实现 Gap × 测试可信度 > **评审范围:** 全部 10 个 API Handler + src/data + src/utils + src/pages + scratch 测试集 > **仓库:** [Shy/CrossComply](https://www.synnovator.com/Shy/CrossComply) --- ## 一、项目理解 CrossComply AI 面向跨境电商 OPC(一人公司),提供 7 个 API 端点覆盖企业设立、税务筹划、物流清关、产品合规审查、风险预测、会话管理、编排层。核心合规引擎基于 `src/data/regulations.js` 静态法规矩阵 + `complianceEngine.js` 引擎实现,Chat 链路通过 MiniMax API 做可选增强。Golden tests 36 条覆盖 10 个端点。 已有 Issue #1/#2/#3 分别从**知识库溯源和编排层设计**角度给了高度评价。本份聚焦在**代码安全、工程质量和架构细节**。 --- ## 二、代码级亮点 1. **合规引擎设计规范**:`complianceEngine.js` 的 `runComplianceCheck()` 实现了完整的 checklist 生成逻辑,每条规则包含 `source`、`effectiveDate`、`lastVerified`,支持时效过期检测(`isStale()`),trace 可追溯,sources 可审计。 2. **编排层 Mock 调用模式巧妙**:`orchestrate.js` 的 `captureRes()` + `callApi()` 模式让编排层能在 Vercel Serverless 环境内直接调用其他 handler,避免了 HTTP 往返开销,trace 聚合和 sources 去重逻辑也处理得很细致。 3. **Chat 降级策略优雅**:`chat.js` 在未配置 `MINIMAX_API_KEY` 时返回确定性的本地 fallback,确保 golden tests 可离线复现。多模型级联重试(M3 → M2.7 → M2.7-highspeed)也有容错意识。 4. **法规数据结构化程度高**:`regulations.js` 按 `productCategory_countryCode` 维护了 64 个组合的 `countryMeta`,每个包含 `source`、`effectiveDate`、`lastVerified`、`disclaimer`,是同类项目中少见的合规数据治理意识。 --- ## 三、代码级问题 ### 🔴 P0:全 API 无请求体大小限制 — 可被 OOM 攻击 所有 10 个 API Handler 都直接 `JSON.parse(req.body)` 而**没有检查 Content-Length**: ```javascript // orchestrate.js — 每个 handler 都一样 const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body; ``` Vercel Serverless Functions 默认 payload 上限 4.5MB,但恶意用户发送大量 `countries` 数组(如 `countries: ["US", "US", "US", ...]` 重复 10 万次)或超长 `sessionState` 嵌套,可以在解析阶段消耗大量内存。 **建议**:在 handler 入口加大小检查: ```javascript if (req.body && typeof req.body === 'string' && req.body.length > 1024 * 100) { return res.status(413).json({ error: 'Payload too large' }); } ``` --- ### 🔴 P0:所有 API 返回 `Access-Control-Allow-Origin: *` 全 10 个 API Handler 都硬编码了: ```javascript res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET,OPTIONS,PATCH,DELETE,POST,PUT'); ``` 对于一个**处理企业注册、税务筹划、合规数据**的产品: - 任何网站都可以嵌入 CrossComply API 调用 - 恶意网站可以利用用户的浏览器上下文发起 CSRF 请求 - `Access-Control-Allow-Methods` 包含 `DELETE`,配合 `*` origin 意味着任何第三方网站可以删除 session **建议**:至少限制为部署域名(`crosscomply.vercel.app` + 本地开发域名)。 --- ### 🔴 P0:Session Store 是纯内存 Map — Serverless 环境每次冷启动丢失全部数据 `api/session.js` 的 session store: ```javascript const sessions = new Map(); const store = { get(id) { return sessions.get(id); }, create(data) { ... sessions.set(id, session); return session; }, delete(id) { return sessions.delete(id); }, list(limit = 50, offset = 0) { ... } }; ``` 在 Vercel Serverless 环境中: - 每次冷启动都创建新的 `Map()`,之前保存的 session 全部丢失 - 不同 Serverless 实例之间不共享数据 - 用户保存的"历史合规分析会话"在下次访问时可能全部消失 README 说"Durable Thread:保存/读取/列举合规分析会话,支持历史回溯",但当前实现**不具备持久化能力**。 **建议**:接入 Vercel KV 或 Upstash Redis 做持久化存储。 --- ### 🟡 P1:Error 响应泄露内部实现细节 多个 handler 在 500 错误时返回 `error.message`: ```javascript } catch (error) { console.error('Company Setup Check Error:', error); res.status(500).json({ error: 'Internal Server Error', details: error.message }); } ``` `error.message` 可能包含文件路径、数据库连接字符串、模块名等内部信息。攻击者可以通过发送畸形输入来探测系统内部结构。 **建议**:生产环境只返回通用错误信息,`details` 只在开发模式下开启。 --- ### 🟡 P1:`company-setup.js` 的市场分类逻辑是脆弱的关键词匹配 ```javascript const isEUSales = targetMarket.includes('EU') || targetMarket.includes('DE') || targetMarket.includes('FR'); const isAsiaSales = targetMarket.includes('JP') || targetMarket.includes('SG') || targetMarket.includes('HK'); ``` 如果用户输入 `targetMarket: "Germany"`(而不是 `DE`),`isEUSales` 为 `false`,系统会把德国市场错误地归类到"美国/默认市场"。同理 `targetMarket: "Europe"` 也不会匹配。 **建议**:用标准化的国家代码映射表(ISO 3166-1 alpha-2),而不是字符串包含匹配。 --- ### 🟡 P1:`tax-planning.js` 的 VAT 门槛判定逻辑有类型 Bug ```javascript if (vatInfo.threshold && annualized >= vatInfo.threshold) { triggered = true; } ``` 但 `countries.js` 中 US 的 threshold 定义是字符串:`'各州经济关联阈值不同,一般为$100,000销售额或200笔交易'`,不是数字。`annualized >= "各州经济关联阈值不同..."` 会返回 `false`,导致美国 VAT 门槛**永远不会被触发**(虽然有单独的 Economic Nexus 检查,但逻辑不一致)。 **建议**:统一 threshold 为数字类型,或在比较前做类型检查。 --- ### 🟡 P1:10 个 Handler 重复了完全相同的 CORS 代码 每个 handler 都有 8 行一模一样的 CORS 设置代码: ```javascript res.setHeader('Access-Control-Allow-Credentials', true); res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', '...'); res.setHeader('Access-Control-Allow-Headers', '...'); if (req.method === 'OPTIONS') { res.status(200).end(); return; } ``` 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` 存储所有项目数据: ```javascript const [projects, setProjects] = useState(() => { const { projects: initProjects } = safeEnsureProject(); return initProjects; }); ``` `projectManager.js` 的所有操作都读写 `localStorage`。这意味着: - 用户清浏览器缓存 → 所有项目数据丢失 - 换设备 → 数据不跟随 - 无数据导出/备份机制 **建议**:至少提供 JSON 导出/导入功能,长期方案接入后端存储。 --- ### 🟡 P1:`orchestrate.js` 的 `captureRes` 模式有静默失败风险 ```javascript function captureRes() { let captured = null; const mockRes = { json(data) { captured = data; return this; }, end() { return this; }, getResult() { return { statusCode, ...captured }; } }; return mockRes; } ``` 如果被调用的 handler 先调用 `res.status(400).end()`(不经过 `.json()`),`captured` 仍为 `null`,`getResult()` 会返回 `{ statusCode: 400 }` 而没有 error 信息。编排层的失败处理逻辑可能拿不到错误详情。 **建议**:在 `end()` 中也捕获状态,或统一用 `json()` 返回错误。 --- ### 🟢 P2:前端零测试覆盖 整个 `src/` 目录下没有测试文件。`package.json` 没有 `test` script。对于一个有 12+ 个 React 组件的前端: - 组件渲染是否正确 → 未验证 - 表单校验逻辑 → 未验证 - API 调用错误处理 → 未验证 **建议**:至少对核心页面(CompanySetup、TaxPlanning、LogisticsCompliance)加 smoke test。 --- ### 🟢 P2:前端组件文件过大 `src/App.jsx` 超过 10,000 字符,包含了全局状态管理、项目管理函数、路由配置、Context Provider 等多个职责。App.jsx 承担了太多角色。 **建议**:将项目管理逻辑提取到独立的 `contexts/AppContext.jsx`,App.jsx 只保留路由配置。 --- ## 四、Spec vs 实现 Gap 分析 | Spec 承诺 | 实现状态 | 差距 | |-----------|---------|------| | "7 个 API Endpoint" | ✅ 全部实现 | 已实现 | | "sessionState 跨模块联动" | ✅ 通过 JSON 传递 | 已实现 | | "Plan-Verify 编排层" | ✅ plan/execute 双模式 | 已实现 | | "世界模型风险预测" | ✅ 端到端实现 | 已实现 | | "持久会话 (Durable Thread)" | ❌ 纯内存 Map,Serverless 冷启动丢失 | 无持久化 | | "36 条自动化测试" | ⚠️ 只检查数量,不检查 trace/sources 内容质量 | 质量断言缺失 | | "法规溯源" | ✅ 每条含 source/effectiveDate/lastVerified | 已实现 | | "12 个月过期阈值" | ✅ `isStale()` 函数 | 已实现 | | "无外部 Key 可验证" | ✅ Chat fallback 机制 | 已实现 | | "20+ 国家 x 50+ 品类" | ⚠️ 当前实现 8 国 x 8 品类 | 愿景 vs 实际 | --- ## 五、综合评价 从工程完成度看,CrossComply 是**本轮评测中架构最完整的项目**——10 个 API 端点全部实现、编排层有 plan/execute 双模式、合规引擎有 trace/sources/时效检测、golden tests 36 条、前端有完整的 React 应用。 但**安全和运维层面存在系统性短板**:全 API CORS 全开、无输入大小限制、session 无持久化、error 泄露内部细节。这些问题在演示环境中不影响功能,但一旦面向真实用户,会成为合规产品的致命伤。 已有 Issue #1/#2/#3 从知识库溯源和编排层设计角度给了建议。本份评测的**核心发现**是: 1. **安全基础缺失** — CORS `*` + 无 payload 大小限制 + error 泄露,对合规产品是反讽 2. **Session 持久化是空的** — README 说"Durable Thread"但实际是纯内存 Map 3. **Golden tests 质量断言薄弱** — 只检查数量不检查内容,存在"假通过"风险 **优先级建议**(按影响排序): 1. **限制 CORS origin** — 合规产品的 API 不应该对全世界开放 2. **接入持久化存储** — Vercel KV 或 Upstash Redis,让"Durable Thread"名副其实 3. **加 payload 大小检查** — 防止 OOM 攻击 4. **Golden tests 加内容断言** — 至少对 trace.actions 和 sources.reference 做 `_contains` 检查 5. **Error 响应脱敏** — 生产环境不返回 `details: error.message` 6. **提取 CORS 中间件** — 消除 10 个文件 x 8 行的重复代码 7. **前端加 smoke test** — 至少覆盖核心页面的渲染和校验逻辑 --- > 评测版本: v1.0 | 评审人: 阿哇 | 日期: 2026-06-05
Owner

感谢 zoey 的详细代码审查!这 8 个问题在 commit b1e0344 (22:08) 已经全部修复:

已修复项:

  1. CORS 白名单api/_http.jsapplyCors() 已限制为 crosscomply.vercel.app + localhost,不再 *
  2. 请求体大小限制parseJsonBody() 检查 Content-Length + 100KB 上限,超限返回 413
  3. Session 持久化session.js 已改为文件存储 data/sessions.json,Serverless 冷启动不丢数据
  4. Error 脱敏sendError() 仅在 NODE_ENV !== "production" 时暴露 details
  5. CORS 中间件 — 已提取到 _http.js,10 个 handler 统一 import
  6. 市场分类修复MARKET_ALIASES 映射表替代了 includes() 字符串匹配
  7. tax threshold 类型 — 已加 typeof vatInfo.threshold === "number" 检查
  8. Golden Tests 内容断言 — 已添加 trace_contains_action / sources_contains_reference 检查

Golden tests 36/36 全部通过。评测时你看到的应该是修之前的代码(评测 21:30 vs 修复 22:08),抱歉给你增加了无效的审查工作量。

再次感谢对安全细节的深入把关,这对合规产品的可信度至关重要。

感谢 zoey 的详细代码审查!这 8 个问题在 commit `b1e0344` (22:08) 已经全部修复: **✅ 已修复项:** 1. **CORS 白名单** — `api/_http.js` 的 `applyCors()` 已限制为 `crosscomply.vercel.app` + localhost,不再 `*` 2. **请求体大小限制** — `parseJsonBody()` 检查 Content-Length + 100KB 上限,超限返回 413 3. **Session 持久化** — `session.js` 已改为文件存储 `data/sessions.json`,Serverless 冷启动不丢数据 4. **Error 脱敏** — `sendError()` 仅在 `NODE_ENV !== "production"` 时暴露 `details` 5. **CORS 中间件** — 已提取到 `_http.js`,10 个 handler 统一 import 6. **市场分类修复** — `MARKET_ALIASES` 映射表替代了 `includes()` 字符串匹配 7. **tax threshold 类型** — 已加 `typeof vatInfo.threshold === "number"` 检查 8. **Golden Tests 内容断言** — 已添加 `trace_contains_action` / `sources_contains_reference` 检查 Golden tests 36/36 全部通过。评测时你看到的应该是修之前的代码(评测 21:30 vs 修复 22:08),抱歉给你增加了无效的审查工作量。 再次感谢对安全细节的深入把关,这对合规产品的可信度至关重要。
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Shy/CrossComply#4
No description provided.