安全模型
qzjs 是面向可信脚本的可嵌入运行时,不是运行不可信代码的沙箱。本页明确 陈述边界,便于你推理部署方式并正确上报问题。
上报漏洞
安全漏洞不要开公开 GitHub issue。
请通过 GitHub Security Advisories 私下上报。请包含:
- 受影响版本(commit hash 或 release tag),
- 问题描述与影响,
- 复现步骤或 PoC,
- 已知缓解措施。
你应在 7 天内收到确认,30 天内收到状态更新。修复就绪后,我们会与你 协调披露,并在 advisory 中致谢(除非你希望匿名)。
支持的版本
安全修复应用于最新 release 与当前 master 分支。旧版本不做回溯移植。
威胁模型
在范围内
让数据跨越运行时自身划定的边界、或让意外输入破坏内存/崩溃进程的缺陷:
- 字节码读取器(
JS_ReadObject)处理畸形或恶意字节码, - IPC 信封解码器,以及 HTTP/WS/HTTP2/protobuf 解析器处理来自对端进程或 网络的畸形输入,
- 经由公开 API 从脚本可达的内存安全缺陷,
- 密码学正确性(
crypto.subtle、TLS 配置、随机数)。
若你能让不可信输入——网络字节、字节码、来自不可信对端的 IPC 帧——导致 内存破坏、逃出解析器边界或绕过显式校验,那就在范围内。
按设计不在范围内
脚本本就合法拥有的能力。这些不是逃逸:
- 文件系统 — 脚本可读写宿主进程能访问的任意路径。路径校验只拒绝
..组件;没有根隔离,也没有权限模型。见 fs。 - 派生进程 — 脚本可派生进程(
pal.processSpawn→execv)。 - 环境 — 脚本可通过
globalThis.env读取完整环境。 - 与宿主共处 — 脚本与宿主同进程(THREAD 后端)或处于兄弟进程 (ISOLATED 后端);两者都不是针对恶意脚本的安全边界。
- 网络暴露 —
serve()默认绑定127.0.0.1,且没有认证中间件。 传hostname: '0.0.0.0'会把它暴露到网络——若这么做,请在前方放置你自己的 认证。
部署指引
由于运行时信任其脚本,qzjs 部署的安全性即你宿主应用边界的安全性:
- 把脚本当作第一方代码。 若其中任何部分来自不可信来源,在没有你自己的 隔离(独立 OS 用户、容器、虚拟机或 seccomp 策略)时,不要放进 qzjs 运行时 执行。
- 不要把
serve()直接暴露到公网。 它是个裸服务器。绑定回环,前置一个 终结 TLS 并强制认证的反向代理。 - 约束进程可达范围。 文件系统、环境与派生能力的范围等同于宿主进程自身 的权限。若工作负载不需要,就在 OS 层降权。
- 隔离在运维上重要时优先
ISOLATED。 崩溃或卡死的 worker 不会拖垮主 运行时,进程边界对资源限制也更干净。但它仍不是针对恶意脚本的安全边界。 - 校验 TLS 对端。 运行时对出站 TLS 执行 SNI 与证书主机名校验;校验失败 对该连接是致命的,而非静默忽略。
- 审计代理配置。
fetch遵循环境中的HTTP_PROXY/HTTPS_PROXY/NO_PROXY。不支持的代理 scheme 会 fail closed,而非静默绕过代理——但任何 能设置这些变量的进程都能改写出站流量。
上游依赖
qzjs 将依赖作为固定的 git 子模块置于 deps/ 下,外加本地补丁 (deps/*.patch)。
上游 quickjs-ng 明确将字节码读取器加固列为项目外,因此针对内置读取器的 畸形字节码问题应报给我们,而非上游。
捆绑依赖中的问题请先报给我们,以便评估对本运行时的影响;我们会酌情一并 转交上游。