mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-06 19:35:13 +02:00
* feat: Enhance data exfiltration detection with source sensitivity gating for cookies and headers * feat: Implement cross-file data exfiltration detection with parameter-specific gate filters * feat: Add calibration tests and refine DATA_EXFIL severity scoring logic * feat: Introduce per-detector configuration for data exfiltration suppression * feat: Enhance DATA_EXFIL findings with destination field tracking in diagnostics and SARIF output * feat: Add tainted body and URL handling for data exfiltration detection * feat: Add integration tests and fixtures for DATA_EXFIL and SSRF detection in Go * feat: Add Java integration tests and fixtures for DATA_EXFIL detection across multiple HTTP clients * feat: Add synthetic externals handling for closure-captured variables in SSA * feat: Implement closure-based suppression for resource leak findings * feat: Add regression guards for shell-injection and taint propagation in for-of destructure patterns * feat: Implement constructor cap narrowing for data exfiltration detection in HTTP request builders * feat: Add gated sinks for data exfiltration detection in C and C++ using curl_easy_setopt * feat: Implement DATA_EXFIL cap parity for backwards analysis and add integration tests * feat: Add data exfiltration sinks for various languages and enhance documentation * refactor: Simplify formatting and improve readability in various files * refactor: Improve readability by simplifying conditional statements and adding clippy linting * docs: Update CHANGELOG and comments for data exfiltration features and configuration * docs: Clarify configuration instructions for data exfiltration trusted destinations * docs: Enhance comments for evidence routing logic in data exfiltration
370 lines
13 KiB
Text
370 lines
13 KiB
Text
# --------------------------------------------------------------------
|
||
# nyx Vulnerability Scanner — DEFAULT CONFIGURATION
|
||
#
|
||
# Copy this file to `nyx.local` in the same directory and override
|
||
# only the keys you need. Anything you omit inherits the defaults
|
||
# shown here.
|
||
# --------------------------------------------------------------------
|
||
|
||
[scanner]
|
||
|
||
## Analysis mode: full | ast | cfg | taint
|
||
## full = AST analyses + CFG + state + taint
|
||
## ast = AST analyses only (tree-sitter patterns + auth analysis; no CFG/taint/state)
|
||
## cfg = CFG + state + taint only (no AST patterns)
|
||
## taint = taint-focused CFG analysis only (no AST patterns, no state findings)
|
||
mode = "full"
|
||
|
||
## Minimum severity level to include in the report
|
||
## Possible values: Low | Medium | High
|
||
min_severity = "Low"
|
||
|
||
## Maximum file size to scan (MiB); null = unlimited.
|
||
## Raise or set to `null` when scanning a trusted codebase with large generated files or bundles.
|
||
max_file_size_mb = 16
|
||
|
||
## File extensions to ignore completely
|
||
excluded_extensions = [
|
||
"jpg", "png", "gif", "mp4", "avi", "mkv",
|
||
"zip", "tar", "gz", "exe", "dll", "so",
|
||
]
|
||
|
||
## Directories to ignore completely
|
||
excluded_directories = [
|
||
"node_modules", ".git", "target", ".vscode",
|
||
".idea", "build", "dist",
|
||
]
|
||
|
||
## Individual files to ignore completely
|
||
excluded_files = []
|
||
|
||
## Honour global ignore file (e.g. ~/.config/nyx/ignore) (RESERVED)
|
||
read_global_ignore = false
|
||
|
||
## Honour .gitignore / .hgignore, etc.
|
||
read_vcsignore = true
|
||
|
||
## Require a .git directory to read gitignore files
|
||
require_git_to_read_vcsignore = true
|
||
|
||
## Limit search to the starting file system only
|
||
one_file_system = false
|
||
|
||
## Follow symlinks when scanning
|
||
follow_symlinks = false
|
||
|
||
## Scan hidden files (dot-files)
|
||
scan_hidden_files = false
|
||
|
||
## Enable state-model dataflow analysis (resource lifecycle + auth state).
|
||
## Detects use-after-close, double-close, resource leaks, and unauthed access.
|
||
## Requires mode = "full" or "cfg" (or explicit taint/state-capable scans). Default: on.
|
||
enable_state_analysis = true
|
||
|
||
## Enable AST-based authorization analysis for supported web frameworks.
|
||
## Produces `<lang>.auth.*` findings such as admin-route, ownership, token,
|
||
## and stale-auth checks. Runs only when AST analysis is active:
|
||
## mode = "full" or "ast" => auth analysis runs
|
||
## mode = "cfg" or "taint" => auth analysis is skipped
|
||
## Per-language auth overrides live under [analysis.languages.<slug>.auth].
|
||
enable_auth_analysis = true
|
||
|
||
## Catch per-file panics during analysis and continue the scan.
|
||
## When false (default), a panic in one file's analyser aborts the whole
|
||
## scan — useful for catching engine bugs loudly in development.
|
||
## When true, the poisoned file is skipped with a warning; the rest of
|
||
## the scan proceeds. Enable when running against untrusted input.
|
||
# enable_panic_recovery = false
|
||
|
||
|
||
[database]
|
||
|
||
## Custom SQLite database path (empty = platform default) (RESERVED)
|
||
path = ""
|
||
|
||
## Number of days to keep database files; 0 = no cleanup (RESERVED)
|
||
auto_cleanup_days = 30
|
||
|
||
## Maximum database size in MiB; 0 = no limit (RESERVED)
|
||
max_db_size_mb = 1024
|
||
|
||
## Run VACUUM on startup
|
||
vacuum_on_startup = false
|
||
|
||
|
||
[output]
|
||
|
||
## Default output format: console | json | sarif
|
||
## Used when --format is not specified on the command line.
|
||
default_format = "console"
|
||
|
||
## Suppress all human-readable status output (stderr)
|
||
quiet = false
|
||
|
||
## Enable attack-surface ranking (sort findings by exploitability score)
|
||
attack_surface_ranking = true
|
||
|
||
## Cap the number of issues shown; null = unlimited
|
||
max_results = null
|
||
|
||
## Minimum attack-surface score to include; null = no minimum
|
||
## Findings below this threshold are dropped after ranking.
|
||
## Requires attack_surface_ranking to be enabled.
|
||
min_score = null
|
||
|
||
## Minimum confidence level to include in output; null = no minimum
|
||
## Values: "low", "medium", "high"
|
||
# min_confidence = "medium"
|
||
|
||
## Include Quality-category findings (excluded by default).
|
||
## Quality findings (e.g. unwrap, expect, panic) are noise-heavy and hidden
|
||
## unless this is set to true or --include-quality is passed.
|
||
include_quality = false
|
||
|
||
## Show all findings: disables category filtering, rollups, and LOW budgets.
|
||
## Equivalent to --all on the command line.
|
||
show_all = false
|
||
|
||
## Maximum total LOW findings to show (rollups count as 1).
|
||
max_low = 20
|
||
|
||
## Maximum LOW findings per file (rollups count as 1).
|
||
max_low_per_file = 1
|
||
|
||
## Maximum LOW findings per rule (rollups count as 1).
|
||
max_low_per_rule = 10
|
||
|
||
## Number of example locations stored in rollup findings.
|
||
rollup_examples = 5
|
||
|
||
|
||
[performance]
|
||
|
||
## Maximum search depth; null = unlimited
|
||
max_depth = null
|
||
|
||
## Minimum depth for reported entries; null = none (RESERVED)
|
||
min_depth = null
|
||
|
||
## Stop traversing into matching directories (RESERVED)
|
||
prune = false
|
||
|
||
## Worker threads; null or 0 = auto
|
||
worker_threads = null
|
||
|
||
## Number of entries to index in a single chunk
|
||
batch_size = 100
|
||
|
||
## Channel capacity multiplier (capacity = threads × this)
|
||
channel_multiplier = 4
|
||
|
||
## Maximum stack size for Rayon threads (bytes)
|
||
rayon_thread_stack_size = 8388608 # 8 MiB
|
||
|
||
## Timeout on individual files (seconds); null = none (RESERVED)
|
||
scan_timeout_secs = null
|
||
|
||
## Maximum memory to use in MiB; 0 = no limit (RESERVED)
|
||
memory_limit_mb = 512
|
||
|
||
|
||
[server]
|
||
|
||
## Enable the local web UI server (nyx serve)
|
||
enabled = true
|
||
|
||
## Host to bind to (localhost only by default for security)
|
||
host = "127.0.0.1"
|
||
|
||
## Port for the web UI
|
||
port = 9700
|
||
|
||
## Open browser automatically when serve starts
|
||
open_browser = true
|
||
|
||
## Auto-reload UI when scan results change
|
||
auto_reload = true
|
||
|
||
## Persist scan runs for history view
|
||
persist_runs = true
|
||
|
||
## Maximum number of saved runs
|
||
max_saved_runs = 50
|
||
|
||
## Auto-sync triage decisions to .nyx/triage.json in the project root.
|
||
## When enabled, triage changes are written to this file so they can be
|
||
## committed to git and shared with your team.
|
||
triage_sync = true
|
||
|
||
|
||
[runs]
|
||
|
||
## Persist scan run history to disk
|
||
persist = false
|
||
|
||
## Maximum number of runs to keep
|
||
max_runs = 100
|
||
|
||
## Save scan logs with each run
|
||
save_logs = false
|
||
|
||
## Save stdout capture with each run
|
||
save_stdout = false
|
||
|
||
## Save code snippets in findings
|
||
save_code_snippets = true
|
||
|
||
|
||
# ─── Scan Profiles ──────────────────────────────────────────────────
|
||
# Named presets that override scan-related config.
|
||
# Activate with --profile <name> on the command line.
|
||
#
|
||
# Built-in profiles: quick, full, ci, taint_only, conservative_large_repo.
|
||
# Override a built-in by defining [profiles.<name>] here.
|
||
#
|
||
# [profiles.quick]
|
||
# mode = "ast"
|
||
# min_severity = "Medium"
|
||
#
|
||
# [profiles.ci]
|
||
# mode = "full"
|
||
# min_severity = "Medium"
|
||
# quiet = true
|
||
# default_format = "sarif"
|
||
|
||
|
||
# ─── Analysis engine toggles ────────────────────────────────────────
|
||
# Release-grade switches for optional analysis passes. Every field has a
|
||
# matching CLI flag (e.g. --no-symex / --backwards-analysis), which takes
|
||
# precedence over the config value for a single run. The listed env vars
|
||
# override both config and CLI when set to "0" or "false".
|
||
#
|
||
# For a shortcut that sets the full stack in one shot, use
|
||
# `nyx scan --engine-profile {fast,balanced,deep}`. The profile applies
|
||
# before individual toggles, so you can mix (e.g. `--engine-profile fast
|
||
# --backwards-analysis`). See `docs/cli.md` for profile contents.
|
||
#
|
||
# To print the resolved engine config for a given invocation without
|
||
# running a scan, pass `--explain-engine`.
|
||
|
||
[analysis.engine]
|
||
|
||
## Path-constraint solving (prunes infeasible paths in taint).
|
||
## Default: on. CLI: --constraint-solving / --no-constraint-solving.
|
||
## env: NYX_CONSTRAINT=0 disables.
|
||
constraint_solving = true
|
||
|
||
## Abstract interpretation (interval / string domains).
|
||
## Default: on. CLI: --abstract-interp / --no-abstract-interp.
|
||
## env: NYX_ABSTRACT_INTERP=0 disables.
|
||
abstract_interpretation = true
|
||
|
||
## k=1 context-sensitive callee inlining for intra-file calls.
|
||
## Default: on. CLI: --context-sensitive / --no-context-sensitive.
|
||
## env: NYX_CONTEXT_SENSITIVE=0 disables.
|
||
context_sensitive = true
|
||
|
||
## Demand-driven backwards taint analysis. Adds a second pass from
|
||
## candidate sinks back toward sources to recover flows the forward
|
||
## solver gave up on. Default: off because it adds scan time on large
|
||
## repos. CLI: --backwards-analysis / --no-backwards-analysis.
|
||
## env: NYX_BACKWARDS=1 enables.
|
||
backwards_analysis = false
|
||
|
||
## Per-file tree-sitter parse timeout (ms). 0 disables the cap.
|
||
## CLI: --parse-timeout-ms. env: NYX_PARSE_TIMEOUT_MS.
|
||
parse_timeout_ms = 10000
|
||
|
||
[analysis.engine.symex]
|
||
|
||
## Run the symex pipeline after taint. Produces witness strings and
|
||
## symbolic verdicts; disable only if you want raw taint output.
|
||
## Default: on. CLI: --symex / --no-symex. env: NYX_SYMEX=0 disables.
|
||
enabled = true
|
||
|
||
## Persist and consult cross-file SSA bodies so symex can reason about
|
||
## callees defined in other files. Adds index/DB work on pass 1.
|
||
## Default: on. CLI: --cross-file-symex / --no-cross-file-symex.
|
||
## env: NYX_CROSS_FILE_SYMEX=0 disables.
|
||
cross_file = true
|
||
|
||
## Intra-file interprocedural symex (k >= 2 via frame stack).
|
||
## Default: on. CLI: --symex-interproc / --no-symex-interproc.
|
||
## env: NYX_SYMEX_INTERPROC=0 disables.
|
||
interprocedural = true
|
||
|
||
## Use the SMT backend when nyx was built with the `smt` feature.
|
||
## Ignored when the feature is off.
|
||
## Default: on. CLI: --smt / --no-smt. env: NYX_SMT=0 disables.
|
||
smt = true
|
||
|
||
|
||
# ─── Detector knobs ──────────────────────────────────────────────────
|
||
# Per-detector class suppression and enablement. These knobs target
|
||
# common false-positive classes that show up on legitimate forwarding
|
||
# pipelines (telemetry / analytics / metrics dispatch).
|
||
#
|
||
# [detectors.data_exfil]
|
||
#
|
||
# # Toggle the entire `taint-data-exfiltration` detector class. Set to
|
||
# # false on projects whose architecture routes user-derived payloads
|
||
# # through trusted forwarding boundaries by design.
|
||
# enabled = true
|
||
#
|
||
# # URL prefixes treated as trusted destinations. Outbound calls whose
|
||
# # destination argument has a static prefix (proven by the abstract
|
||
# # string domain or visible as a literal) matching one of these entries
|
||
# # have `Cap::DATA_EXFIL` dropped before event emission. Mirrors the
|
||
# # SSRF prefix-lock semantics. Use full origins or origin-prefixed
|
||
# # paths (e.g. "https://api.internal/") so partial matches across
|
||
# # unrelated hosts cannot occur.
|
||
# trusted_destinations = [
|
||
# "https://api.internal/",
|
||
# "https://telemetry.",
|
||
# ]
|
||
|
||
|
||
# ─── Per-language analysis rules ─────────────────────────────────────
|
||
|
||
# [analysis.languages.javascript.auth]
|
||
# enabled = true
|
||
# admin_path_patterns = ["/admin/"]
|
||
# admin_guard_names = ["requireAdmin", "isAdmin", "adminOnly"]
|
||
# login_guard_names = ["requireLogin", "authenticate", "requireAuth"]
|
||
# authorization_check_names = ["checkMembership", "hasWorkspaceMembership", "checkOwnership"]
|
||
# mutation_indicator_names = ["update", "delete", "create", "archive", "publish", "addMembership"]
|
||
# read_indicator_names = ["find", "findById", "get", "list"]
|
||
# token_lookup_names = ["findByToken"]
|
||
# token_expiry_fields = ["expires_at", "expiresAt"]
|
||
# token_recipient_fields = ["email", "recipient_email", "recipientEmail"]
|
||
# Auth-analysis rule IDs use language-normalized prefixes:
|
||
# javascript + typescript => js.auth.*
|
||
# python => py.auth.* ruby => rb.auth.* rust => rs.auth.*
|
||
# TypeScript inherits [analysis.languages.javascript.auth] by default; add an
|
||
# optional [analysis.languages.typescript.auth] block only for TS-specific
|
||
# overlays. These settings affect auth analysis only in "full" or "ast" mode.
|
||
# Add custom sources, sanitizers, sinks, terminators, and event handlers.
|
||
# Each language is keyed under [analysis.languages.<slug>] where slug is
|
||
# one of: rust, javascript, typescript, python, go, java, c, cpp, php, ruby.
|
||
#
|
||
# Example: recognise `escapeHtml` as an HTML sanitizer in JavaScript:
|
||
#
|
||
# [analysis.languages.javascript]
|
||
# event_handlers = ["addEventListener"]
|
||
# terminators = ["process.exit"]
|
||
#
|
||
# [[analysis.languages.javascript.rules]]
|
||
# matchers = ["escapeHtml"]
|
||
# kind = "sanitizer"
|
||
# cap = "html_escape"
|
||
#
|
||
# [[analysis.languages.javascript.rules]]
|
||
# matchers = ["location.href", "window.location.href"]
|
||
# kind = "sink"
|
||
# cap = "url_encode"
|
||
#
|
||
# Valid `kind` values: "source", "sanitizer", "sink"
|
||
# Valid `cap` values: "env_var", "html_escape", "shell_escape",
|
||
# "url_encode", "json_parse", "file_io",
|
||
# "fmt_string", "sql_query", "deserialize",
|
||
# "ssrf", "code_exec", "crypto", "all"
|