mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-06 19:35:13 +02:00
* chore: Exclude CLAUDE.md from Cargo.toml * feat: add callgraph module and integrate into main analysis flow * feat: enhance CLI with new severity filtering and analysis modes * feat: update CHANGELOG with recent enhancements and fixes to severity filtering and output handling * feat: implement state-model dataflow analysis for resource lifecycle and auth state * feat: enhance diagnostic output formatting and add evidence structure * feat: implement attack surface ranking for diagnostics with scoring and sorting * feat: add comprehensive documentation for installation, usage, and rules reference * feat: add multiple language support for command execution and evaluation endpoints * feat: implement inline suppression for findings using `nyx:ignore` comments * feat: add confidence levels to AST patterns and update output structure * feat: implement low-noise prioritization system with category filtering, rollup grouping, and configurable budgets * feat: bump version to 0.4.0 and update changelog with new features and improvements * feat: add dead code allowances to various functions in mod.rs and real_world_tests.rs
3.2 KiB
3.2 KiB
Rust Rules
Nyx detects Rust vulnerabilities through AST patterns (memory safety, code quality) and taint analysis (command injection via env::var → Command::new).
Taint Sources
| Function | Capability | Source Kind |
|---|---|---|
std::env::var, env::var |
all |
EnvironmentConfig |
Taint Sinks
| Function | Required Capability |
|---|---|
Command::new, Command::arg, Command::args |
SHELL_ESCAPE |
Command::status, Command::output |
SHELL_ESCAPE |
fs::read_to_string, fs::write, fs::read, File::open, File::create |
FILE_IO |
Taint Sanitizers
| Function | Strips Capability |
|---|---|
html_escape::encode_safe, sanitize_html |
HTML_ESCAPE |
shell_escape::unix::escape, sanitize_shell |
SHELL_ESCAPE |
Note:
fs::read_to_stringwas moved from taint sources to sinks to support path traversal detection (env::var→fs::read_to_string).
AST Pattern Rules
Memory Safety
| Rule ID | Severity | Tier | Description |
|---|---|---|---|
rs.memory.transmute |
High | A | std::mem::transmute — unchecked type reinterpretation |
rs.memory.copy_nonoverlapping |
High | A | ptr::copy_nonoverlapping — raw pointer memcpy |
rs.memory.get_unchecked |
High | A | get_unchecked / get_unchecked_mut — unchecked indexing |
rs.memory.mem_zeroed |
High | A | std::mem::zeroed — may be UB for non-POD types |
rs.memory.ptr_read |
High | A | ptr::read / ptr::read_volatile — raw pointer dereference |
rs.memory.narrow_cast |
Low | A | as u8/i8/u16/i16 — possible truncation |
rs.memory.mem_forget |
Low | A | std::mem::forget — may leak resources |
Code Quality
| Rule ID | Severity | Tier | Description |
|---|---|---|---|
rs.quality.unsafe_block |
Medium | A | unsafe { } block — manual memory safety obligation |
rs.quality.unsafe_fn |
Medium | A | unsafe fn declaration |
rs.quality.unwrap |
Low | A | .unwrap() — panics on None/Err |
rs.quality.expect |
Low | A | .expect() — panics on None/Err |
rs.quality.panic_macro |
Low | A | panic!() macro invocation |
rs.quality.todo |
Low | A | todo!() / unimplemented!() placeholder |
Examples
rs.memory.transmute — Unchecked type reinterpretation
Vulnerable:
let x: u32 = 42;
let y: f32 = unsafe { std::mem::transmute(x) };
Safe alternative:
let x: u32 = 42;
let y: f32 = f32::from_bits(x);
rs.quality.unsafe_block — Unsafe block
Flagged:
unsafe {
let ptr = &x as *const i32;
println!("{}", *ptr);
}
Safe alternative:
// Use safe abstractions when possible
println!("{}", x);
Taint: env::var → Command::new
Vulnerable:
let cmd = std::env::var("USER_CMD").unwrap();
Command::new("sh").arg("-c").arg(&cmd).output()?;
Safe alternative:
let cmd = std::env::var("USER_CMD").unwrap();
// Validate against allowlist
let allowed = ["ls", "whoami", "date"];
if allowed.contains(&cmd.as_str()) {
Command::new(&cmd).output()?;
}