mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-06 19:35:13 +02:00
chore: Update version placeholders and changelog for release 0.6.0
This commit is contained in:
parent
215dd02eff
commit
92aaa36ed6
6 changed files with 86 additions and 42 deletions
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -41,7 +41,7 @@ body:
|
|||
attributes:
|
||||
label: Nyx version
|
||||
description: Output of `nyx --version`.
|
||||
placeholder: "nyx 0.5.0"
|
||||
placeholder: "nyx 0.6.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ All notable changes to Nyx are documented here. The format is based on [Keep a C
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.6.0] - TBD
|
||||
## [0.6.0] - 2026-05-02
|
||||
|
||||
A focused release that splits data-exfiltration off from SSRF and ships sinks for outbound HTTP request bodies across all 10 languages, with calibration tuned so plain user input echoed back upstream does not fire.
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ Requires stable Rust 1.88+. The frontend is compiled and embedded in the binary
|
|||
|
||||
## Languages
|
||||
|
||||
All 10 languages parse via tree-sitter and run through the full pipeline, but rule depth and engine coverage are uneven. Benchmark F1 on the 492-case corpus at [`tests/benchmark/ground_truth.json`](tests/benchmark/ground_truth.json) is 100% across all ten languages, so F1 alone no longer separates the tiers. Tiering reflects rule depth, gated-sink coverage, and structural idioms the synthetic corpus does not fully stress:
|
||||
All 10 languages parse via tree-sitter and run through the full pipeline, but rule depth and engine coverage are uneven. Benchmark F1 on the 507-case corpus at [`tests/benchmark/ground_truth.json`](tests/benchmark/ground_truth.json) is 100% across all ten languages, so F1 alone no longer separates the tiers. Tiering reflects rule depth, gated-sink coverage, and structural idioms the synthetic corpus does not fully stress:
|
||||
|
||||
| Tier | Languages | F1 | Use as a CI gate? |
|
||||
|---|---|---|---|
|
||||
|
|
@ -137,6 +137,7 @@ The corpus also holds a small set of vulnerable/patched pairs extracted from pub
|
|||
| [CVE-2023-22621](https://nvd.nist.gov/vuln/detail/CVE-2023-22621) | Strapi | JavaScript | Code execution (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 injection |
|
||||
| [CVE-2022-30323](https://nvd.nist.gov/vuln/detail/CVE-2022-30323) | hashicorp/go-getter | Go | Command injection |
|
||||
| [CVE-2024-31450](https://nvd.nist.gov/vuln/detail/CVE-2024-31450) | owncast | Go | Path traversal |
|
||||
|
|
@ -211,7 +212,7 @@ Or add rules interactively: `nyx config add-rule --lang javascript --matcher esc
|
|||
|
||||
## Status
|
||||
|
||||
Under active development. APIs, detector behavior, and configuration options may change between releases. Rule-level F1 on the 492-case corpus is the CI regression floor; per-language detail lives in [`tests/benchmark/RESULTS.md`](tests/benchmark/RESULTS.md).
|
||||
Under active development. APIs, detector behavior, and configuration options may change between releases. Rule-level F1 on the 507-case corpus is the CI regression floor; per-language detail lives in [`tests/benchmark/RESULTS.md`](tests/benchmark/RESULTS.md).
|
||||
|
||||
Taint analysis is interprocedural. Persisted per-function SSA summaries carry per-return-path transforms and parameter-granularity points-to, and call-graph SCCs (including SCCs that span files) iterate to a joint fixed-point. The default `balanced` profile also runs k=1 context-sensitive inlining for intra-file callees. Symex (with cross-file and interprocedural frames) and the demand-driven backwards walk are opt-in. Enable them individually with `--symex` and `--backwards-analysis`, or together with `--engine-profile deep`.
|
||||
|
||||
|
|
|
|||
102
SECURITY.md
102
SECURITY.md
|
|
@ -1,46 +1,88 @@
|
|||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
## Reporting a vulnerability
|
||||
|
||||
| Version | Supported | Notes |
|
||||
|---------|-----------|----------------------|
|
||||
| 0.5.x | ✅ | Latest stable line |
|
||||
| 0.4.x | ✅ | Critical fixes only |
|
||||
| < 0.4 | ❌ | End-of-life |
|
||||
Report privately. Do not open a public GitHub issue for a security bug.
|
||||
|
||||
We follow [Semantic Versioning] as soon as we hit **1.0.0**.
|
||||
Before that, breaking changes may land in any minor release.
|
||||
Use [GitHub Security Advisories](https://github.com/elicpeter/nyx/security/advisories/new) to file a private report. Only the maintainers see it.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
Include:
|
||||
|
||||
* **Private disclosure first.**
|
||||
Please **do not** open public GitHub issues for security bugs.
|
||||
- Affected version (`nyx --version`) and OS
|
||||
- Reproduction steps or a minimal PoC
|
||||
- Impact (RCE, file read or write, sandbox escape, auth bypass in `nyx serve`, etc.)
|
||||
- Whether you have a fix in mind
|
||||
|
||||
* **How to report**
|
||||
1. To report a vulnerability, please use the GitHub disclosure in the security tab to alert us to a security issue.
|
||||
You'll get an acknowledgement within 3 business days, and a status update every 7 days until the issue is closed.
|
||||
|
||||
* **What to include**
|
||||
– A minimal PoC or reproduction steps
|
||||
– Affected Nyx version (`nyx --version`) and OS
|
||||
– Impact explanation (e.g. RCE, DoS, data leak)
|
||||
## Scope
|
||||
|
||||
* **Response timeline**
|
||||
We acknowledge within **3 business days** and give a status update every **7 days** thereafter until resolution.
|
||||
In scope: bugs that let untrusted input reach the Nyx process and cause harm.
|
||||
|
||||
## Disclosure Process
|
||||
- Code execution in the scanner: parser exploits, deserialization, command injection in helpers, custom-rule sandbox escape.
|
||||
- Path traversal or arbitrary file access outside the target repo.
|
||||
- `nyx serve` issues: auth bypass, host-header bypass, CSRF on mutating routes, XSS in the UI, cross-origin access from a non-loopback origin.
|
||||
- Memory safety bugs in any unsafe Rust we introduce.
|
||||
- Tampering with `.nyx/` triage state from outside the user's repo.
|
||||
- Supply chain issues affecting published `nyx-scanner` crates or release artifacts.
|
||||
|
||||
1. We confirm the issue and assign a CVE (via GitHub or MITRE).
|
||||
2. A fix is developed on a private branch and back-ported if needed.
|
||||
3. Coordinated release: new version on crates.io + public advisory.
|
||||
4. Credit is given to the reporter unless they request anonymity.
|
||||
Out of scope:
|
||||
|
||||
## Scope & Severity
|
||||
- False positives or missed detections in scan output. File a regular GitHub issue with the rule ID and a fixture.
|
||||
- Findings Nyx reports against your own code. That's the scanner working, not a Nyx vulnerability.
|
||||
- Anything requiring physical or local-account access to the user's machine.
|
||||
- Self-XSS and missing security headers on `127.0.0.1` endpoints. The UI is loopback-only.
|
||||
- Performance pathologies on hostile input (a 50 GB file, deeply nested grammars). We harden where we can.
|
||||
- Issues only reachable by a user editing their own `nyx.conf` to weaken defaults.
|
||||
|
||||
This policy covers vulnerabilities that let an **untrusted Nyx input** cause:
|
||||
## Supported versions
|
||||
|
||||
* Remote or local code execution in the Nyx process
|
||||
* Privilege escalation, data exfiltration, or denial of service
|
||||
| Version | Status |
|
||||
|---------|-----------------------|
|
||||
| 0.6.x | Supported |
|
||||
| 0.5.x | Critical fixes only |
|
||||
| < 0.5 | End of life |
|
||||
|
||||
**False positives / missed detections** in scan results are *quality issues*, not security issues. Please file normal GitHub issues for those.
|
||||
The project follows [Semantic Versioning](https://semver.org) once it reaches 1.0.0. Until then, breaking changes can land in any minor release.
|
||||
|
||||
[Semantic Versioning]: https://semver.org
|
||||
## Severity
|
||||
|
||||
We use [CVSS 3.1](https://www.first.org/cvss/v3.1/specification-document) to rate reports.
|
||||
|
||||
| Severity | Examples |
|
||||
|----------|-----------------------------------------------------------------------------------------------|
|
||||
| Critical | Unauthenticated RCE in `nyx serve`, custom-rule sandbox escape during a default scan |
|
||||
| High | Auth bypass against `nyx serve`, arbitrary file write outside the repo |
|
||||
| Medium | Stored XSS in the UI, CSRF on a mutating route, host-header bypass |
|
||||
| Low | Information disclosure with no privilege change, log-injection, denial of service via input |
|
||||
|
||||
## Disclosure
|
||||
|
||||
Coordinated disclosure.
|
||||
|
||||
1. We confirm the report and assign severity.
|
||||
2. We request a CVE through GitHub or MITRE.
|
||||
3. A fix is developed on a private branch, with backports to supported lines if needed.
|
||||
4. A new release ships on crates.io and a public advisory goes out.
|
||||
5. The reporter is credited in the advisory and the changelog, unless they ask to stay anonymous.
|
||||
|
||||
Target window from report to fix is 90 days. If you need to publish on a shorter timeline, tell us in the report and we'll work toward it.
|
||||
|
||||
## Safe harbor
|
||||
|
||||
Good-faith security research is welcome. We won't pursue legal action against researchers who:
|
||||
|
||||
- Report privately and give a reasonable window before publishing.
|
||||
- Test against their own installations, not third-party deployments running Nyx.
|
||||
- Avoid data destruction, account takeover, and service disruption.
|
||||
- Stop and reach out if a test starts to affect data or systems they don't own.
|
||||
|
||||
If you're not sure whether a test is in scope, ask first.
|
||||
|
||||
## Bounty
|
||||
|
||||
There is no paid bug bounty program. Credit, a thank-you in the advisory, and a mention in the changelog are what we offer today.
|
||||
|
||||
## Security model recap
|
||||
|
||||
Nyx runs locally. The browser UI binds to `127.0.0.1` by default, requires a matching `Host` header, and uses a CSRF token on every mutating request. There is no login, no telemetry, and no remote control plane. If you find a way around any of those defaults, that's a security issue and we want to hear about it.
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ Current baseline (2026-05-02):
|
|||
| Recall | 1.000 | 1.000 | 0.944 |
|
||||
| F1 | 1.000 | 1.000 | 0.901 |
|
||||
|
||||
Corpus: 499 cases across 10 languages, 496 evaluated (3 disabled). Per-run JSON lands in `tests/benchmark/results/` (`latest.json` plus dated snapshots). See `README.md` for what the scoring modes mean and how to run a subset.
|
||||
Corpus: 507 cases across 10 languages, 504 evaluated (3 disabled). Per-run JSON lands in `tests/benchmark/results/` (`latest.json` plus dated snapshots). See `README.md` for what the scoring modes mean and how to run a subset.
|
||||
|
||||
The corpus is mostly synthetic 8-20 line fixtures, one vulnerability or one safe pattern per file. A smaller real-CVE replay set under `cve_corpus/` covers 20 published CVEs across all 10 languages. Both contribute to the headline numbers.
|
||||
The corpus is mostly synthetic 8-20 line fixtures, one vulnerability or one safe pattern per file. A smaller real-CVE replay set under `cve_corpus/` covers 30 published advisories across all 10 languages. Both contribute to the headline numbers.
|
||||
|
||||
## Real CVE coverage
|
||||
|
||||
|
|
@ -40,6 +40,9 @@ Real disclosed CVEs reduced to minimal reproducers, vulnerable + patched pair pe
|
|||
| CVE-2023-38337 | Ruby | rswag | MIT | path_traversal | detected |
|
||||
| CVE-2017-9841 | PHP | PHPUnit | BSD-3-Clause | code_exec | detected |
|
||||
| CVE-2018-15133 | PHP | Laravel | MIT | Deserialization | detected |
|
||||
| CVE-2018-20997 | Rust | tar-rs | MIT OR Apache-2.0 | path_traversal | detected |
|
||||
| CVE-2022-36113 | Rust | cargo | MIT OR Apache-2.0 | path_traversal | detected |
|
||||
| CVE-2024-24576 | Rust | Rust stdlib | MIT OR Apache-2.0 | CMDI | detected |
|
||||
| CVE-2016-3714 | C | ImageMagick (ImageTragick) | ImageMagick License | CMDI | detected |
|
||||
| CVE-2019-18634 | C | sudo (pwfeedback) | ISC | memory_safety | detected |
|
||||
| CVE-2019-13132 | C++ | ZeroMQ libzmq | MPL-2.0 | memory_safety | detected |
|
||||
|
|
|
|||
|
|
@ -15995,9 +15995,8 @@
|
|||
"sqli",
|
||||
"vulnerable"
|
||||
],
|
||||
"disabled": true,
|
||||
"disabled_reason": "Validated-flow propagation through SSA-derived values and helper-summary returns is missing. The patched counterpart applies a regex allowlist (`SAFE_STRING_REGEX.test(value)` throw) PLUS a `replace()` escape chain inside `sanitizeValue`, then interpolates the result into a SQL template literal in `createJSONQuery` and returns the string to the handler, which calls `db.execute(sql)`. This session landed `classify_condition` recognition of `<*regex*>.test(value)` / `<*pattern*>.test(value)` as a ValidationCall whose target is the call's first arg (covered by `path_state::tests::target_regex_test_first_arg`, `target_regex_test_pattern_receiver`, `target_test_non_regex_receiver_is_not_validation`, plus the SSA-level `regex_test_allowlist_narrowing_clears_direct_flow` integration test). But validated_must is per-symbol and consulted only at the sink site; it does NOT propagate through the SSA Assign that templates a clean `value` into a derived `sql` string, nor does it ride a helper's `param_to_return` summary back into a caller. Disabled until that propagation path lands. Tracked in CVE_DEFERRED.md.",
|
||||
"notes": "CVE-2026-25544: Payload `sanitizeValue` SQL injection via Postgres jsonb_path_exists template-string interpolation. Vulnerable form (`@payloadcms/drizzle@v3.72.0`, MIT) lets attacker-controlled JSON-query value escape the surrounding SQL string literal because `sanitizeValue` only double-quotes it without escaping `\\`/`\"`. Disabled pending validated-flow propagation engine work, see disabled_reason."
|
||||
"disabled": false,
|
||||
"notes": "CVE-2026-25544: Payload `sanitizeValue` SQL injection via Postgres jsonb_path_exists template-string interpolation. Vulnerable form (`@payloadcms/drizzle@v3.72.0`, MIT) lets attacker-controlled JSON-query value escape the surrounding SQL string literal because `sanitizeValue` only double-quotes it without escaping `\\`/`\"`. Enabled after validated-flow propagation landed via `SsaFuncSummary.validated_params_to_return` + `propagate_validated_params_to_return`."
|
||||
},
|
||||
{
|
||||
"case_id": "cve-ts-2026-25544-patched",
|
||||
|
|
@ -16024,9 +16023,8 @@
|
|||
"safe",
|
||||
"patched"
|
||||
],
|
||||
"disabled": true,
|
||||
"disabled_reason": "Sibling of cve-ts-2026-25544-vulnerable. Disabled together until validated-flow summary propagation lands. See vulnerable counterpart's disabled_reason for the engine gap.",
|
||||
"notes": "Patched form of `sanitizeValue` from `@payloadcms/drizzle@v3.73.0` (MIT). Disabled together with its vulnerable counterpart pending validated-flow propagation work."
|
||||
"disabled": false,
|
||||
"notes": "Patched form of `sanitizeValue` from `@payloadcms/drizzle@v3.73.0` (MIT). Enabled after validated-flow propagation landed."
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue