mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-18 20:15:14 +02:00
fix(cli): apply repository triage file during scans
This commit is contained in:
parent
991c84a1eb
commit
1148e65f36
42 changed files with 571 additions and 20 deletions
|
|
@ -99,6 +99,8 @@ fn make_diag(
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ fn diag_with_caps(path: &str, line: usize, caps: Cap) -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ fn fixture_findings() -> Vec<Diag> {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: Vec::new(),
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@
|
|||
//! reproducible.
|
||||
|
||||
use assert_cmd::Command;
|
||||
use nyx_scanner::commands::scan::Diag;
|
||||
use predicates::prelude::*;
|
||||
use serde_json::Value;
|
||||
use serde_json::{Value, json};
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Build a scan command with a fresh config dir and a writable tempdir as
|
||||
|
|
@ -197,6 +198,91 @@ fn scan_json_stdout_is_machine_clean_when_tracing_warns() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scan_respects_committed_triage_file_for_cli_output_and_fail_on() {
|
||||
let home = tempfile::tempdir().unwrap();
|
||||
let target = tempfile::tempdir().unwrap();
|
||||
std::fs::write(
|
||||
target.path().join("app.js"),
|
||||
b"const q = req.query.x;\neval(q);\n",
|
||||
)
|
||||
.unwrap();
|
||||
let canonical_target = target.path().canonicalize().unwrap();
|
||||
|
||||
let scan_args = [
|
||||
"--format",
|
||||
"json",
|
||||
"--quiet",
|
||||
"--index",
|
||||
"off",
|
||||
"--no-verify",
|
||||
"--all",
|
||||
"--include-quality",
|
||||
"--parse-timeout-ms",
|
||||
"0",
|
||||
];
|
||||
let (mut first_cmd, _) = scan_cmd(home.path(), target.path());
|
||||
first_cmd.args(scan_args);
|
||||
let first = first_cmd.assert().success();
|
||||
let first_json = assert_stdout_is_json_from_byte_zero(
|
||||
&first.get_output().stdout,
|
||||
"initial nyx scan --format json",
|
||||
);
|
||||
let findings = first_json["findings"]
|
||||
.as_array()
|
||||
.expect("scan JSON must include findings");
|
||||
assert!(
|
||||
!findings.is_empty(),
|
||||
"fixture should emit at least one finding"
|
||||
);
|
||||
|
||||
let decisions: Vec<Value> = findings
|
||||
.iter()
|
||||
.map(|finding| {
|
||||
let diag: Diag = serde_json::from_value(finding.clone()).unwrap();
|
||||
json!({
|
||||
"fingerprint": nyx_scanner::server::models::compute_portable_fingerprint(
|
||||
&diag,
|
||||
&canonical_target,
|
||||
),
|
||||
"state": "false_positive",
|
||||
"note": "fixture triaged by committed file",
|
||||
"rule_id": diag.id,
|
||||
"path": diag.path.strip_prefix(canonical_target.to_string_lossy().as_ref())
|
||||
.unwrap_or(&diag.path)
|
||||
.trim_start_matches('/')
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
let nyx_dir = target.path().join(".nyx");
|
||||
std::fs::create_dir(&nyx_dir).unwrap();
|
||||
std::fs::write(
|
||||
nyx_dir.join("triage.json"),
|
||||
serde_json::to_vec_pretty(&json!({
|
||||
"version": 1,
|
||||
"decisions": decisions,
|
||||
"suppression_rules": []
|
||||
}))
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let (mut second_cmd, _) = scan_cmd(home.path(), target.path());
|
||||
second_cmd.args(scan_args).args(["--fail-on", "HIGH"]);
|
||||
let second = second_cmd.assert().success();
|
||||
let second_json = assert_stdout_is_json_from_byte_zero(
|
||||
&second.get_output().stdout,
|
||||
"triaged nyx scan --format json",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
second_json["findings"].as_array().unwrap().len(),
|
||||
0,
|
||||
"terminal triage decisions from .nyx/triage.json should be hidden by default"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scan_sarif_stdout_is_machine_clean_when_tracing_warns() {
|
||||
let home = tempfile::tempdir().unwrap();
|
||||
|
|
|
|||
|
|
@ -970,6 +970,8 @@ fn make_diag(path: &Path, func: &str, cap: Cap, sink_line: u32) -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ fn base_diag() -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: Vec::new(),
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ fn deny_diag(stable_hash: u64) -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
@ -312,6 +314,8 @@ fn confirmed_run_is_byte_identical_across_runs() {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ mod parity_tests {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ mod verify_e2e {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
@ -111,6 +113,8 @@ mod verify_e2e {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ fn high_confidence_taint_diag(path: &str, line: u32) -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: Vec::new(),
|
||||
|
|
|
|||
|
|
@ -454,6 +454,8 @@ mod go_fixture_tests {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ fn diag(severity: Severity, id: &str, conf: Option<Confidence>) -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: Vec::new(),
|
||||
|
|
|
|||
|
|
@ -452,6 +452,8 @@ mod java_fixture_tests {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -447,6 +447,8 @@ mod js_fixture_tests {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ fn base_diag() -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: Vec::new(),
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ mod lang_detect {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -442,6 +442,8 @@ mod php_fixture_tests {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ fn empty_diag() -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -930,6 +930,8 @@ mod python_fixture_tests {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -281,6 +281,8 @@ mod rust_fixture_tests {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -754,6 +754,8 @@ mod hardening_tests {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
@ -947,6 +949,8 @@ mod hardening_tests {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -649,6 +649,8 @@ finally:
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
@ -787,6 +789,8 @@ finally:
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ fn base_diag() -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: "deadbeef01234567".into(),
|
||||
alternative_finding_ids: Vec::new(),
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ fn make_diag(id: &str, path: &str, line: usize) -> Diag {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ mod spec_strategies {
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ fn make_diag(path: &str, handler: &str, line: usize, cap: Cap, rule_id: &str) ->
|
|||
rank_reason: None,
|
||||
suppressed: false,
|
||||
suppression: None,
|
||||
triage_state: "open".to_string(),
|
||||
triage_note: String::new(),
|
||||
rollup: None,
|
||||
finding_id: String::new(),
|
||||
alternative_finding_ids: vec![],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue