fix: stop disabling TruffleHog verification for verified-only scans - #110
Open
lelia wants to merge 3 commits into
Open
fix: stop disabling TruffleHog verification for verified-only scans#110lelia wants to merge 3 commits into
lelia wants to merge 3 commits into
Conversation
Turning trufflehog_show_unverified off passed --no-verification, which disabled verification outright instead of returning only verified findings. Severity is derived from each finding's Verified flag, so every result came back Verified: false -> low severity -> non-blocking. On the setting's default path no secret could ever block a run: the exact inverse of intent. Verification now always runs, and the setting selects result types only: --results=verified when off, --results=verified,unverified,unknown when on (the latter matching TruffleHog's own default). Verified findings stay critical/blocking, unverified stay low/non-blocking. --include-detectors=all is now passed unconditionally so detector selection no longer changes as a side effect of the setting. TruffleHog already defaults to all detectors, so this is a no-op in practice. Verified against the pinned trufflesecurity/trufflehog:3.96.0 binary: an unverifiable private key is returned under the "on" filter and dropped under the "off" filter. Two upgrade consequences, documented in the changelog: runs with the setting off will start reporting blocking critical findings previously downgraded to low, and verification is a live check, so TruffleHog now makes outbound requests to third-party credential-validation endpoints. Also corrects TruffleHog parameter docs (exclude paths accept files and globs, not just directories; show-unverified widens result types rather than toggling verification) and a JSON config example that named a nonexistent show_unverified key. Fixes CE-351 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Only the environment loader coerces bool params (config.py:924). A Socket dashboard config is passed through verbatim (config.py:1309) and outranks env, so a dashboard-supplied string "false" reached the connector as a truthy value. Under the old --no-verification code that misread was a harmless no-op: it selected --include-detectors=all, which is TruffleHog's default anyway. Now it would select --results=verified,unverified,unknown and report unverified secrets to someone who explicitly asked for verified-only, so the same latent misread became a real behavioral bug. Covers "false"/"False"/"0"/"no", the true forms, and the unset cases (None and the empty string an unset action input forwards). Verified the new test fails against the truthiness read and passes with coerce_bool. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Any non-zero exit was logged and converted into an empty result, so a malformed exclude pattern or a broken install silently zeroed out every secret finding while the run exited green. A scanner that could not scan looked identical to a repository with no secrets. Non-zero exits and a missing trufflehog binary now raise SystemExit with the exit code and TruffleHog's own stderr. SystemExit is deliberate: the connector manager catches Exception, and this must not be downgraded to a skipped connector. The exclude-file cleanup in the finally block still runs on the failure path. This closes the last open acceptance criterion from CE-347 ("a malformed/unopenable exclude value no longer causes trufflehog to silently return zero findings for the whole run"). Its other two criteria shipped in 2.2.1 via #94, which referenced CE-347 without closing it. Matches the fail-closed idiom already used for an unresolvable changed_files scope, which also raises SystemExit with an actionable message. test_scan_cleans_exclude_file_when_trufflehog_fails asserted the old swallowing behavior; it now expects the failure to surface while still asserting the temp filter file is cleaned up. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 64cf028. Configure here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stabilizes the TruffleHog experience for a single upcoming release, closing CE-351 and the last open item from CE-347.
1. Verified-only scans no longer disable verification (CE-351)
Turning Show Unverified Secrets off passed
--no-verification, which disabled verification outright instead of returning only verified findings.Severity is derived from each finding's
Verifiedflag (trufflehog/__init__.py:476,481,541), so with verification disabled every finding came backVerified: false→low→ non-blocking. On the setting's default path, no secret could ever block a run — the exact inverse of the intended behavior.Verification now always runs; the setting selects result types only:
trufflehog_show_unverified--results=verified--results=verified,unverified,unknown--include-detectors=allis now passed unconditionally so detector selection no longer changes as a side effect. TruffleHog already defaults to all detectors, so that half is a no-op in practice.The setting is also now read through
coerce_bool. Only the env loader coerces bool params (config.py:924); the dashboard normalizer assigns verbatim (config.py:1309) at higher priority, so a dashboard-supplied string"false"was truthy and would have reported unverified secrets to someone who turned them off. (Bugbot finding, fixed in 12048e0.)2. A TruffleHog run that cannot scan no longer looks like a clean scan (CE-347)
Any non-zero exit was logged and converted into an empty result, so a malformed exclude pattern or a broken install silently zeroed out every secret finding while the run exited green. Non-zero exits and a missing binary now raise
SystemExitnaming the exit code and TruffleHog's own stderr.This is the same failure class as #1 — secret scanning reporting nothing and passing — which is why it's folded in here rather than shipped separately. It also de-risks #1 directly: verification is now a live network call, so there are strictly more ways for the run to fail, and until now every one of them was silent.
SystemExitis deliberate — the connector manager catchesException(manager.py:290), and this must not be downgraded to a skipped connector. It matches the fail-closed idiom already used for an unresolvablechanged_filesscope. The exclude-file cleanup in thefinallyblock still runs on the failure path.CE-347's other two criteria (multiple comma-separated patterns,
**/appsettings.*.jsonglobs) shipped in 2.2.1 via #94, which referenced CE-347 without closing it. This closes it.Validation
uv run --with pytest pytest -q— 349 passedtrufflesecurity/trufflehog:3.96.0binary rather than from help text alone. Scanning a throwaway RSA private key:--results=verified,unverified,unknown→PrivateKey Verified=Falsereturned--results=verified→ zero findings--resultsisverified,unverified,unknown, so the "on" branch matches TruffleHog's default exactly.socket-basics --helpand importing both modules, to rule out a circular import from the new top-levelfrom ...config import coerce_bool.New
tests/test_trufflehog_verification.py(10 tests): result-type flag per setting state,--no-verificationabsent in both, detector flag identical across both states,coerce_boolstring forms ("false"/"False"/"0"/"no"plus the true forms) and unset cases (Noneand the empty string an unset action input forwards), severity/action proving verified →critical/error(blocks) and unverified →low/ignore(does not), and both fail-closed paths.Two existing tests asserted the old behavior and are updated rather than worked around:
tests/test_changed_files_scope.py:890asserted--no-verificationwas in the commandtests/test_trufflehog_excludes.py:474asserted a failed run returns{}; it now expects the failure to surface, still asserting temp-file cleanupI confirmed the
coerce_booltest is not vacuous: it fails against the truthiness read and passes with the fix.Three user-visible changes on the default path, all documented explicitly in the CHANGELOG and both user-facing docs pages:
unknown, which--results=verifieddrops — so a no-egress scanner reports zero findings rather than failing loudly. Documented workaround: settrufflehog_show_unverified: truesounknownresults still surface as low severity. This is the one silent-failure mode left in the change; the AC specified--results=verifiedexplicitly, so I implemented that rather than quietly addingunknown. Worth a second opinion.Also for a reviewer's call
is_enabled()readssecret_scanning_enabledwith raw truthiness, as doscan_allandchanged_files_scope_requestedelsewhere in this connector. Same latentcoerce_boolhazard as the Bugbot finding above, but fixing them changes behavior beyond this PR's scope — and they err toward enabling scanning rather than under-reporting secrets, so it's the less dangerous direction. Happy to do a follow-up sweep of bool reads across all connectors if you want it tracked separately.Suggested version: 3.2.0 (minor), matching the precedent set by 3.1.0, which shipped a fail-the-run behavioral change as a minor. No version files are bumped here — CHANGELOG entries sit under
[Unreleased]per the usual release-prep flow.Docs
Corrected
docs/parameters.md(which claimed "by default only verified secrets are shown" — false while--no-verificationwas in use), the input reference and example indocs/github-action.md, and thetrufflehog_show_unverifieddescriptions inaction.yml/connectors.yaml. Added egress warnings to both docs pages.Drive-by:
docs/parameters.mddocumented the JSON config key asshow_unverified, which does not exist — a customer copying that example would get no effect. Nowtrufflehog_show_unverified. (Neighboringsecrets_enabledlooks similarly suspect but is referenced ingithub_pr_notifier.py:493, so I left it alone.)Fixes CE-351
Fixes CE-347
🤖 Generated with Claude Code
Note
High Risk
Behavioral changes to secret scanning affect CI gating, introduce live verification network calls, and can silently under-report on restricted egress; misconfiguration now fails runs instead of passing quietly.
Overview
Fixes TruffleHog secret scanning so verification always runs and
trufflehog_show_unverifiedonly widens reported result types (--results=verifiedvs--results=verified,unverified,unknown), removing the old--no-verificationpath that made every finding unverified/low and non-blocking on the default setting. The connector now always passes--include-detectors=all, reads the flag viacoerce_bool(so dashboard string"false"is not truthy), and fails the run on non-zero TruffleHog exit or a missing binary instead of returning an empty “clean” result.Upgrade impact: verified secrets can start blocking runs that previously passed; scans require network egress for verification; air-gapped runners may see zero findings unless
trufflehog_show_unverifiedis enabled. CHANGELOG, action inputs, and docs are updated accordingly, with new regression tests intests/test_trufflehog_verification.py.Reviewed by Cursor Bugbot for commit 64cf028. Configure here.