nyx/README.zh-CN.md
2026-06-05 10:16:30 -05:00

18 KiB
Raw Permalink Blame History

NYX

本地优先的安全扫描器,带沙箱动态验证和浏览器 UI。在本地扫描代码仓库并在浏览器中分诊处理无需云端、无需账号。

crates.io License: GPL v3 Rust 1.88+ CI Docs

English · 简体中文

Nyx UI 演示:从空欢迎页开始扫描,查看含健康分的总览页,钻入一条 HIGH 级发现的流可视化,再到分诊流程


本地扫描,本地浏览

Nyx 在你的代码仓库上运行跨语言污点分析,然后对中高置信度发现运行小型沙箱 harness验证真实代码里 source 到 sink 的流是否会触发。结果通过绑定到 127.0.0.1 的 React UI 提供给你。你会看到严重等级、静态证据、动态验证结果,以及分步流可视化,从源 → 净化器 → 汇逐步呈现数据流。分诊决策持久化在 .nyx/triage.json 中,与代码一同提交,团队共享同一份分诊状态。

cargo install nyx-scanner
nyx scan           # 运行分析器,把发现缓存到 .nyx/
nyx serve          # 在浏览器中打开 http://localhost:9700

一切都留在你本地:仅回环绑定、强制 host 头校验、所有变更操作均带 CSRF、无远程遥测、无登录。

一个小型 JS 应用的总览仪表盘:健康分 C 78,五项分量分解(严重度压力、置信度质量、趋势、分诊覆盖、回归抗性),3 条发现,OWASP A03 与 A02 类别,置信度分布与问题类别条形图,受影响最多的文件


UI 中包含什么

页面 显示内容
总览 仪表盘:按严重等级分类的发现计数、热点文件、引擎画像摘要
发现 可浏览列表,含严重度徽章、分诊状态、规则筛选、语言筛选
发现详情 流路径可视化,带编号步骤(源 → 净化器 → 汇)、动态验证结果、代码片段、证据、跨文件标记、分诊下拉框
分诊 批量更新状态open、investigating、fixed、false_positive、accepted_risk、suppressed审计日志JSON 导入/导出
资源管理器 文件树,含每个文件的符号列表与发现叠加层
扫描 历史记录、指标,对比两次扫描查看差异
规则 各语言的内置与自定义规则;可在 UI 中添加规则
配置 实时配置编辑器;无需重启即可重载

nyx serve 参数:--port <N>(默认 9700)、--host <addr>(仅回环:127.0.0.1localhost::1)、--no-browser。持久化设置见 nyx.conf[server] 段,分页面 UI 介绍与安全模型详见 Browser UI 指南


用于 CI 的 CLI

同一个引擎可以无头运行用于 CI 流水线。SARIF 输出可直接上传到 GitHub Code Scanning。

nyx scan 终端输出:JS 与 Python 文件中的 HIGH 级污点发现及 source → sink 箭头

# 在 medium 及以上等级让 CI 失败,并输出 SARIF
nyx scan --format sarif --fail-on MEDIUM > results.sarif

# 临时 JSON无索引
nyx scan ./server --format json --index off

# 仅 AST 模式(最快;跳过 CFG + 污点)
nyx scan --mode ast

# 引擎深度快捷方式fast | balanced默认 | deep
# `deep` 增加 symex 与按需后向污点,精度更高,开销约 2-3 倍
nyx scan --engine-profile deep

正向跨文件污点在所有画像下都会运行。Symex 与按需后向遍历是可选项,可通过 --engine-profile deep 一次性开启,或单独开启(--symex--backwards-analysis)。完整开关矩阵见 CLI 参考

GitHub Action

- uses: elicpeter/nyx@v0.8.0
  with:
    format: sarif
    fail-on: MEDIUM
- uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: nyx-results.sarif

输入:pathversionformatsarif|json|console)、fail-onargstoken。输出:finding-countsarif-fileexit-codenyx-version。支持 Linux 与 macOS runnerx86_64、ARM64


安装

Cargo推荐

cargo install nyx-scanner

预编译二进制:Releases 下载对应平台的归档包,对照 SHA256SUMS(以及随附的 SHA256SUMS.asc GPG 签名,如有提供)校验,解压并把 nyx 放到 PATH 中。

# 可选:校验校验文件的 GPG 签名(当 SHA256SUMS.asc 已发布时)
gpg --verify SHA256SUMS.asc SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing
unzip nyx-x86_64-unknown-linux-gnu.zip && chmod +x nyx && sudo mv nyx /usr/local/bin/

从源码编译:

git clone https://github.com/elicpeter/nyx.git
cd nyx && cargo build --release

需要 stable Rust 1.88+。前端会在编译期被打包嵌入二进制中,因此 nyx serve 没有单独的安装步骤。


语言支持

