#5190·trufflehog

GitHub Action: unhandled event types silently fall through to a full-history scan (BASE/HEAD left empty)

Author: MoazMansourCreated Aug 8, 2026Updated Aug 8, 2026

Summary

The action's event dispatch has branches for push, workflow_dispatch/schedule, and pull_request. Any other github.event_name falls out of the ladder with BASE and HEAD still unset, and the scan then runs with empty --since-commit and --branch. Combined with the fetch-depth: 0 checkout the action's own README recommends, the effect is a silent full-history scan across all fetched refs — where the user expected a diff scan, and with no indication in the log that the scope changed.

release is the case that bit us, but the same applies to merge_group, pull_request_target, push_tag, and anything else not in the list.

The code

action.yml:

bash
else
  if [ "${{ github.event_name }}" == "push" ]; then
    ...
  elif [ "${{ github.event_name }}" == "workflow_dispatch" ] || [ "${{ github.event_name }}" == "schedule" ]; then
    BASE=""
    HEAD=""
  elif [ "${{ github.event_name }}" == "pull_request" ]; then
    BASE=${{github.event.pull_request.base.sha}}
    HEAD=${{github.event.pull_request.head.sha}}
  fi
fi
...
docker run --rm -v .:/tmp -w /tmp \
"${IMAGE}:${VERSION}" \
git file:///tmp/ \
--since-commit \
${BASE:-''} \
--branch \
${HEAD:-''} \

There is no else on the inner ladder. For an unhandled event both variables stay empty and ${BASE:-''} / ${HEAD:-''} expand to empty strings.

Worth contrasting with the guard immediately above it, which handles the opposite failure explicitly:

bash
## If BASE == HEAD, exit with error
echo "::error::BASE and HEAD commits are the same. TruffleHog won't scan anything. Please see documentation (...)"

"Scans nothing" gets a hard error. "Scans everything, on every ref, unasked" gets nothing.

Observed

A release: [published] run, on a workflow whose other jobs are shared with its PR checks:

if [ "release" == "push" ]; then ...
elif [ "release" == "workflow_dispatch" ] || [ "release" == "schedule" ]; then ...
elif [ "release" == "pull_request" ]; then ...
fi
env:
  BASE:
  HEAD:
scanning repo {"unit": "/tmp/trufflehog-19-2005203197", "repo": "file:///tmp"}
finished scanning {"chunks": 5730, "bytes": 3110451, "verified_secrets": 20, ...}
##[error]Process completed with exit code 183

5730 chunks is the entire history, not the release diff.

Why this is worse than a scope surprise

The findings a history scan surfaces are, by construction, things you cannot fix by changing code — they're immutable commits. So the failure is not actionable in the way a diff finding is, and it arrives at release time rather than at review time.

In our case all 20 were false positives from the Lob detector (#5184), the oldest from 2024. The PR that introduced each of those filenames had passed, correctly, because PR runs scan a diff. The same commits then blocked a release two years later. Two defects were needed to produce that outcome, and this is the one that decided when it landed and how much it surfaced.

It also makes the behaviour non-obvious to debug: identical code, identical action ref, one job passes and one fails, and nothing in the log says the scan scope differed.

Suggested fix

Any of these would be an improvement, roughly in order of preference:

  1. Add an else that fails loudly, mirroring the BASE == HEAD guard — ::error:: naming the unhandled event_name and pointing at the base/head inputs. Unhandled input should not silently become the most expensive possible behaviour.
  2. Handle release explicitly. github.event.release.tag_name and the previous tag are both reachable, so a tag-to-tag diff is well defined.
  3. Log the effective scan scope unconditionally — one line stating diff-vs-full and the resolved BASE/HEAD. Cheap, and it would have made this self-diagnosing.

Happy to open a PR for (1) plus (3) if you'd take it.

Environment

  • Action trufflesecurity/[email protected], scanner image 3.96.0
  • actions/checkout@v7 with fetch-depth: 0
  • extra_args: --only-verified
  • Runner ubuntu-24.04

Source: trufflesecurity/trufflehog