Secrets and dependencies
Five static scanners that never touch the running app. They read artefacts of the repository itself: manifests that name a version, and a git history that remembers what was committed. Each one turns a line of text into a name plus a version or a secret shape, then decides from a table, a regex, or an OSV.dev lookup.
How this group works
All five run in phase 7 of the pipeline against the same repository snapshot. Two lanes share that input. The dependency lane extracts name@version from a manifest and looks it up; the secrets lane runs regexes over every file at HEAD and over every added line in history. Only the lookup lane ever makes a network request, and only to api.osv.dev.
1Repo ingestion clones shallow and indexes key files by exact name (package.json, pyproject.toml, pom.xml, build.gradle, go.mod, .env) and by pattern (Dockerfile*, docker-compose*.y*ml, compose*.y*ml, requirements*.txt, openapi*.y*ml, swagger*.y*ml, .env.* with template files such as .env.example excluded), plus the usual code extensions. Everything below reads from that snapshot.
2Extract. A manifest line becomes a name and a version. Semver prefixes are stripped (^4.17.15 is queried as 4.17.15), Python names are lower-cased with dashes removed, Maven coordinates are group:artifact. A version that is a ${property} cannot be resolved and is skipped.
3Look up. Two mechanisms. The Python and Java scanners carry a built-in table of 13 and 12 packages with a <X.Y.Z range each; the rule is installed < threshold, comparing the first three numeric parts. The npm and OSV scanners POST batches of up to 100 queries to api.osv.dev/v1/querybatch, which needs no API key.
4Report. One finding per matched range or per OSV vulnerability: the severity comes from the table entry or from OSV's label, the file and line come from the manifest, the fix is an upgrade target. Confidence is 0.85 for a table hit and 0.95 for an OSV hit.
5The secrets lane has no lookup. Thirteen regexes run over every indexed file at HEAD, then over the added lines of up to 500 file-adding commits, then over the file names in history. A hit is masked, tagged with its commit, and marked whether it still exists at HEAD, because a key that was "removed" is still live until rotated.
Scanners in this group
Git secrets
Thirteen key shapes over the working tree and over every added line in history. A secret deleted in a later commit is still found, tagged with the commit that added it.
npm dependencies
package.json across every workspace, prefixes stripped, batches of 100 posted to OSV, and how a CVSS score or a MODERATE label becomes a severity.
Python dependencies
requirements.txt and pyproject.toml against a 13-package table. The three-part integer compare, the operator it ignores, and the unpinned-line check.
Java dependencies
pom.xml blocks and Gradle declarations against twelve coordinates, Log4Shell first. Why a ${property} version is invisible and when Struts yields two findings.
OSV dependencies
One scanner, six manifest formats, one batch API. The record anatomy: which field sets the severity, which event sets the fix, and the dedup key.
At a glance
| Scanner | What it looks at | What it reports | Severity range | Needs |
|---|---|---|---|---|
Git secretsgit_secret_scanner | Every indexed file at HEAD; added lines of up to 500 file-adding commits (git log --all -p); file names in history | 13 secret patterns (Stripe, AWS, GitHub, OpenAI, Anthropic, DB URLs, Firebase, SendGrid, Twilio, private keys, JWT-shaped Supabase keys); 5 sensitive file names | Critical–High | Repository with a .git directory; no network |
npm dependenciesdependency_scanner | package.json at the root and in each workspace: dependencies + devDependencies, first 200 packages | One finding per OSV vulnerability for the cleaned version; severity from the OSV label, else a computed CVSS v3 score, default Medium | Critical–Low | Repository; outbound HTTPS to api.osv.dev; no API key |
Python dependenciespython_dependency_scanner | requirements.txt, pyproject.toml [project.dependencies] | 13-package built-in table with <X.Y.Z ranges; unpinned lines in requirements.txt | Critical–Low | Repository only |
Java dependenciesjava_dependency_scanner | pom.xml <dependency> blocks; build.gradle / .kts declarations | 12-coordinate built-in table (Log4j, Struts, Spring, Jackson, JJWT, Commons, Guava, Tomcat, MySQL) | Critical–Medium | Repository only |
OSV dependenciesosv_dependency_scanner | package.json, requirements.txt, pyproject.toml, pom.xml, build.gradle(.kts), go.mod | One finding per (package, version, vuln id) from OSV.dev, with CVE alias, fixed version and osv.dev link; default Medium | Critical–Low | Repository; outbound HTTPS to api.osv.dev; no API key |
All five are in the fixed SAST list, so they run on every scan that has a repository, in default and deep mode alike, with or without an LLM key or credentials. The npm scanner and the OSV scanner both query OSV for package.json; a vulnerable npm package can therefore arrive twice, once from each, before triage dedups.
Why this class matters
Your application is mostly other people's code: a typical Next.js app has 500 to 1000 transitive dependencies, and a bug in any of them is your bug. A leaked secret is faster still. A database URL is direct read and write on every row, an AWS key is the account, a Supabase service-role key bypasses every Row Level Security policy. And a secret does not need to be in the current code: if it was ever committed, anyone who clones the repo can run git log -p and read it.
Uber (2016). Engineers committed AWS credentials to a private GitHub repository. Attackers found them, reached an S3 bucket and took 57 million user and driver records. Uber paid the attackers $100K and concealed the breach for over a year. Samsung (2022). GitGuardian researchers found internal source, private keys and AWS credentials in public GitLab repositories.
Equifax (2017). 147 million records stolen through an unpatched Apache Struts dependency (CVE-2017-5638). The patch had been available for two months; the settlements cost $700 million. Log4Shell (2021). CVE-2021-44228 in Log4j allowed remote code execution from a crafted log message and affected hundreds of thousands of applications, including services from Apple, Amazon, Cloudflare and Steam.