Scanner group

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.

5 scanners5 SAST · 0 DASTCritical–LowExposed Secrets · Dependency Vulnerability

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.

Repository snapshot shallow clone, key files indexed package.json requirements.txt pyproject.toml pom.xml · gradle go.mod .env · *.pem · *.key .git history node_modules, dist, .git are never indexed as code Extract name@version lodash ^4.17.15 → 4.17.15 PyJWT==2.3.0 → pyjwt log4j-core 2.14.1 Look the version up built-in table (Python, Java) pyjwt: <2.4.0 → CRITICAL OSV.dev API (npm, OSV) POST /v1/querybatch Dependency finding pyjwt==2.3.0 CRITICAL CVE-2022-29217 · line 3 confidence 0.85 table · 0.95 OSV Match 13 secret patterns pass 1: every file at HEAD · pass 2: added lines of up to 500 commits · pass 3: file names sk_live_[a-zA-Z0-9]{24,} AKIA[0-9A-Z]{16} -----BEGIN (RSA |EC |DSA |OPENSSH |ENCRYPTED |PGP )?PRIVATE KEY( BLOCK)?----- postgres(ql)/mysql/mongodb(+srv)://user:pass@ · ghp_ · AIza · SG. · eyJ (service_role) Secret finding sk_live_5***3def CRITICAL · commit abc123 still at HEAD? no confidence 0.90

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

At a glance

ScannerWhat it looks atWhat it reportsSeverity rangeNeeds
Git secrets
git_secret_scanner
Every indexed file at HEAD; added lines of up to 500 file-adding commits (git log --all -p); file names in history13 secret patterns (Stripe, AWS, GitHub, OpenAI, Anthropic, DB URLs, Firebase, SendGrid, Twilio, private keys, JWT-shaped Supabase keys); 5 sensitive file namesCritical–HighRepository with a .git directory; no network
npm dependencies
dependency_scanner
package.json at the root and in each workspace: dependencies + devDependencies, first 200 packagesOne finding per OSV vulnerability for the cleaned version; severity from the OSV label, else a computed CVSS v3 score, default MediumCritical–LowRepository; outbound HTTPS to api.osv.dev; no API key
Python dependencies
python_dependency_scanner
requirements.txt, pyproject.toml [project.dependencies]13-package built-in table with <X.Y.Z ranges; unpinned lines in requirements.txtCritical–LowRepository only
Java dependencies
java_dependency_scanner
pom.xml <dependency> blocks; build.gradle / .kts declarations12-coordinate built-in table (Log4j, Struts, Spring, Jackson, JJWT, Commons, Guava, Tomcat, MySQL)Critical–MediumRepository only
OSV dependencies
osv_dependency_scanner
package.json, requirements.txt, pyproject.toml, pom.xml, build.gradle(.kts), go.modOne finding per (package, version, vuln id) from OSV.dev, with CVE alias, fixed version and osv.dev link; default MediumCritical–LowRepository; outbound HTTPS to api.osv.dev; no API key
Who runs when

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

Why it 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.

Real-world breach · secrets

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.

Real-world breach · dependencies

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.