2025-06-25 03:37:39 +02:00
< div align = "center" >
2025-06-25 17:23:31 +02:00
< img src = "assets/logo.png" alt = "nyx logo" width = "300" / >
2025-06-25 03:37:39 +02:00
**Fast, cross-language cli vulnerability scanner.**
2025-06-25 03:56:07 +02:00
[](https://crates.io/crates/nyx-scanner)
2025-06-25 17:23:31 +02:00
[](https://www.gnu.org/licenses/gpl-3.0)
2025-06-28 17:36:14 +02:00
[](https://www.rust-lang.org)
2025-06-25 03:37:39 +02:00
[](https://github.com/ecpeter23/nyx/actions)
< / div >
---
## What is Nyx?
2026-02-24 23:44:07 -05:00
**Nyx** is a lightweight, lightning-fast Rust-native command-line tool that detects security vulnerabilities across 10 programming languages. It combines [`tree-sitter` ](https://tree-sitter.github.io/ ) parsing, intra-procedural control-flow graphs, and cross-file taint analysis with an optional SQLite-backed index to deliver deep, repeatable scans on projects of any size.
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
---
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
## Key Capabilities
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
| Capability | Description |
|---|---|
| Multi-language support | Rust, C, C++, Java, Go, PHP, Python, Ruby, TypeScript, JavaScript |
| AST-level pattern matching | Language-specific queries written against precise parse trees |
| Control-flow graph analysis | Auth gaps, unguarded sinks, unreachable security code, resource leaks, error fallthrough |
| Cross-file taint tracking | BFS taint propagation from sources through sanitizers to sinks with function summaries |
| Cross-language interop | Taint flows across language boundaries via explicit interop edges |
| Two-pass architecture | Pass 1 extracts function summaries; Pass 2 runs taint with full cross-file context |
| Incremental indexing | SQLite database stores file hashes, summaries, and findings to skip unchanged files |
| Parallel execution | File walking and analysis run concurrently via Rayon; scales with available CPU cores |
2026-02-25 04:02:11 -05:00
| Configurable analysis rules | Define custom sources, sanitizers, sinks, terminators, and event handlers per language via TOML config or CLI |
2026-02-24 23:44:07 -05:00
| Configurable scan parameters | Exclude directories, set maximum file size, tune worker threads, limit output, and more |
2026-02-25 04:02:11 -05:00
| Multiple output formats | Console (default), JSON, and SARIF 2.1.0 for CI integration |
| Progress reporting | Real-time progress bars for file discovery and analysis passes |
2025-06-25 00:24:05 +02:00
---
2025-06-17 11:20:19 +02:00
2025-06-25 01:42:10 +02:00
## Why choose Nyx?
2026-02-24 23:44:07 -05:00
| Advantage | What it means for you |
|---|---|
| **Pure-Rust, single binary** | No JVM, Python, or server to install; drop the `nyx` executable into your `$PATH` and go. |
| **Massively parallel** | Uses Rayon and a thread-pool walker; scales to all CPU cores. Scanning the entire **rust-lang/rust** codebase (~53,000 files) on an M2 MacBook Pro takes ** ~1 s**. |
| **Deep analysis** | Real CFG construction and taint propagation, not just regex matching. Cross-file function summaries, capability-based sanitizer tracking, and scored findings. |
| **Index-aware** | An optional SQLite index stores file hashes and findings; subsequent scans touch *only* changed files, slashing CI times. |
| **Offline & privacy-friendly** | Requires no login, cloud account, or telemetry. Perfect for air-gapped environments and strict compliance policies. |
| **Tree-sitter precision** | Parses real language grammars, not regexes, giving far fewer false positives than line-based scanners. |
| **Extensible** | Add new patterns with concise `tree-sitter` queries; no SaaS lock-in. |
2025-06-25 01:42:10 +02:00
---
2025-06-17 11:20:19 +02:00
## Installation
2025-06-28 17:36:14 +02:00
### Install crate
```bash
$ cargo install nyx-scanner
```
### Install Github release
1. Navigate to the [Releases ](https://github.com/ecpeter23/nyx/releases ) page of the repository.
2. Download the appropriate binary for your system:
```nyx-x86_64-unknown-linux-gnu.zip` `` for Linux
```nyx-x86_64-pc-windows-msvc.zip` `` for Windows
```nyx-x86_64-apple-darwin.zip` `` or ` ``nyx-aarch64-apple-darwin.zip` `` for macOS (Intel or Apple Silicon)
3. Unzip the file and move the executable to a directory in your system PATH:
```bash
# Example for Unix systems
unzip nyx-x86_64-unknown-linux-gnu.zip
chmod +x nyx
sudo mv nyx /usr/local/bin/
```
```bash
# Example for Windows in PowerShell
Expand-Archive -Path nyx-x86_64-pc-windows-msvc.zip -DestinationPath .
Move-Item -Path .\nyx.exe -Destination "C:\Program Files\Nyx\" # Add to PATH manually if needed
```
2026-02-24 23:44:07 -05:00
2025-06-28 17:36:14 +02:00
4. Verify the installation:
```bash
nyx --version
```
2025-06-25 00:24:05 +02:00
### Build from source
2025-06-17 11:20:19 +02:00
```bash
2025-06-28 17:36:14 +02:00
$ git clone https://github.com/ecpeter23/nyx.git
2025-06-25 00:24:05 +02:00
$ cd nyx
$ cargo build --release
# optional – copy the binary into PATH
$ cargo install --path .
2025-06-17 11:20:19 +02:00
```
2025-06-28 17:36:14 +02:00
Nyx targets **stable Rust 1.85 or later** .
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
---
## Quick Start
2025-06-17 11:20:19 +02:00
```bash
2025-06-25 00:24:05 +02:00
# Scan the current directory (creates/uses an index automatically)
$ nyx scan
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
# Scan a specific path and emit JSON
$ nyx scan ./server --format json
2025-06-17 11:20:19 +02:00
2026-02-25 04:02:11 -05:00
# Emit SARIF 2.1.0 for CI integration (GitHub Code Scanning, etc.)
$ nyx scan --format sarif > results.sarif
2026-02-24 23:44:07 -05:00
# Perform an ad-hoc scan without touching the index
2025-06-25 00:24:05 +02:00
$ nyx scan --no-index
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
# Restrict results to high-severity findings
2025-06-25 00:24:05 +02:00
$ nyx scan --high-only
2026-02-24 23:44:07 -05:00
# AST pattern matching only (fastest, no CFG/taint)
$ nyx scan --ast-only
# CFG + taint analysis only (skip AST pattern rules)
$ nyx scan --cfg-only
2026-02-25 04:02:11 -05:00
# Include test/vendor/benchmark paths at original severity
# (by default these are downgraded one tier)
$ nyx scan --include-nonprod
2025-06-17 11:20:19 +02:00
```
2025-06-25 00:24:05 +02:00
### Index Management
2025-06-17 11:20:19 +02:00
```bash
2025-06-25 00:24:05 +02:00
# Create or rebuild an index
$ nyx index build [PATH] [--force]
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
# Display index metadata (size, modified date, etc.)
$ nyx index status [PATH]
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
# List all indexed projects (add -v for detailed view)
$ nyx list [-v]
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
# Remove a single project or purge all indexes
$ nyx clean < PROJECT_NAME >
$ nyx clean --all
```
2025-06-17 11:20:19 +02:00
2026-02-25 04:02:11 -05:00
### Configuration Management
```bash
# Print the effective merged configuration
$ nyx config show
# Print the config directory path
$ nyx config path
# Add a custom sanitizer rule (written to nyx.local)
$ nyx config add-rule --lang javascript --matcher escapeHtml --kind sanitizer --cap html_escape
# Add a terminator function
$ nyx config add-terminator --lang javascript --name process.exit
```
2025-06-25 00:24:05 +02:00
---
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
## Analysis Modes
Nyx supports three analysis modes, selectable via the `scanner.mode` config option or CLI flags:
| Mode | CLI flag | What runs |
|---|---|---|
| **Full** (default) | — | AST pattern matching + CFG construction + taint analysis |
| **AST-only** | `--ast-only` | AST pattern matching only; skips CFG and taint entirely |
| **Taint-only** | `--cfg-only` | CFG + taint analysis only; filters out AST pattern findings |
### What the CFG + taint engine detects
| Finding | Rule ID | Description |
|---|---|---|
| Tainted data flow | `taint-*` | Untrusted data (env vars, user input, file reads) flowing to dangerous sinks (shell exec, SQL, file write) without matching sanitization |
| Unguarded sink | `cfg-unguarded-sink` | Sink calls not dominated by a guard or sanitizer on the control-flow path |
| Auth gap | `cfg-auth-gap` | Web handler functions that reach privileged sinks without an auth check |
| Unreachable security code | `cfg-unreachable-*` | Sanitizers, guards, or sinks in dead code branches |
| Error fallthrough | `cfg-error-fallthrough` | Error-handling branches that don't terminate, allowing execution to fall through to dangerous operations |
| Resource leak | `cfg-resource-leak` | Resources acquired but not released on all exit paths (malloc/free, fopen/fclose, Lock/Unlock) |
Findings are scored and ranked by severity, proximity to entry point, path complexity, and taint confirmation.
---
## Supported Languages
All 10 languages have full AST pattern matching and CFG/taint analysis. Resource leak detection is available where language-specific acquire/release pairs are defined.
| Language | AST Patterns | CFG + Taint | Resource Leaks |
|---|---|---|---|
| Rust | Yes | Yes | Yes |
| C | Yes | Yes | Yes |
| C++ | Yes | Yes | Yes |
| Java | Yes | Yes | Yes |
| Go | Yes | Yes | Yes |
2026-02-25 04:02:11 -05:00
| PHP | Yes | Yes | Yes |
| Python | Yes | Yes | Yes |
| Ruby | Yes | Yes | Yes |
| TypeScript | Yes | Yes | Yes |
| JavaScript | Yes | Yes | Yes |
2026-02-24 23:44:07 -05:00
---
2025-06-25 00:24:05 +02:00
## Configuration Overview
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
Nyx merges a default configuration file (`nyx.conf` ) with user overrides (`nyx.local` ). Both live in the platform-specific configuration directory shown below.
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
| Platform | Directory |
|---|---|
| Linux | `~/.config/nyx/` |
| macOS | `~/Library/Application Support/dev.ecpeter23.nyx/` |
| Windows | `%APPDATA%\ecpeter23\nyx\config\` |
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
Minimal example (`nyx.local` ):
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
```toml
[scanner]
2026-02-24 23:44:07 -05:00
mode = "full" # full | ast | taint
2025-06-25 00:24:05 +02:00
min_severity = "Medium"
follow_symlinks = true
excluded_extensions = ["mp3", "mp4"]
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
[output]
default_format = "json"
max_results = 200
2026-02-25 04:02:11 -05:00
quiet = true # suppress status messages
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
[performance]
2026-02-24 23:44:07 -05:00
worker_threads = 8 # 0 = auto-detect
2025-06-25 00:24:05 +02:00
batch_size = 200
channel_multiplier = 2
```
2025-06-17 11:20:19 +02:00
2026-02-25 04:02:11 -05:00
### Custom Analysis Rules
You can define custom sources, sanitizers, sinks, terminators, and event handlers per language. These take priority over built-in rules, letting you teach Nyx about project-specific functions.
```toml
[analysis.languages.javascript]
terminators = ["process.exit"]
event_handlers = ["addEventListener"]
[[analysis.languages.javascript.rules]]
matchers = ["escapeHtml"]
kind = "sanitizer" # "source" | "sanitizer" | "sink"
cap = "html_escape" # "env_var" | "html_escape" | "shell_escape" |
# "url_encode" | "json_parse" | "file_io" | "all"
[[analysis.languages.javascript.rules]]
matchers = ["dangerouslySetHTML"]
kind = "sink"
cap = "html_escape"
```
Rules can also be added interactively via `nyx config add-rule` and `nyx config add-terminator` .
2025-06-25 00:24:05 +02:00
A fully documented `nyx.conf` is generated automatically on first run.
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
---
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
## Architecture in Brief
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
Nyx uses a **two-pass architecture** to enable cross-file analysis without sacrificing parallelism:
1. **File enumeration** -- A parallel walker (Rayon + `ignore` crate) applies gitignore rules, size limits, and user exclusions.
2. **Pass 1 -- Summary extraction** -- Each file is parsed via tree-sitter, an intra-procedural CFG is built (petgraph), and a `FuncSummary` is exported per function capturing source/sanitizer/sink capabilities (bitflags), taint propagation behavior, and callee lists. Summaries are persisted to SQLite.
3. **Summary merge** -- All per-file summaries are merged into a `GlobalSummaries` map with conservative conflict resolution (union caps, OR booleans).
4. **Pass 2 -- Analysis** -- Files are re-parsed and analyzed with the full cross-file context: BFS taint propagation resolves callees against local and global summaries, CFG analysis checks for auth gaps, unguarded sinks, resource leaks, and more.
5. **Reporting** -- Findings are scored, ranked, deduplicated, and emitted to the console or serialized as JSON.
With indexing enabled, Pass 1 skips files whose blake3 content hash is unchanged, and cached findings are served directly for AST-only results.
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
---
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
## Roadmap
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
### Phase 1 -- Deep Static Engine
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
| Feature | Description |
|---|---|
| Interprocedural call graph | Precise symbol resolution via `FuncKey` , language-scoped namespaces, cross-module linking. No name-collision merging -- full call graph with topological analysis. |
| Path-sensitive analysis | Track path predicates and conditional constraints. Detect infeasible paths and validation-only-in-one-branch patterns. Dramatically reduces false positives. |
| Dataflow & state modeling | Resource state machines (init -> use -> close), auth state transitions, privilege level tracking. Semantic analysis beyond pattern matching. |
| Attack surface ranking | Score entry points by distance-to-sink, guard strength, path complexity, and privilege escalation potential. Deterministic attack surface scoring. |
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
### Phase 2 -- Dynamic Capability
| Feature | Description |
|---|---|
| Controlled dynamic execution | Local sandbox: identify entry points, spin up test harnesses, inject payloads, detect runtime crashes and command execution. Deterministic automated exploit validation -- static finds `exec(user_input)` , dynamic confirms it with `; id` . |
| Fuzzing integration | libFuzzer (C/C++), cargo-fuzz (Rust), go-fuzz, HTTP fuzzing harness. Static engine identifies interesting functions, fuzzer targets only those. |
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
### Phase 3 -- Intelligent Reasoning Layer
2025-06-28 17:36:14 +02:00
2026-02-24 23:44:07 -05:00
| Feature | Description |
|---|---|
| Semantic similarity | Embeddings for finding similar vulnerability patterns across codebases. |
| LLM reasoning | AI-assisted detection of non-obvious logic bugs. |
| Exploit refinement | Automated loops to refine and validate exploit chains. |
2025-06-28 17:36:14 +02:00
2026-02-24 23:44:07 -05:00
### Other planned improvements
2025-06-28 17:36:14 +02:00
2026-02-24 23:44:07 -05:00
| Area | Details |
|---|---|
2026-02-25 04:02:11 -05:00
| Output formats | JUnit XML, HTML report generator |
| Language coverage | Expanded taint rules per language |
2026-02-24 23:44:07 -05:00
| Rule updates | Remote rule feed with signature verification |
2026-02-25 04:02:11 -05:00
| UX | Smart file-watch re-scan |
2026-02-24 23:44:07 -05:00
Community feedback shapes priorities -- please [open an issue ](https://github.com/ecpeter23/nyx/issues ) to discuss proposed changes.
2025-06-28 17:36:14 +02:00
---
2025-06-25 00:24:05 +02:00
## Contributing
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
Pull requests are welcome. To contribute:
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
1. Fork the repository and create a feature branch.
2. Adhere to `rustfmt` and ensure `cargo clippy --all -- -D warnings` passes.
3. Add unit and/or integration tests where applicable (`cargo test` should remain green).
2026-02-24 23:44:07 -05:00
4. Submit a concise, well-documented pull request.
Please open an issue for any crash, panic, or suspicious result -- attach the minimal code snippet and mention the Nyx version.
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
See `CONTRIBUTING.md` for full guidelines.
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
---
2025-06-17 11:20:19 +02:00
2025-06-25 00:24:05 +02:00
## License
2025-06-17 11:20:19 +02:00
2026-02-24 23:44:07 -05:00
Nyx is licensed under the **GNU General Public License v3.0 (GPL-3.0)** .
2025-06-25 17:23:31 +02:00
This ensures that all modified versions of the scanner remain free and open-source, protecting the integrity and transparency of security tools.
See [LICENSE ](./LICENSE ) for full details.