2026-05-11 12:42:39 -04:00
< div align = "center" >
2026-06-05 10:16:30 -05:00
< img src = "assets/nyx-readme-header.png" alt = "NYX" width = "640" / >
2026-05-11 12:42:39 -04:00
2026-06-05 10:16:30 -05:00
**本地优先的安全扫描器,带沙箱动态验证和浏览器 UI。在本地扫描代码仓库并在浏览器中分诊处理, 无需云端、无需账号。**
2026-05-11 12:42:39 -04:00
[](https://crates.io/crates/nyx-scanner)
[](https://www.gnu.org/licenses/gpl-3.0)
[](https://www.rust-lang.org)
[](https://github.com/elicpeter/nyx/actions)
2026-06-05 10:16:30 -05:00
[](https://nyxscan.dev/docs/)
2026-05-11 12:42:39 -04:00
[English ](./README.md ) · 简体中文
< / div >
< p align = "center" > < img src = "assets/screenshots/demo.gif" alt = "Nyx UI 演示:从空欢迎页开始扫描,查看含健康分的总览页,钻入一条 HIGH 级发现的流可视化,再到分诊流程" width = "900" / > < / p >
---
## 本地扫描,本地浏览
2026-06-05 10:16:30 -05:00
Nyx 在你的代码仓库上运行跨语言污点分析,然后对中高置信度发现运行小型沙箱 harness, 验证真实代码里 source 到 sink 的流是否会触发。结果通过绑定到 `127.0.0.1` 的 React UI 提供给你。你会看到严重等级、静态证据、动态验证结果,以及分步**流可视化**,从源 → 净化器 → 汇逐步呈现数据流。分诊决策持久化在 `.nyx/triage.json` 中,与代码一同提交,团队共享同一份分诊状态。
2026-05-11 12:42:39 -04:00
```bash
cargo install nyx-scanner
nyx scan # 运行分析器,把发现缓存到 .nyx/
nyx serve # 在浏览器中打开 http://localhost:9700
```
2026-06-05 10:16:30 -05:00
一切都留在你本地:仅回环绑定、强制 host 头校验、所有变更操作均带 CSRF、无远程遥测、无登录。
2026-05-11 12:42:39 -04:00
< p align = "center" > < img src = "assets/screenshots/overview.png" alt = "一个小型 JS 应用的总览仪表盘:健康分 C 78, 五项分量分解( 严重度压力、置信度质量、趋势、分诊覆盖、回归抗性) , 3 条发现, OWASP A03 与 A02 类别,置信度分布与问题类别条形图,受影响最多的文件" width = "900" / > < / p >
---
## UI 中包含什么
| 页面 | 显示内容 |
|---|---|
| **总览** | 仪表盘:按严重等级分类的发现计数、热点文件、引擎画像摘要 |
| **发现** | 可浏览列表,含严重度徽章、分诊状态、规则筛选、语言筛选 |
2026-06-05 10:16:30 -05:00
| **发现详情** | 流路径可视化,带编号步骤(源 → 净化器 → 汇)、动态验证结果、代码片段、证据、跨文件标记、分诊下拉框 |
2026-05-11 12:42:39 -04:00
| **分诊** | 批量更新状态( open、investigating、fixed、false_positive、accepted_risk、suppressed) , 审计日志, JSON 导入/导出 |
| **资源管理器** | 文件树,含每个文件的符号列表与发现叠加层 |
| **扫描** | 历史记录、指标,对比两次扫描查看差异 |
| **规则** | 各语言的内置与自定义规则;可在 UI 中添加规则 |
| **配置** | 实时配置编辑器;无需重启即可重载 |
2026-06-05 10:16:30 -05:00
`nyx serve` 参数:`--port <N>` (默认 `9700` )、`--host <addr>` (仅回环:`127.0.0.1` 、`localhost` 、`::1` )、`--no-browser` 。持久化设置见 `nyx.conf` 的 `[server]` 段,分页面 UI 介绍与安全模型详见 [Browser UI 指南 ](https://nyxscan.dev/docs/serve.html )。
2026-05-11 12:42:39 -04:00
---
## 用于 CI 的 CLI
同一个引擎可以无头运行用于 CI 流水线。SARIF 输出可直接上传到 GitHub Code Scanning。
< p align = "center" > < img src = "assets/screenshots/cli-scan.gif" alt = "nyx scan 终端输出: JS 与 Python 文件中的 HIGH 级污点发现及 source → sink 箭头" width = "820" / > < / p >
```bash
# 在 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
```
2026-06-05 10:16:30 -05:00
正向跨文件污点在所有画像下都会运行。Symex 与按需后向遍历是可选项,可通过 `--engine-profile deep` 一次性开启,或单独开启(`--symex` 、`--backwards-analysis` )。完整开关矩阵见 [CLI 参考 ](https://nyxscan.dev/docs/cli.html#engine-depth-profile )。
2026-05-11 12:42:39 -04:00
### GitHub Action
```yaml
2026-06-05 10:16:30 -05:00
- uses: elicpeter/nyx@v0 .8.0
2026-05-11 12:42:39 -04:00
with:
format: sarif
fail-on: MEDIUM
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: nyx-results.sarif
```
输入:`path` 、`version` 、`format` ( `sarif` |`json` |`console` )、`fail-on` 、`args` 、`token` 。输出:`finding-count` 、`sarif-file` 、`exit-code` 、`nyx-version` 。支持 Linux 与 macOS runner( x86_64、ARM64) 。
---
## 安装
**Cargo( 推荐) : **
```bash
cargo install nyx-scanner
```
**预编译二进制:** 从 [Releases ](https://github.com/elicpeter/nyx/releases ) 下载对应平台的归档包,对照 `SHA256SUMS` (以及随附的 `SHA256SUMS.asc` GPG 签名,如有提供)校验,解压并把 `nyx` 放到 `PATH` 中。
```bash
# 可选:校验校验文件的 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/
```
**从源码编译:**
```bash
git clone https://github.com/elicpeter/nyx.git
cd nyx & & cargo build --release
```
需要 stable Rust 1.88+。前端会在编译期被打包嵌入二进制中,因此 `nyx serve` 没有单独的安装步骤。
---
## 语言支持
2026-06-05 10:16:30 -05:00
全部 10 种语言都通过 tree-sitter 解析并跑完整流水线,但规则深度与引擎覆盖并不均衡。在 [`tests/benchmark/ground_truth.json` ](tests/benchmark/ground_truth.json ) 的合成语料上,所有十种语言在最近一次基线测量中 F1 均为 100%(见 [`tests/benchmark/RESULTS.md` ](tests/benchmark/RESULTS.md )),因此 F1 已无法单独区分梯度。分级反映规则深度、门控汇覆盖、以及合成语料未充分覆盖的结构性惯用法:
2026-05-11 12:42:39 -04:00
| 梯度 | 语言 | F1 | 适合用作 CI 门禁吗? |
|---|---|---|---|
| **稳定** | Python、JavaScript、TypeScript | 100% | 适合 |
| **Beta** | Java、PHP、Ruby、Rust、Go | 100% | 适合,需轻度 FP 分诊 |
| **预览** | C、C++ | 合成语料 100% | 不适合。已跟踪 STL 容器流、builder 链、内联类成员函数;尚未覆盖深度指针别名与函数指针。建议与 clang-tidy 或 Clang Static Analyzer 搭配使用 |
2026-06-05 10:16:30 -05:00
所有真实 CVE 用例均触发,语料在记录基线下无未关闭的 FP( P=R=F1=1.000)。各维度详情与已知盲区见 [语言成熟度页面 ](https://nyxscan.dev/docs/language-maturity.html )。
2026-05-11 12:42:39 -04:00
### 通过真实 CVE 验证
语料中还包含一小批从公开公告中提取的「漏洞 / 已修复」配对,因此基准下限不仅由合成的同形测例守护,还由对真实 bug 的回归保护守护。每个配对 Nyx 都在漏洞文件上触发、在已修复文件上零发现。
| CVE | 项目 | 语言 | 类别 |
|---|---|---|---|
| [CVE-2023-48022 ](https://nvd.nist.gov/vuln/detail/CVE-2023-48022 ) | Ray | Python | 命令注入 |
| [CVE-2017-18342 ](https://nvd.nist.gov/vuln/detail/CVE-2017-18342 ) | PyYAML | Python | 反序列化 |
| [CVE-2019-14939 ](https://nvd.nist.gov/vuln/detail/CVE-2019-14939 ) | mongo-express | JavaScript | 代码执行(`eval` ) |
| [CVE-2023-22621 ](https://nvd.nist.gov/vuln/detail/CVE-2023-22621 ) | Strapi | JavaScript | 代码执行( SSTI) |
| [CVE-2025-64430 ](https://nvd.nist.gov/vuln/detail/CVE-2025-64430 ) | Parse Server | JavaScript | SSRF |
| [CVE-2023-26159 ](https://nvd.nist.gov/vuln/detail/CVE-2023-26159 ) | follow-redirects | TypeScript | SSRF |
| [GHSA-4x48-cgf9-q33f ](https://github.com/advisories/GHSA-4x48-cgf9-q33f ) | Novu | TypeScript | SSRF |
| [CVE-2026-25544 ](https://nvd.nist.gov/vuln/detail/CVE-2026-25544 ) | Payload CMS | TypeScript | SQL 注入 |
| [CVE-2022-30323 ](https://nvd.nist.gov/vuln/detail/CVE-2022-30323 ) | hashicorp/go-getter | Go | 命令注入 |
| [CVE-2024-31450 ](https://nvd.nist.gov/vuln/detail/CVE-2024-31450 ) | owncast | Go | 路径穿越 |
| [CVE-2023-3188 ](https://nvd.nist.gov/vuln/detail/CVE-2023-3188 ) | owncast | Go | SSRF |
| [CVE-2026-41422 ](https://github.com/daptin/daptin/security/advisories/GHSA-rw2c-8rfq-gwfv ) | daptin | Go | SQL 注入 |
| [CVE-2015-7501 ](https://nvd.nist.gov/vuln/detail/CVE-2015-7501 ) | Apache Commons Collections | Java | 反序列化 |
| [CVE-2017-12629 ](https://nvd.nist.gov/vuln/detail/CVE-2017-12629 ) | Apache Solr | Java | 命令注入 |
| [CVE-2022-1471 ](https://nvd.nist.gov/vuln/detail/CVE-2022-1471 ) | SnakeYAML | Java | 反序列化 |
| [CVE-2022-42889 ](https://nvd.nist.gov/vuln/detail/CVE-2022-42889 ) | Apache Commons Text | Java | 代码执行 |
| [GHSA-h8cj-hpmg-636v ](https://github.com/advisories/GHSA-h8cj-hpmg-636v ) | Appsmith | Java | SQL 注入 |
| [CVE-2013-0156 ](https://nvd.nist.gov/vuln/detail/CVE-2013-0156 ) | Ruby on Rails | Ruby | 反序列化 |
| [CVE-2020-8130 ](https://nvd.nist.gov/vuln/detail/CVE-2020-8130 ) | Rake | Ruby | 命令注入 |
| [CVE-2021-21288 ](https://nvd.nist.gov/vuln/detail/CVE-2021-21288 ) | CarrierWave | Ruby | SSRF |
| [CVE-2023-38337 ](https://nvd.nist.gov/vuln/detail/CVE-2023-38337 ) | rswag-api | Ruby | 路径穿越 |
| [CVE-2017-9841 ](https://nvd.nist.gov/vuln/detail/CVE-2017-9841 ) | PHPUnit | PHP | 代码执行(`eval` ) |
| [CVE-2018-15133 ](https://nvd.nist.gov/vuln/detail/CVE-2018-15133 ) | Laravel | PHP | 反序列化 |
| [CVE-2018-20997 ](https://nvd.nist.gov/vuln/detail/CVE-2018-20997 ) | tar-rs | Rust | 路径穿越 |
| [CVE-2022-36113 ](https://nvd.nist.gov/vuln/detail/CVE-2022-36113 ) | cargo | Rust | 路径穿越 |
| [CVE-2024-24576 ](https://nvd.nist.gov/vuln/detail/CVE-2024-24576 ) | Rust stdlib | Rust | 命令注入 |
| [CVE-2023-42456 ](https://rustsec.org/advisories/RUSTSEC-2023-0069.html ) | sudo-rs | Rust | 路径穿越 |
| [CVE-2024-32884 ](https://rustsec.org/advisories/RUSTSEC-2024-0335.html ) | gitoxide | Rust | 命令注入 |
| [CVE-2025-53549 ](https://rustsec.org/advisories/RUSTSEC-2025-0043.html ) | matrix-rust-sdk | Rust | SQL 注入 |
| [CVE-2016-3714 ](https://nvd.nist.gov/vuln/detail/CVE-2016-3714 ) | ImageMagick (ImageTragick) | C | 命令注入 |
| [CVE-2019-18634 ](https://nvd.nist.gov/vuln/detail/CVE-2019-18634 ) | sudo (pwfeedback) | C | 内存安全 |
| [CVE-2019-13132 ](https://nvd.nist.gov/vuln/detail/CVE-2019-13132 ) | ZeroMQ libzmq | C++ | 内存安全 |
| [CVE-2022-1941 ](https://nvd.nist.gov/vuln/detail/CVE-2022-1941 ) | Protocol Buffers | C++ | 内存安全 |
| [CVE-2025-69662 ](https://nvd.nist.gov/vuln/detail/CVE-2025-69662 ) | geopandas | Python | SQL 注入 |
| [CVE-2026-33626 ](https://nvd.nist.gov/vuln/detail/CVE-2026-33626 ) | LMDeploy | Python | SSRF |
用例文件位于 [`tests/benchmark/cve_corpus/` ](tests/benchmark/cve_corpus/ ),并附上游归属头注释。
---
## 工作原理
对文件系统进行两遍扫描,可选用 SQLite 索引跳过未变更文件:
1. **Pass 1** :用 tree-sitter 解析每个文件,构建过程内 CFG( petgraph) , 下降到剪枝后的 SSA( 在支配边界上做 Cytron phi 插入) , 并导出每函数摘要( source/sanitizer/sink 能力位、污点变换、指向集、被调集合)。
2. **摘要合并** :将每文件摘要并集合并为 `GlobalSummaries` 映射。
3. **Pass 2** :在跨文件上下文与有限上下文敏感(文件内被调用 k=1 内联, SCC 不动点上限 64 次迭代,超过内联体大小阈值的被调用走摘要回退)下重新分析每个文件。正向数据流工作表通过 SSA 格传播污点,保证收敛。调用图 SCC 迭代到不动点(在上限内),使相互递归函数能拿到准确摘要。
2026-06-05 10:16:30 -05:00
4. **排序、去重、动态验证、输出** :按 严重度 × 证据强度 × 源类可利用性 打分。默认构建会对中高置信度发现做动态验证, 然后输出到控制台、JSON、SARIF 和浏览器 UI。
2026-05-11 12:42:39 -04:00
2026-06-05 10:16:30 -05:00
检测器家族:污点(跨文件 source→sink, 含 SQLi、XSS、命令/代码执行、反序列化、SSRF、路径穿越、格式串、加密、LDAP 注入、XPath 注入、HTTP 头/响应拆分、开放重定向、服务端模板注入、XXE、原型污染、数据外泄、以及 auth 折入的能力位类规则) 、CFG 结构( 鉴权缺失、未守卫汇、资源泄漏) 、状态模型( use-after-close、double-close、must-leak、unauthed-access) 、AST 模式( tree-sitter 结构匹配)。完整检测器文档:[Detectors ](https://nyxscan.dev/docs/detectors.html )。
---
## 动态验证
静态分析说明 source 到 sink 可达。动态验证会尝试证明这条路径在真实代码里会触发。默认构建开启该功能,`nyx scan` 会为中高置信度发现生成 harness, 在沙箱中用 curated payload 运行,并把结果写入 `evidence.dynamic_verdict` 。
```bash
nyx scan --verify # 默认行为的显式写法
nyx scan --no-verify # 只跑静态分析,适合本地快速循环
```
`Confirmed` 只有在攻击 payload 触发 sink 且对应的良性 control 保持干净时才会出现。`NotConfirmed` 表示 harness 跑完但没有触发,不等于发现已关闭。完整能力矩阵、后端与限制见 [Dynamic verification ](https://nyxscan.dev/docs/dynamic.html )。
2026-05-11 12:42:39 -04:00
---
## 配置
配置由 `nyx.conf` (默认值)与 `nyx.local` ( 你的覆写) 合并而成, 从平台配置目录读取( Linux 为 `~/.config/nyx/` , macOS 为 `~/Library/Application Support/nyx/` , Windows 为 `%APPDATA%\elicpeter\nyx\config\` )。
```toml
[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"
```
2026-06-05 10:16:30 -05:00
或交互式添加规则:`nyx config add-rule --lang javascript --matcher escapeHtml --kind sanitizer --cap html_escape` 。能力位( caps) : `env_var` 、`html_escape` 、`shell_escape` 、`url_encode` 、`json_parse` 、`file_io` 、`fmt_string` 、`sql_query` 、`deserialize` 、`ssrf` 、`data_exfil` 、`code_exec` 、`crypto` 、`unauthorized_id` 、`ldap_injection` 、`xpath_injection` 、`header_injection` 、`open_redirect` 、`ssti` 、`xxe` 、`prototype_pollution` 、`all` 。完整 schema: [Configuration ](https://nyxscan.dev/docs/configuration.html )。运行 `nyx rules list` 可在终端浏览注册表。
2026-05-11 12:42:39 -04:00
---
## 状态
2026-06-05 10:16:30 -05:00
正在积极开发中。API、检测器行为、配置项可能在版本间发生变化。合成语料上的规则级 F1 是 CI 回归下限;分语言详情见 [`tests/benchmark/RESULTS.md` ](tests/benchmark/RESULTS.md )。
2026-05-11 12:42:39 -04:00
污点分析是过程间的。持久化的每函数 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 的工具搭配使用。
- 结果可能含误报或漏报;预期需要人工复核。
---
## 文档
2026-06-05 10:16:30 -05:00
完整文档站点:**[nyxscan.dev/docs ](https://nyxscan.dev/docs/ )**。
2026-05-11 12:42:39 -04:00
2026-06-05 10:16:30 -05:00
- [Quick Start ](https://nyxscan.dev/docs/quickstart.html ) · [CLI Reference ](https://nyxscan.dev/docs/cli.html ) · [Installation ](https://nyxscan.dev/docs/installation.html )
- [`nyx serve` ](https://nyxscan.dev/docs/serve.html ) · [Output Formats ](https://nyxscan.dev/docs/output.html ) · [Configuration ](https://nyxscan.dev/docs/configuration.html )
- [How it works ](https://nyxscan.dev/docs/how-it-works.html ) · [Detectors ](https://nyxscan.dev/docs/detectors.html )( [Taint ](https://nyxscan.dev/docs/detectors/taint.html )、[CFG ](https://nyxscan.dev/docs/detectors/cfg.html )、[State ](https://nyxscan.dev/docs/detectors/state.html )、[AST Patterns ](https://nyxscan.dev/docs/detectors/patterns.html ))
- [Rule Reference ](https://nyxscan.dev/docs/rules.html ) · [Language Maturity ](https://nyxscan.dev/docs/language-maturity.html ) · [Advanced Analysis ](https://nyxscan.dev/docs/advanced-analysis.html ) · [Auth Analysis ](https://nyxscan.dev/docs/auth.html )
2026-05-11 12:42:39 -04:00
---
## 参与贡献
欢迎贡献。
Nyx 是开源项目,并将永远保有完全开源的核心。为了支持长期开发并使项目可持续,贡献者在首次合入前可能会被要求签署 Contributor License Agreement。
提交前请运行 `sh scripts/check.sh` 。完整指南(包括如何添加规则与支持新语言)见 [`CONTRIBUTING.md` ](CONTRIBUTING.md )。崩溃、panic 或可疑结果请提 issue, 附最小复现片段与 Nyx 版本号。
---
## AI 披露
- **引擎代码**( taint、SSA、CFG、调用图、抽象解释、符号执行) : 以人工编写为主。AI 仅用于有选择的重构与样板代码,所有合入均经人工审阅。
- **文档与本 README 的大部分内容**:由 AI 基于代码生成并经人工编辑。文档与代码漂移请作为 bug 上报。
- **测试用例与 `expected.yaml` 文件**: AI 协助起草,落库前经人工审核。
- **前端 UI**( React 应用):在 AI 协助下构建,经人工审阅。
与任何静态分析器一样,在把 Nyx 用作 CI 门禁前,请基于你自己的语料验证发现。
---
## 许可证
GNU General Public License v3.0 或更高版本( GPL-3.0-or-later) 。可选的 `smt` 特性会捆绑 Z3( MIT 许可);分发以 `--features smt` 构建的二进制时,应在归属信息中包含 Z3 的许可证。完整文本见 [LICENSE ](./LICENSE );第三方依赖见 [THIRDPARTY-LICENSES.html ](./THIRDPARTY-LICENSES.html )。