全部 10 种语言都通过 tree-sitter 解析并跑完整流水线,但规则深度与引擎覆盖并不均衡。在 tests/benchmark/ground_truth.json 的合成语料上,所有十种语言在最近一次基线测量中 F1 均为 100%(见 tests/benchmark/RESULTS.md),因此 F1 已无法单独区分梯度。分级反映规则深度、门控汇覆盖、以及合成语料未充分覆盖的结构性惯用法:

梯度 语言 F1 适合用作 CI 门禁吗?
稳定 Python、JavaScript、TypeScript 100% 适合
Beta Java、PHP、Ruby、Rust、Go 100% 适合,需轻度 FP 分诊
预览 C、C++ 合成语料 100% 不适合。已跟踪 STL 容器流、builder 链、内联类成员函数;尚未覆盖深度指针别名与函数指针。建议与 clang-tidy 或 Clang Static Analyzer 搭配使用

所有真实 CVE 用例均触发,语料在记录基线下无未关闭的 FPP=R=F1=1.000)。各维度详情与已知盲区见 语言成熟度页面

通过真实 CVE 验证

语料中还包含一小批从公开公告中提取的「漏洞 / 已修复」配对,因此基准下限不仅由合成的同形测例守护,还由对真实 bug 的回归保护守护。每个配对 Nyx 都在漏洞文件上触发、在已修复文件上零发现。

CVE 项目 语言 类别
CVE-2023-48022 Ray Python 命令注入
CVE-2017-18342 PyYAML Python 反序列化
CVE-2019-14939 mongo-express JavaScript 代码执行(eval
CVE-2023-22621 Strapi JavaScript 代码执行SSTI
CVE-2025-64430 Parse Server JavaScript SSRF
CVE-2023-26159 follow-redirects TypeScript SSRF
GHSA-4x48-cgf9-q33f Novu TypeScript SSRF
CVE-2026-25544 Payload CMS TypeScript SQL 注入
CVE-2022-30323 hashicorp/go-getter Go 命令注入
CVE-2024-31450 owncast Go 路径穿越
CVE-2023-3188 owncast Go SSRF
CVE-2026-41422 daptin Go SQL 注入
CVE-2015-7501 Apache Commons Collections Java 反序列化
CVE-2017-12629 Apache Solr Java 命令注入
CVE-2022-1471 SnakeYAML Java 反序列化
CVE-2022-42889 Apache Commons Text Java 代码执行
GHSA-h8cj-hpmg-636v Appsmith Java SQL 注入
CVE-2013-0156 Ruby on Rails Ruby 反序列化
CVE-2020-8130 Rake Ruby 命令注入
CVE-2021-21288 CarrierWave Ruby SSRF
CVE-2023-38337 rswag-api Ruby 路径穿越
CVE-2017-9841 PHPUnit PHP 代码执行(eval
CVE-2018-15133 Laravel PHP 反序列化
CVE-2018-20997 tar-rs Rust 路径穿越
CVE-2022-36113 cargo Rust 路径穿越
CVE-2024-24576 Rust stdlib Rust 命令注入
CVE-2023-42456 sudo-rs Rust 路径穿越
CVE-2024-32884 gitoxide Rust 命令注入
CVE-2025-53549 matrix-rust-sdk Rust SQL 注入
CVE-2016-3714 ImageMagick (ImageTragick) C 命令注入
CVE-2019-18634 sudo (pwfeedback) C 内存安全
CVE-2019-13132 ZeroMQ libzmq C++ 内存安全
CVE-2022-1941 Protocol Buffers C++ 内存安全
CVE-2025-69662 geopandas Python SQL 注入
CVE-2026-33626 LMDeploy Python SSRF

用例文件位于 tests/benchmark/cve_corpus/,并附上游归属头注释。


工作原理

对文件系统进行两遍扫描,可选用 SQLite 索引跳过未变更文件:

  1. Pass 1:用 tree-sitter 解析每个文件,构建过程内 CFGpetgraph下降到剪枝后的 SSA在支配边界上做 Cytron phi 插入并导出每函数摘要source/sanitizer/sink 能力位、污点变换、指向集、被调集合)。
  2. 摘要合并:将每文件摘要并集合并为 GlobalSummaries 映射。
  3. Pass 2:在跨文件上下文与有限上下文敏感(文件内被调用 k=1 内联SCC 不动点上限 64 次迭代,超过内联体大小阈值的被调用走摘要回退)下重新分析每个文件。正向数据流工作表通过 SSA 格传播污点,保证收敛。调用图 SCC 迭代到不动点(在上限内),使相互递归函数能拿到准确摘要。
  4. 排序、去重、动态验证、输出:按 严重度 × 证据强度 × 源类可利用性 打分。默认构建会对中高置信度发现做动态验证然后输出到控制台、JSON、SARIF 和浏览器 UI。

检测器家族:污点(跨文件 source→sink含 SQLi、XSS、命令/代码执行、反序列化、SSRF、路径穿越、格式串、加密、LDAP 注入、XPath 注入、HTTP 头/响应拆分、开放重定向、服务端模板注入、XXE、原型污染、数据外泄、以及 auth 折入的能力位类规则、CFG 结构鉴权缺失、未守卫汇、资源泄漏、状态模型use-after-close、double-close、must-leak、unauthed-access、AST 模式tree-sitter 结构匹配)。完整检测器文档:Detectors


动态验证

静态分析说明 source 到 sink 可达。动态验证会尝试证明这条路径在真实代码里会触发。默认构建开启该功能,nyx scan 会为中高置信度发现生成 harness在沙箱中用 curated payload 运行,并把结果写入 evidence.dynamic_verdict

nyx scan --verify          # 默认行为的显式写法
nyx scan --no-verify       # 只跑静态分析,适合本地快速循环

Confirmed 只有在攻击 payload 触发 sink 且对应的良性 control 保持干净时才会出现。NotConfirmed 表示 harness 跑完但没有触发,不等于发现已关闭。完整能力矩阵、后端与限制见 Dynamic verification


配置

配置由 nyx.conf(默认值)与 nyx.local你的覆写合并而成从平台配置目录读取Linux 为 ~/.config/nyx/macOS 为 ~/Library/Application Support/nyx/Windows 为 %APPDATA%\elicpeter\nyx\config\)。

[scanner]
mode         = "full"        # full | ast | cfg | taint
min_severity = "Medium"

[server]
host = "127.0.0.1"
port = 9700
open_browser = true

# 项目专属净化器
[[analysis.languages.javascript.rules]]
matchers = ["escapeHtml"]
kind     = "sanitizer"
cap      = "html_escape"

或交互式添加规则:nyx config add-rule --lang javascript --matcher escapeHtml --kind sanitizer --cap html_escape。能力位capsenv_varhtml_escapeshell_escapeurl_encodejson_parsefile_iofmt_stringsql_querydeserializessrfdata_exfilcode_execcryptounauthorized_idldap_injectionxpath_injectionheader_injectionopen_redirectsstixxeprototype_pollutionall。完整 schemaConfiguration。运行 nyx rules list 可在终端浏览注册表。


状态

正在积极开发中。API、检测器行为、配置项可能在版本间发生变化。合成语料上的规则级 F1 是 CI 回归下限;分语言详情见 tests/benchmark/RESULTS.md

污点分析是过程间的。持久化的每函数 SSA 摘要带有按返回路径的变换与参数粒度的指向集,调用图 SCC包括跨文件 SCC迭代到联合不动点。默认 balanced 画像还会对文件内被调用做 k=1 上下文敏感内联。Symex含跨文件与过程间帧以及按需后向遍历是可选项。可分别用 --symex--backwards-analysis 单独开启,或通过 --engine-profile deep 一并开启。

局限:

  • 过程间精度是有界而非无限的。上下文敏感内联为 k=1 且有被调用体大小上限SCC 不动点有迭代上限。引擎触达上限时回退到摘要,并在发现上记录 engine_note
  • 不跨语言追踪调用FFI、子进程、WASM。每种语言独立分析。
  • 几项语言特性未建模:宏、大多数动态分派、别名导入、反射。
  • C/C++ 处于预览梯度。当前已跟踪 STL 容器流、builder 链、内联类成员函数;深度指针别名与函数指针未跟踪。干净报告不应被理解为干净审计。在作为硬性 CI 门禁之前,请与基于 clang 的工具搭配使用。
  • 结果可能含误报或漏报;预期需要人工复核。

文档

完整文档站点:nyxscan.dev/docs


参与贡献

欢迎贡献。

Nyx 是开源项目,并将永远保有完全开源的核心。为了支持长期开发并使项目可持续,贡献者在首次合入前可能会被要求签署 Contributor License Agreement。

提交前请运行 sh scripts/check.sh。完整指南(包括如何添加规则与支持新语言)见 CONTRIBUTING.md。崩溃、panic 或可疑结果请提 issue附最小复现片段与 Nyx 版本号。


AI 披露

  • 引擎代码taint、SSA、CFG、调用图、抽象解释、符号执行以人工编写为主。AI 仅用于有选择的重构与样板代码,所有合入均经人工审阅。
  • 文档与本 README 的大部分内容:由 AI 基于代码生成并经人工编辑。文档与代码漂移请作为 bug 上报。
  • 测试用例与 expected.yaml 文件AI 协助起草,落库前经人工审核。
  • 前端 UIReact 应用):在 AI 协助下构建,经人工审阅。

与任何静态分析器一样,在把 Nyx 用作 CI 门禁前,请基于你自己的语料验证发现。


许可证

GNU General Public License v3.0 或更高版本GPL-3.0-or-later。可选的 smt 特性会捆绑 Z3MIT 许可);分发以 --features smt 构建的二进制时,应在归属信息中包含 Z3 的许可证。完整文本见 LICENSE;第三方依赖见 THIRDPARTY-LICENSES.html