Skip to content

ci: scan pull requests for credentials and injection with ThreatCrush - #856

Closed
ralyodio wants to merge 6 commits into
NeptuneHub:mainfrom
ralyodio:threatcrush-scan
Closed

ci: scan pull requests for credentials and injection with ThreatCrush#856
ralyodio wants to merge 6 commits into
NeptuneHub:mainfrom
ralyodio:threatcrush-scan

Conversation

@ralyodio

Copy link
Copy Markdown

Adds a pull-request workflow that scans the diff for hardcoded credentials,
injection, SSRF and unsafe deserialisation. Results go to the Security tab as
SARIF and to a comment on the pull request.

It is report-only. failOn is empty, so it annotates and never fails a build.
A repository with pre-existing findings should get a report on its first install,
not a blocked pull request — a gate that fires on everything gets switched off
within a day. Tighten it to critical,high in the workflow once any backlog is
triaged.

  • .github/workflows/threatcrush-scan.yml — the workflow
  • .github/scripts/threatcrush-to-sarif.py — a compatibility shim for CLI versions
    older than native SARIF output; unused once the installed CLI can emit it itself

Permissions are least-privilege (contents: read, pull-requests: write,
security-events: write). It runs on pull_request, not pull_request_target,
so contributor code never executes with your secrets in scope. The SARIF upload
is continue-on-error and degrades quietly where code scanning is unavailable.

Disclosure: I maintain ThreatCrush.
It is free and MIT, and the workflow installs it from npm — nothing here phones
home. If this is not something you want, closing it is the right answer, and I
will not send another.

SonarCloud's quality gate failed this PR with a C security rating on new
code, both findings on the install line:

  githubactions:S6505  omitting --ignore-scripts allows lifecycle scripts
                       to run during package installation
  githubactions:S8543  using dependencies without locking resolved versions

Both are fair, and on a security-scanning workflow they are the whole
argument. The job holds pull-requests: write and security-events: write,
and it was installing a floating @latest with lifecycle scripts enabled.

- install with --ignore-scripts. The CLI declares no install hook, and
  `scan` was verified to run correctly from an --ignore-scripts install.
- pin @profullstack/threatcrush@0.11.0 instead of @latest.
- persist-credentials: false on checkout; nothing in this job pushes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ralyodio

Copy link
Copy Markdown
Author

Your SonarCloud gate caught two real problems in this workflow, and it was right to fail it — on a security-scanning PR they are the whole argument. Pushed a fix rather than leaving it red:

githubactions:S6505  Omitting "--ignore-scripts" allows lifecycle scripts to run
                     during package installation.
githubactions:S8543  Using dependencies without locking resolved versions is
                     security-sensitive.

The job holds pull-requests: write and security-events: write, and it was installing a floating @latest with lifecycle scripts enabled. That means a publish anywhere in the scanner's dependency tree could have run arbitrary code in a write-scoped job on your runners. Not something you should have to accept from a drive-by PR.

  • install with --ignore-scripts — the CLI declares no install hook, and I verified scan still runs correctly from an --ignore-scripts install before changing this
  • pin @profullstack/threatcrush@0.11.0 instead of @latest, so the version you review is the version that runs
  • persist-credentials: false on checkout — nothing in this job pushes, so the token should not sit in .git/config while a network-installed scanner reads the diff

Fixed upstream too, so nobody else receives the version your scanner just rejected: profullstack/sh1pt#957 and profullstack/threatcrush#121.

Entirely understood if this still isn't something you want — closing it is a fine answer and I won't send another.

Signed-off-by: Anthony Ettinger <anthony@chovy.com>
Signed-off-by: Anthony Ettinger <anthony@chovy.com>
Signed-off-by: Anthony Ettinger <anthony@chovy.com>
Signed-off-by: Anthony Ettinger <anthony@chovy.com>
@sonarqubecloud

Copy link
Copy Markdown

@NeptuneHub

Copy link
Copy Markdown
Owner

I'm not going to merge it, this PR wasn't discussed in an issue as explained in the contributing guideline and also the test that you proposed are already covered from other test.

@NeptuneHub NeptuneHub closed this Aug 19, 2026
@ralyodio
ralyodio deleted the threatcrush-scan branch August 19, 2026 07:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants