Skip to content

feat(cli): 磁盘缓存+ETag & 安全 URL 规则求值,让消费方脱离 Node 纯 shell #16

Description

@MasonChow

背景

有个消费方(值班告警诊断 skill)在用 source-map-parser CLI 把 minified stack 映射回源码。目标是让它彻底脱离 Node、纯 shell(jq 拼 stack)+ CLI 完成。目前还差两块能力,仍被迫保留一层 Node 编排脚本来补:

  1. 跨进程磁盘缓存 + ETag——CLI 现在只有 map 里那个进程内 HashMap(单次调用内去重),load_map 是裸 ureq::get,无磁盘缓存、无条件请求。消费方场景是「同一 release 的 5MB+ .map 在多张工单反复出现」,每次重下代价大,故目前由 Node 侧 cached-fetch(磁盘 LRU + If-None-Match)兜着。
  2. 安全的 URL 规则求值——上游 APM 按项目返回一段 JS 规则(形如 originUrl.replace('/assets/','/sm/').replace('.js','.js.map'))把 JS URL 映射成 .map URL。CLI 的 --map-url-template 只做 {url} 字面替换,表达不了任意 .replace 链,所以消费方仍在 Node 里用 new Function(rule) eval(RCE 隐患)。

诉求

1. 磁盘缓存 + ETag(--map-url-template 拉取路径)

  • load_map 拉取远程 .map 时接入磁盘缓存:命中且有 ETag → 落盘;下次带 If-None-Match,304 直读盘。
  • 缓存目录可配(env,如 SOURCE_MAP_PARSER_CACHE_DIR),容量 LRU(按 size,默认值可对齐现有 MCP 的 200MB)。
  • 参考实现:source-map-parser-mcpcachingFetch / memoryCacheManager(把内存版落到磁盘即可)。
  • 建议加 --no-cache 显式关闭。

2. 安全 URL 规则(替代 new Function

二选一(或都做):

  • 方案 A(推荐):新增 --map-url-replace <FROM> <TO>(可重复,按顺序 apply 到 JS URL 得 .map URL)。覆盖绝大多数 APM 规则(就是若干次字面/正则 replace),且完全无 eval。
    source-map-parser map --stack - \
      --map-url-replace '/assets/' '/sourcemaps/' \
      --map-url-replace '.js' '.js.map'
    
  • 方案 B:接受 APM 那段 rule 字符串,在 Rust 侧用受限求值器(只允许 originUrl + 链式 .replace(strOrRegex, str),AST 白名单,非通用 JS eval)跑,例如 --map-url-rule '<rule>'。这样消费方可直接把 APM 原样规则透传,CLI 安全求值,彻底消除 Node 侧 RCE。

收益

上述两条到位后,消费方可整体删掉 Node 编排层,改成 jq 拼 stack | source-map-parser map --map-url-replace ... / --map-url-rule ...,做到无 Node、无 node_modules、无 RCE

参考

  • 现状代码:crates/cli/src/main.rsload_map 约 324 行、进程内 cache 约 239 行、--map-url-template 约 305 行)。
  • 消费方现在的临时形态(保留 Node 编排 + cached-fetch):见下游 agent-factory MR(sourcemap 解析改用原生 CLI)。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions