diff --git a/CHANGELOG.md b/CHANGELOG.md index 8555b69..023cc33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. ## [Unrelease] - pattern_requirements for rules — Post-regex character-class gating to cut false positives without lookarounds. Authors can now require minimum counts of digits, uppercase, lowercase, and special characters, with an optional custom special-char set. Why? Hyperscan doesn’t support lookaheads/behinds, so many "must contain X and Y" checks had to be baked into the regex (hurting readability) or were impossible. `pattern_requirements` applies lightweight, in-memory checks after a match is found, keeping patterns fast and clean. +- updated rules with support for `pattern_requirements` +- Automatically set `--no-dedup` whenever `--manage-baseline` is supplied so baseline management retains every occurrence of a finding + ## [v1.61.0] - Fixed local filesystem scans to keep `open_path_as_is` enabled when opening Git repositories and only disable it for diff-based scans. - Created Linux and Windows specific installer script diff --git a/README.md b/README.md index 29a11e8..5924c55 100644 --- a/README.md +++ b/README.md @@ -1083,6 +1083,8 @@ kingfisher scan /path/to/code \ --baseline-file ./baseline-file.yml ``` +`--manage-baseline` automatically enables `--no-dedup` so the baseline captures every individual occurrence. + Use the same YAML file with the `--baseline-file` option on future scans to hide all recorded findings: ```bash @@ -1159,7 +1161,7 @@ leaves the default unchanged. - `--redact`: Replaces discovered secrets with a one-way hash for secure output - `--exclude `: Skip any file or directory whose path matches this glob pattern (repeatable, uses gitignore-style syntax, case sensitive) - `--baseline-file `: Ignore matches listed in a baseline YAML file -- `--manage-baseline`: Create or update the baseline file with current findings +- `--manage-baseline`: Create or update the baseline file with current findings (automatically enables `--no-dedup`) - `--skip-regex `: Ignore findings whose text matches this regex (repeatable) - `--skip-word `: Ignore findings containing this case-insensitive word (repeatable) - `--skip-aws-account `: Skip live AWS validation for findings tied to the specified AWS account number (repeatable, accepts comma-separated lists) diff --git a/src/cli/commands/scan.rs b/src/cli/commands/scan.rs index 8deb595..1f0aaf5 100644 --- a/src/cli/commands/scan.rs +++ b/src/cli/commands/scan.rs @@ -416,6 +416,10 @@ impl ScanCommandArgs { self.scan_args.input_specifier_args.emit_deprecated_warnings(); } + if self.scan_args.manage_baseline { + self.scan_args.no_dedup = true; + } + Ok(ScanOperation::Scan(self.scan_args)) } } diff --git a/tests/smoke_baseline.rs b/tests/smoke_baseline.rs index f69be7c..d6dbf5b 100644 --- a/tests/smoke_baseline.rs +++ b/tests/smoke_baseline.rs @@ -6,6 +6,39 @@ use tempfile::tempdir; const GH_PAT: &str = "ghp_1wuHFikBKQtCcH3EB2FBUkyn8krXhP2qLqPa"; +#[test] +fn manage_baseline_enables_no_dedup() -> anyhow::Result<()> { + use kingfisher::cli::{ + commands::scan::ScanOperation, + global::{Command, CommandLineArgs}, + }; + + let dir = tempdir()?; + + let args = CommandLineArgs::try_parse_from([ + "kingfisher", + "scan", + dir.path().to_str().unwrap(), + "--manage-baseline", + "--no-update-check", + ])?; + + let command = match args.command { + Command::Scan(scan_args) => scan_args, + other => panic!("unexpected command parsed: {:?}", other), + }; + + let scan_args = match command.into_operation()? { + ScanOperation::Scan(scan_args) => scan_args, + op => panic!("expected scan operation, got {:?}", op), + }; + + assert!(scan_args.manage_baseline); + assert!(scan_args.no_dedup); + + Ok(()) +} + #[test] fn baseline_create_and_filter() -> anyhow::Result<()> { let dir = tempdir()?;