From b468f31a68c6c65108696fb1b7b3de774c074fd8 Mon Sep 17 00:00:00 2001 From: pitboss Date: Thu, 21 May 2026 07:10:26 -0500 Subject: [PATCH] [pitboss/grind] cleanup session-0012 (20260520T233019Z-6958) --- CHANGELOG.md | 2 +- README.md | 12 +++++----- assets/nyx-readme-header.png | Bin 0 -> 10148 bytes assets/nyx-readme-header.svg | 24 ++++++++++++++++++++ docs/configuration.md | 42 ++++++++++++++++++++++++++++++----- src/dynamic/sandbox/mod.rs | 2 +- src/fmt.rs | 2 +- src/state/lattice.rs | 2 -- 8 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 assets/nyx-readme-header.png create mode 100644 assets/nyx-readme-header.svg diff --git a/CHANGELOG.md b/CHANGELOG.md index ae32ad5f..f0771ccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,7 +70,7 @@ A focused release on three fronts: an attack-surface map and chain composer that ### License -- **Internal license grants documentation** at `LICENSE-GRANTS.md`. Grant 1 covers Nyx Pro derived works (renamed to reflect the Nyctos rebrand). The repo stays GPL-3.0-or-later; the grants document scope of internal product licensing. +- **Internal license grants documentation** at `LICENSE-GRANTS.md`. Grant 1 covers Nyctos derived works. The repo stays GPL-3.0-or-later; the grants document scope of internal product licensing. ## [0.7.0] - 2026-05-11 diff --git a/README.md b/README.md index cbda3276..81c7d5a9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
- nyx + NYX **A local-first security scanner with a browser UI. Scan your repo and triage in your browser, with no cloud and no account.** @@ -234,12 +234,12 @@ Limitations: ## Documentation -Browse the full docs site at **[elicpeter.github.io/nyx](https://elicpeter.github.io/nyx/)**. +Browse the full docs site at **[nyxscan.dev/docs](https://nyxscan.dev/docs/)**. -- [Quick Start](https://elicpeter.github.io/nyx/quickstart.html) · [CLI Reference](https://elicpeter.github.io/nyx/cli.html) · [Installation](https://elicpeter.github.io/nyx/installation.html) -- [`nyx serve`](https://elicpeter.github.io/nyx/serve.html) · [Output Formats](https://elicpeter.github.io/nyx/output.html) · [Configuration](https://elicpeter.github.io/nyx/configuration.html) -- [How it works](https://elicpeter.github.io/nyx/how-it-works.html) · [Detectors](https://elicpeter.github.io/nyx/detectors.html) ([Taint](https://elicpeter.github.io/nyx/detectors/taint.html), [CFG](https://elicpeter.github.io/nyx/detectors/cfg.html), [State](https://elicpeter.github.io/nyx/detectors/state.html), [AST Patterns](https://elicpeter.github.io/nyx/detectors/patterns.html)) -- [Rule Reference](https://elicpeter.github.io/nyx/rules.html) · [Language Maturity](https://elicpeter.github.io/nyx/language-maturity.html) · [Advanced Analysis](https://elicpeter.github.io/nyx/advanced-analysis.html) · [Auth Analysis](https://elicpeter.github.io/nyx/auth.html) +- [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) --- diff --git a/assets/nyx-readme-header.png b/assets/nyx-readme-header.png new file mode 100644 index 0000000000000000000000000000000000000000..a692d7635bf30a6142bb65529709cf1013c2b1dc GIT binary patch literal 10148 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 XrM^;nrj_?T`Kb^U9pxg$ry>6f+k914 literal 0 HcmV?d00001 diff --git a/assets/nyx-readme-header.svg b/assets/nyx-readme-header.svg new file mode 100644 index 00000000..f1b55a3b --- /dev/null +++ b/assets/nyx-readme-header.svg @@ -0,0 +1,24 @@ + + NYX + NYX security scanner. + + + + + + + + + + + + + diff --git a/docs/configuration.md b/docs/configuration.md index eaf610b9..ccc8d8a5 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -65,6 +65,13 @@ excluded_extensions = ["foo", "jpg"] | `scan_hidden_files` | bool | `false` | Scan dot-files | | `include_nonprod` | bool | `false` | Keep original severity for test/vendor paths | | `enable_state_analysis` | bool | `true` | Enable resource lifecycle + auth state analysis. Detects use-after-close, double-close, resource leaks (per-function scope), and unauthenticated access. Requires `mode = "full"` or `mode = "taint"`. | +| `enable_auth_analysis` | bool | `true` | Enable auth-state analysis within the state engine. When false, only resource lifecycle findings (leak, use-after-close, double-close) are produced. | +| `enable_panic_recovery` | bool | `false` | Catch per-file analysis panics as warnings and continue. When false, a panic aborts the scan, preserving the loud-fail behaviour for users debugging engine bugs. | +| `enable_auth_as_taint` | bool | `false` | Fold auth analysis into the SSA/taint engine via `Cap::UNAUTHORIZED_ID`. Off while the standalone path still carries stable detection. | +| `verify` | bool | `true` | Run dynamic verification on each `Confidence >= Medium` finding after the static pass. Requires the binary to be built with `--features dynamic`. CLI overrides: `--verify` / `--no-verify`. | +| `verify_all_confidence` | bool | `false` | Extend dynamic verification to findings below `Confidence::Medium`. Intended for corpus-building, not production scans. CLI: `--verify-all-confidence`. | +| `verify_backend` | string | `"auto"` | Sandbox backend for dynamic verification. `"auto"` picks docker when available else process; `"docker"` requires docker; `"process"` runs in-process (same as `--unsafe-sandbox`). | +| `harden_profile` | string | `"standard"` | Process-backend hardening profile. `"standard"` engages `PR_SET_NO_NEW_PRIVS` + `setrlimit(RLIMIT_AS)` on Linux; `"strict"` adds namespace unshare, chroot to workdir, and a default-deny seccomp filter on Linux, plus `sandbox-exec` wrapping on macOS keyed off the finding's expected cap. | ### `[database]` @@ -119,6 +126,7 @@ Configuration for the local web UI (`nyx serve`). | `auto_reload` | bool | `true` | Auto-reload UI when scan results change | | `persist_runs` | bool | `true` | Persist scan runs for history view | | `max_saved_runs` | int | `50` | Maximum number of saved runs | +| `triage_sync` | bool | `true` | Auto-sync triage decisions to `.nyx/triage.json` in the project root so changes can be committed to git. | ### `[runs]` @@ -173,10 +181,10 @@ Release-grade switches for the optional analysis passes. Each toggle has a matching CLI flag (pair of `--foo` / `--no-foo`) that overrides the config value for a single run. These used to be `NYX_*` environment variables (`NYX_CONSTRAINT`, `NYX_ABSTRACT_INTERP`, `NYX_SYMEX`, `NYX_CROSS_FILE_SYMEX`, -`NYX_SYMEX_INTERPROC`, `NYX_CONTEXT_SENSITIVE`, `NYX_PARSE_TIMEOUT_MS`, -`NYX_SMT`); those env vars are still honored as a last-resort override when -nyx is used as a library (no CLI entry point), but the config/CLI surface is -the stable path. +`NYX_SYMEX_INTERPROC`, `NYX_CONTEXT_SENSITIVE`, `NYX_BACKWARDS`, +`NYX_PARSE_TIMEOUT_MS`, `NYX_SMT`); those env vars are still honored as a +fallback default when nyx is used as a library (no CLI entry point), but the +config/CLI surface is the stable path. | Field | Type | Default | Description | |-------|------|---------|-------------| @@ -185,6 +193,8 @@ the stable path. | `context_sensitive` | bool | `true` | k=1 context-sensitive callee inlining for intra-file calls | | `backwards_analysis` | bool | `false` | Demand-driven backwards taint walk from sinks (adds scan time; default off) | | `parse_timeout_ms` | int | `10000` | Per-file tree-sitter parse timeout; `0` disables the cap | +| `max_origins` | int | `32` | Maximum taint origins retained per lattice value. Excess origins are dropped deterministically (sorted by source location) and an `OriginsTruncated` engine note is recorded. CLI: `--max-origins`. | +| `max_pointsto` | int | `32` | Maximum abstract heap objects retained per intra-procedural points-to set. Excess objects are dropped and a `PointsToTruncated` engine note is recorded. CLI: `--max-pointsto`. | **`[analysis.engine.symex]`** sub-section: @@ -208,11 +218,33 @@ CLI flag map (each pair is `--enable / --no-enable`): | `symex.cross_file` | `--cross-file-symex` / `--no-cross-file-symex` | | `symex.interprocedural` | `--symex-interproc` / `--no-symex-interproc` | | `symex.smt` | `--smt` / `--no-smt` | +| `max_origins` | `--max-origins ` | +| `max_pointsto` | `--max-pointsto ` | **Engine-depth profile shortcut**: instead of flipping individual toggles, pass `--engine-profile {fast,balanced,deep}` to set the whole stack at once. Individual flags override the profile, so `--engine-profile fast --backwards-analysis` runs the fast stack with backwards analysis on. See `docs/cli.md` for the exact toggle matrix. **Explain effective engine**: pass `--explain-engine` to print the resolved engine configuration (profile + config + CLI overrides) and exit without scanning. +### `[chain]` + +Bounded-DFS path search across taint findings. Emits multi-step attack chains when several findings link through shared SSA values or call edges. + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `max_depth` | int | `4` | Maximum per-finding hops in a single chain path. | +| `min_score` | float | `9.5` | Score threshold; chains below this value are dropped. | +| `reverify_top_n` | int | `5` | Only the top-N chains by score are eligible for composite dynamic re-verification. `0` disables composite re-verification. | + +### `[telemetry]` + +Sampling policy for the on-disk event log written by dynamic verification (`~/.cache/nyx/dynamic/events.jsonl`). Confirmed and Inconclusive verdicts are calibration-critical and kept by default; other verdict statuses can be downsampled to bound log growth. Decisions are seeded by `spec_hash` for determinism. See `docs/dynamic.md` for the on-disk schema and `NYX_NO_TELEMETRY=1` opt-out. + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `keep_all_confirmed` | bool | `true` | Always retain `Confirmed` verdicts. | +| `keep_all_inconclusive` | bool | `true` | Always retain `Inconclusive` verdicts. | +| `sample_rate_other` | float | `1.0` | Retention probability for verdicts not covered by the keep-all flags. `1.0` keeps everything, `0.0` drops everything. | + ### `[detectors.data_exfil]` Per-project tuning for the `taint-data-exfiltration` rule. All fields are optional. @@ -354,7 +386,7 @@ nyx config show Config is validated after loading and merging. Validation checks include: -- Server port must be 1–65535 +- Server port must be 1 to 65535 - Server host must not be empty - `max_saved_runs` must be > 0 when `persist_runs` is true - `max_runs` must be > 0 when `persist` is true diff --git a/src/dynamic/sandbox/mod.rs b/src/dynamic/sandbox/mod.rs index c75cdfab..07426ff4 100644 --- a/src/dynamic/sandbox/mod.rs +++ b/src/dynamic/sandbox/mod.rs @@ -837,7 +837,7 @@ fn run_firecracker( ) -> Result { #[cfg(feature = "firecracker")] { - return firecracker::run(_harness, _payload_bytes, _opts); + firecracker::run(_harness, _payload_bytes, _opts) } #[cfg(not(feature = "firecracker"))] { diff --git a/src/fmt.rs b/src/fmt.rs index 25946ef3..4072e793 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -192,7 +192,7 @@ pub fn render_welcome() -> String { for line in LOGO { out.push_str(&format!( " {}\n", - style(line).true_color(114, 243, 215).bold() + style(line).true_color(46, 160, 103).bold() )); } diff --git a/src/state/lattice.rs b/src/state/lattice.rs index 581f9c2b..4a0b9f48 100644 --- a/src/state/lattice.rs +++ b/src/state/lattice.rs @@ -4,7 +4,6 @@ /// - `join` is commutative, associative, and idempotent /// - `bot()` is the identity for `join` /// - `leq(a, b)` iff `join(a, b) == b` -#[allow(dead_code)] pub trait Lattice: Clone + Eq + Sized { /// Bottom element (least information / unreachable). fn bot() -> Self; @@ -28,7 +27,6 @@ pub trait Lattice: Clone + Eq + Sized { /// - `meet(a, b) ⊑ a` and `meet(a, b) ⊑ b` /// - `widen(a, b) ⊒ join(a, b)` (widening is at least as imprecise as join) /// - Ascending chains under `widen` stabilize in finite steps -#[allow(dead_code)] pub trait AbstractDomain: Lattice { /// Top element (no information / maximally imprecise). fn top() -> Self;