Skip to content

Real-world validation report

OAuthLint's whole value rests on low false positives — a security linter that cries wolf gets turned off. This page documents how the full 90-rule pack (v0.2.0) behaves when run against real, popular code across all five supported languages.

Reproduce the raw scan with pnpm validate (clones the targets in scripts/validation-targets.yml and runs the CLI over each). The summary below is from a full-pack scan of the cached corpus.

Method

  • Corpus: 18 widely-used repositories — ~9,400 source files across JavaScript/TypeScript, Python, Go, Java and Rust.
  • Signal classification (from validation-targets.yml):
    • low — mature auth libraries that should be clean. Any finding here is a candidate false positive and is triaged individually.
    • high — auth-heavy / AI-generated apps where real findings are expected.
  • Test/example code is excluded from the false-positive denominator: a library's own test suite legitimately exercises the dangerous APIs it implements.

Headline result

Across 18 repos and ~9,400 files, the pack produced zero false positives on the clean auth libraries. Every finding on a low-signal target resolves to either the library detecting its own primitives in its test suite, or a genuine true positive.

The ten pristine auth libraries below fired zero rules — JS/TS, Python, Go and Rust alike:

LibraryLangFindings
panva/joseJS/TS0
panva/node-openid-clientJS/TS0
jpadilla/pyjwtPython0
lepture/authlibPython0
pallets/flaskPython0
golang/oauth2Go0
gorilla/sessionsGo0
seanmonstar/reqwestRust0
ramosbugs/oauth2-rsRust0
spring-projects/spring-petclinicJava0

Triage of the remaining low-signal findings

These are the only findings on low-signal repos. None is a new false positive:

FindingRepoVerdict
auth.rust.jwt.no-*-validation ×22Keats/jsonwebtokenExcluded — all inside the crate's own #[cfg(test)] module (it implements Validation, so its tests set validate_exp/aud = false). jsonwebtoken is deliberately not a target.
auth.go.jwt.parse-unverified ×1golang-jwt/jwtExcluded — the library's own ParseWithClaims calls ParseUnverified internally before verifying. golang-jwt is the implementer, not a target.
auth.java.web.permit-all ×1spring-projects/spring-securityExcluded — integration-test scaffolding.
auth.flow.timing-unsafe-compare ×2nextauthjs/next-authTrue positive (kept) — a real CSRF-token compare and a Bearer ${CRON_SECRET} compare, both worth constant-time handling.
auth.jwt.no-expiration ×1nextauthjs/next-authTrue positive (kept) — the Dgraph adapter signs a JWT with no exp.

Implementer libraries (jsonwebtoken, golang-jwt) are excluded by design — they ship and test the very primitives the rules flag. See the notes in validation-targets.yml.

The pack still finds real things

On high-signal apps the rules surface genuine, actionable findings — e.g. on directus/directus: auth.oauth.open-redirect-callback in its OAuth2/OIDC drivers, auth.jwt.decode-without-verify, and auth.flow.timing-unsafe-compare. Low false positives, not low recall.

Why this matters

This is the discipline the generic Semgrep registry does not apply to the auth domain: every rule is tuned against real library source so it fires on your bug, not on jose's internals. It is invisible, tedious work — and it is the product.

Last updated:

Released under the MIT License · powered by Semgrep