What RepoGuard checks for
Every detection rule that runs against your repo. Open source, with CWE mapping and a plain-language description on each. Use the layer grouping below to see how each finding gets to your dashboard.
SARIF export → upload findings to GitHub Code Scanning
AST28 rules
TypeScript Compiler API walkers. Detect user input flowing into dangerous sinks across hops the regex layer can't see.
Command injection: child_process exec/spawn called with user input
criticalast/command-injection-user-input
A call to one of child_process.{exec,execSync,execFile,execFileSync,spawn,spawnSync,fork} receives a first argument that interpolates or concatenates a value sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. Shell metacharacters in user input become command execution. Detected via AST: requires both the child_process call shape AND the user-input expression in the same call argument, so false positives on lookalike function names are unlikely.
Dynamic eval / new Function called with user-controlled string
criticalast/eval-user-input
eval() or `new Function(...)` was called with an argument that interpolates or concatenates a value sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. The user controls JavaScript that the server then executes — arbitrary code execution. Refactor to parse the input with a structured schema (JSON.parse with validation, or a real expression parser) and act on it via a dispatch map.
Hardcoded admin credentials: equality check against literal placeholder username + password
criticalast/hardcoded-admin-credentials
An equality check compares a username-shaped identifier (username / user / login / email / account) to a literal admin-shaped name ('admin' / 'root' / 'administrator' / 'superuser' / 'guest' / 'test'), AND/OR compares a password-shaped identifier (password / pwd / pass / passwd) to a placeholder literal ('admin' / 'password' / '123456' / 'changeme' / etc). These patterns ship as demo logins and then never get replaced. Move credentials to env vars and rotate the placeholder values now.
Hardcoded encryption key passed to createCipheriv
criticalast/hardcoded-encryption-key
crypto.createCipheriv / createDecipheriv was called with a string-literal key. Any reader of the repo can decrypt all data ever encrypted with it. Move the key to process.env and rotate every value already encrypted under the committed key (you cannot recover from this incident by changing the source file alone — the leaked key remains valid on existing ciphertext). For new code use crypto.randomBytes(32) at deploy time and store the hex in your secret manager.
JWT signed with a hardcoded string secret
criticalast/jwt-sign-hardcoded-secret
jwt.sign(payload, '<string literal>') was called with the signing secret hard-coded into the source. Any reader of the repo (or the bundled JS in browser dev tools) can forge tokens. Load the secret from process.env at runtime, and rotate it the moment any committed-secret leak is suspected.
Insecure randomness: Math.random() used to generate a security token
criticalast/math-random-for-security-token
Math.random() is a pseudo-random number generator with predictable state — V8 uses xorshift128+, and a handful of observed outputs lets an attacker reproduce the entire stream. Using it for a token / session / csrf / nonce / salt / api-key / reset-token / otp / uuid means the value is forgeable. Use crypto.randomBytes(N).toString('hex') in Node, or crypto.getRandomValues(new Uint8Array(N)) in the browser / edge runtime. For uuids specifically use crypto.randomUUID().
NoSQL injection: $where operator with user-controlled value
criticalast/nosql-injection-where-user-input
A MongoDB query passes `$where` with a value sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. The Mongo server evaluates `$where` as JavaScript, so the attacker controls server-side code: `this.password.match(/^a.*/)` style payloads exfiltrate other users' fields one char at a time. Replace `$where` with declarative operators (`$regex`, `$eq`, `$in`) and validate the user input first, or drop `$where` support entirely on this collection.
Path traversal: fs API called with user-controlled path
criticalast/path-traversal-fs
A Node.js fs.* call receives a path argument that is, or is derived from, a value sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. Even when wrapped in path.join(__dirname, ...), the user-controlled segment can include `../` and escape the intended directory. Use a strict allow-list of filenames or join with a sanitised basename instead.
React XSS: dangerouslySetInnerHTML fed user-controlled HTML
criticalast/react-dangerously-set-inner-html-user-input
A React component sets dangerouslySetInnerHTML with __html sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. React intentionally skips its escaping for this attribute, so any HTML in the input — including <script> — executes in the browser. Either render the content as text (drop dangerouslySetInnerHTML), or pass it through a HTML sanitiser (DOMPurify) before assigning.
SQL injection via template literal interpolating user input
criticalast/sql-injection-template
A query/execute/raw/run call receives a tagged template literal that interpolates a value sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. Interpolating raw user input into SQL is the textbook injection vector — use parameterised queries instead. Detected via AST: false positives are rare because we require both the SQL-call shape AND the user-input expression in the same call site.
SSRF: HTTP client called with user-controlled URL
criticalast/ssrf-http-user-url
fetch / axios / http / got / superagent / needle / ky / undici was called with a URL sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. An attacker can redirect the request to internal-only endpoints (AWS metadata service at 169.254.169.254, internal microservices, Docker socket) and exfiltrate the response. Validate the URL against an allow-list of hosts before issuing the request.
Server-side template injection: template engine compiled / rendered with user input
criticalast/template-injection-user-input
Handlebars / Pug / EJS / Mustache / Nunjucks compile() or render() was called with a template string sourced from user input. These engines parse `{{...}}` (Handlebars/Mustache), `#{...}` / `!=` (Pug), or `<%-%>` (EJS) and execute helper expressions inside — most engines reach JavaScript eval via the prototype chain or escape filters, giving the attacker remote code execution. Render with FIXED templates, never the user's template body; let the user only fill the data slots.
CORS misconfiguration: credentials enabled with permissive origin
highast/cors-credentials-with-any-origin
A `cors(...)` config sets origin to '*' or `true` while also enabling `credentials: true`. Even if the browser blocks the exact spec violation, the deployment is one config drift away from echoing the request Origin header back as Access-Control-Allow-Origin — at which point any site can read authenticated responses. Set an explicit origin allow-list (`origin: ['https://app.example.com']`) or a function that validates against one.
Insecure cookie: httpOnly and/or secure not explicitly set to true
highast/insecure-cookie-set
res.cookie / ctx.cookie was called without options, OR with httpOnly: false or secure: false. Express defaults both to false — that means the cookie is readable by JavaScript on the page (cookie-stealing XSS becomes session takeover) and travels over plain HTTP (cookie sniffable on a coffee-shop Wi-Fi). Pass `{ httpOnly: true, secure: true, sameSite: 'lax' }` (or 'strict' if you can). In dev where HTTPS isn't set up, gate `secure` on process.env.NODE_ENV.
Insecure session configuration: hardcoded secret or cookie security off
highast/insecure-session-config
A session() / cookieSession() / expressSession() factory was called with one of: a string-literal `secret` (hardcoded — any reader of the repo can forge session cookies), `cookie.httpOnly: false` (JavaScript on the page can read the cookie), or `cookie.secure: false` (cookie travels over plain HTTP). Load the secret from process.env, and set httpOnly and secure to true in production.
WebSocket opened over cleartext ws:// instead of wss://
highast/insecure-websocket-protocol
new WebSocket("ws://...") opens an unencrypted connection. Any cookie sent during the handshake, every message body, and any token in the URL travels in cleartext — trivially readable on shared Wi-Fi, hotel networks, or anywhere a network device sees the bytes. Switch to wss:// and terminate TLS at the same gateway as your HTTPS traffic. For local development behind localhost, gate the protocol on process.env.NODE_ENV so production code paths never reach the ws:// branch.
JWT decoded without signature verification
highast/jwt-decode-without-verify
jwt.decode(token) (or jsonwebtoken.decode) parses the JWT payload without checking the signature. An attacker can craft a token with arbitrary claims (`{ "sub": "admin" }`) and your code will trust it. If you're authenticating the user from the decoded payload, switch to jwt.verify(token, secret, options) — that throws on a bad signature. Reserve .decode strictly for non-trust use cases like reading metadata before deciding which secret to verify with.
JWT signed without expiresIn — token lives forever
highast/jwt-sign-no-expires-in
jwt.sign(payload, secret) was called without an `expiresIn` option (or with no options object at all). A JWT without expiry stays valid until the secret is rotated — a compromised token has no natural decay. Pass `{ expiresIn: '15m' }` (or your chosen window) as the third argument. Refresh-token flows should use short access tokens explicitly.
Logging: credential-named value passed to console / logger
highast/log-credential-disclosure
A console / logger call carries an argument whose identifier or property name is one of: password / token / secret / apiKey / accessToken / refreshToken / jwt / privateKey / authorization / credentials. Vercel / Datadog / CloudWatch logs are often broader-access than the app itself, and committed credentials in log lines are a frequent breach vector. Redact before logging (or just don't log the value — log `{ userId }` instead of `{ password }`).
Open redirect: response.redirect called with user-controlled URL
highast/open-redirect-user-url
A redirect target was sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. Attackers craft links like /login?next=https://evil.example.com that bounce the victim through your trusted domain and into a phishing page. Validate the redirect target against an allow-list of paths or hosts before issuing the redirect — for relative paths, also check the value starts with '/' but NOT '//' (protocol-relative).
Prototype pollution: deep merge / assign with user-controlled object
highast/prototype-pollution-merge-user-input
A deep-merge function (lodash.merge / .mergeWith / .defaultsDeep / .set / .setWith) was called with a source object sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. An attacker payload `{ "__proto__": { "isAdmin": true } }` pollutes Object.prototype globally on most lodash versions. Either upgrade to a patched version (lodash >= 4.17.20 with prototype-traversal disabled by default), validate the payload shape with Zod / Joi BEFORE merging, or use `Object.create(null)` as the target so the prototype chain isn't reachable.
ReDoS: RegExp constructed from user-controlled string
highast/redos-dynamic-regexp-user-input
`new RegExp(<user input>)` (or `RegExp(<user input>)`) compiles a regex pattern under attacker control. Crafted nested quantifiers like `(a+)+$` cause catastrophic backtracking that hangs the Node event loop, denying service to other requests on the same instance. On serverless this also burns billed CPU. Either accept only an allow-list of patterns, escape the input to treat it as a literal (replace special chars), or wrap the .match/.test call with a timeout (e.g. via worker thread).
Reflected XSS: response body sourced from user input
highast/reflected-xss-via-res-send
res.send / res.write / res.end was called with a body sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. Express infers Content-Type: text/html when the body is a string — any <script> in the user input runs in the visitor's browser. Either send via res.json (sets Content-Type: application/json, which the browser will NOT parse as HTML), escape the input through a HTML-encoder before sending, or set Content-Type: text/plain explicitly.
Timing attack: credential compared with == / === instead of constant-time compare
highast/timing-unsafe-credential-compare
A `===` or `==` comparison was used against an identifier or property named like a credential (password / token / secret / signature / hmac / apiKey / csrf / etc). JavaScript string equality short-circuits on the first differing character — an attacker measuring response time can deduce the secret one byte at a time. Use `crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b))` (after equal-length check) or a library helper like `@noble/hashes/utils.equalBytes`.
Weak crypto: createCipher() or ECB mode
highast/weak-cipher-mode-or-deprecated-api
crypto.createCipher() is deprecated since Node 10 — it derives the key from a password via EVP_BytesToKey with weak parameters and uses a zeroed IV, so two encryptions of the same plaintext are identical. Use crypto.createCipheriv() with a key from crypto.randomBytes and a fresh IV per message. Separately: createCipheriv('aes-???-ecb', ...) — ECB mode encrypts each block independently, so repeating plaintext blocks (e.g. fixed JSON structure) produce repeating ciphertext blocks — visually obvious in the famous Tux penguin demo. Use GCM or CBC with HMAC instead.
Weak crypto: MD5 / SHA-1 used for security-sensitive hashing
highast/weak-crypto-hash-for-secrets
Node crypto.createHash() was called with a broken algorithm (md5 / sha1 / md4 / md2 / sha-224) and the hashed value carries a security-related identifier (password / token / secret / session / api_key / etc). These algorithms have no preimage or collision resistance for the security use cases people most often grab them for. For password storage use bcrypt/scrypt/argon2; for tokens use a CSPRNG output via crypto.randomBytes; for HMAC use SHA-256+. If the use case is non-security (file content hash, cache key) suppress via .repoguardignore.
CORS misconfiguration: Access-Control-Allow-Origin set to '*' via response header
highast/wildcard-cors-via-set-header
res.setHeader / res.set / res.header / ctx.set was called to assign Access-Control-Allow-Origin: '*'. Combined with any cookie-bearing endpoint this lets any web origin issue authenticated requests against your API and read the response. AI assistants reach for this when asked to 'fix CORS' without using the cors package. Replace with an explicit allow-list of origins, validated per request.
XML parser configured to expand external entities (XXE)
highast/xxe-xml-parser-external-entities
An XML parser was constructed (or invoked) with an option that lets the parser fetch external DTDs / expand external entities — `allowDtd: true` (fast-xml-parser), `noent: true` / `dtdload: true` / `external: true` (libxmljs / xml2js). A crafted payload like `<!DOCTYPE x [<!ENTITY a SYSTEM "file:///etc/passwd">]>` then reads server files into the response. Default-deny: leave the flag at its safe default, and only enable when consuming XML from a fully trusted source. For libxmljs, prefer `parseXml(buf, { noent: false, nonet: true })`.
Code regex34 rules
High-confidence single-line regex rules — fast, language-tagged, tied to a CWE. Bias toward few false positives over coverage.
Command Injection: shell exec with user-controlled argument
criticalcode/js-command-injection
child_process.exec/execSync/spawn runs a shell command that includes untrusted input. Use execFile with an argv array instead.
JWT verified with 'none' algorithm
criticalcode/js-jwt-none-algorithm
Allowing the 'none' algorithm lets any caller forge tokens. Pin a specific algorithm list like ['HS256'] or ['RS256'].
SQL Injection: query built with + string concatenation
criticalcode/js-sqli-string-concat
SQL string is concatenated with a variable. Use parameterized queries (?, $1) or a query builder instead.
SQL Injection: template literal with interpolation
criticalcode/js-sqli-template-literal
SQL is built via a template literal with ${var} interpolation, which is equivalent to string concatenation. Use parameter binding.
SSRF: HTTP client called with user-controlled URL
criticalcode/js-ssrf-fetch-user-input
A request library is invoked with a URL derived from the HTTP request. Attackers can redirect the request to internal metadata endpoints (e.g. AWS 169.254.169.254) or internal services.
Command Injection: subprocess/os.system with shell=True
criticalcode/py-command-injection
subprocess called with shell=True on a string that includes user input allows arbitrary command execution. Pass argv as a list and leave shell=False (default).
Command Injection: os.system with string interpolation
criticalcode/py-os-system
os.system passes its argument to /bin/sh -c. Any interpolated variable becomes a potential injection.
Insecure deserialization: pickle.loads on untrusted data
criticalcode/py-pickle-loads
pickle.loads executes arbitrary code during deserialization. Never use it on data that could be user-controlled.
SQL Injection: Python f-string/format interpolation in query
criticalcode/py-sqli-f-string
SQL query is built via f-string/format/% — both equivalent to string concatenation. Use parameterized queries (cursor.execute(sql, (x,))).
SSRF: requests library called with user-controlled URL
criticalcode/py-ssrf-requests-user-input
A Python HTTP client is called with a URL derived from Flask/Django/FastAPI request data.
SSRF: urllib.request.urlopen with user input
criticalcode/py-urllib-ssrf
urllib.request.urlopen resolves arbitrary schemes (file://, ftp://) and is rarely the right primitive for user-supplied URLs.
Cookie set with httpOnly: false in auth context
highcode/js-cookie-httponly-false
Auth/session cookies should always be HttpOnly so client-side scripts can't read them, eliminating cookie-stealing XSS. AI-generated cookie middleware often omits httpOnly or sets it to false to enable client JS reads.
CORS: wildcard origin with credentials allowed
highcode/js-cors-wildcard-credentials
Access-Control-Allow-Origin: * combined with Access-Control-Allow-Credentials: true is insecure (and ignored by browsers, usually silently). Use an explicit origin list.
process.env fallback to a hardcoded secret-shaped string
highcode/js-env-fallback-secret
`process.env.FOO || "sk-..."` makes the fallback string a hardcoded credential committed to the repo. AI assistants frequently emit this pattern so the snippet 'works' without an env var — and it then ships to prod.
Use of eval() with dynamic input
highcode/js-eval
eval() executes arbitrary code. If the argument is influenced by user input, this is RCE. Avoid eval entirely.
JWT decoded without verification
highcode/js-jwt-decode-instead-of-verify
jwt.decode() does NOT verify the signature — callers often mistake it for authentication. Use jwt.verify with the signing key.
new Function() constructor with dynamic body
highcode/js-new-function
new Function(...) is eval by another name and executes whatever string is passed in.
NEXT_PUBLIC_ env var with a secret-like name
highcode/js-next-public-secret-name
Any env var prefixed NEXT_PUBLIC_ is inlined into the client bundle at build time and visible to every visitor. Naming one *SECRET*, *KEY*, *TOKEN*, *PASSWORD* (other than well-known public keys like Stripe pk_*) almost certainly leaks a credential. AI assistants confuse client-side and server-side env in Next.js routinely.
Path Traversal: fs read with user-controlled path
highcode/js-path-traversal
fs.readFile/createReadStream with a user-derived path can read arbitrary files (../../etc/passwd). Resolve against a fixed root and verify with path.resolve + startsWith.
TLS certificate verification disabled
highcode/js-tls-verify-disabled
rejectUnauthorized: false disables TLS certificate validation, breaking the trust chain and exposing the connection to MitM attacks. Common when AI assistants suggest 'fixes' for self-signed cert errors — the right fix is to add the CA to the trust store, not to disable validation.
XSS: document.write called with a variable
highcode/js-xss-document-write
document.write with untrusted data injects script into the page. Avoid entirely in modern code.
XSS: innerHTML assigned from a variable
highcode/js-xss-innerhtml
Setting .innerHTML with a non-literal string allows script injection. Use textContent or a sanitizer (DOMPurify).
XSS: dangerouslySetInnerHTML with non-constant value
highcode/js-xss-react-dangerously
React's dangerouslySetInnerHTML renders raw HTML. Only pass pre-sanitized (e.g. DOMPurify) or statically-known HTML strings.
Python eval()/exec() with dynamic input
highcode/py-eval-exec
eval/exec run arbitrary Python. Treat as RCE if the input is untrusted.
Path Traversal: open() with user-controlled path
highcode/py-path-traversal
open() with a path derived from request data can read arbitrary files. Resolve via os.path.realpath and verify it stays in an allowlisted root.
TLS verification disabled in HTTP client
highcode/py-tls-verify-disabled
Passing verify=False to requests/httpx skips certificate validation and exposes the call to MitM. Configure the CA bundle (REQUESTS_CA_BUNDLE / verify='/path/to/ca.pem') instead.
Insecure deserialization: yaml.load without SafeLoader
highcode/py-yaml-load
yaml.load (without Loader=SafeLoader) deserializes Python objects and can execute code. Use yaml.safe_load.
bcrypt cost factor below 10
mediumcode/js-bcrypt-low-rounds
bcrypt.hash(..., N) with N below 10 makes offline password cracking cheap. Use at least 10 (current OWASP recommendation is 12+). AI-generated examples often default to 4 or 8 for 'speed'.
Session cookie with secure: false
mediumcode/js-cookie-insecure-prod
secure: false sends the cookie over plain HTTP, making it interceptable on any shared network. Production session cookies must be `secure: true` so they ride only over TLS.
Insecure randomness: Math.random() in security context
mediumcode/js-insecure-random
Math.random() is not cryptographically secure. For tokens/session IDs use crypto.randomBytes or crypto.randomUUID.
Open redirect: res.redirect with user-controlled URL
mediumcode/js-open-redirect
Redirecting to a URL derived from the request allows attackers to craft phishing links that look genuine. Validate against an allowlist or relative paths only.
Weak hashing: MD5/SHA1 used in auth/password context
mediumcode/js-weak-hash-password
MD5 and SHA1 are unsuitable for password hashing or tokens. Use bcrypt/argon2/scrypt for passwords, HMAC-SHA256 for tokens.
Insecure randomness: random module used for security token
mediumcode/py-insecure-random
Python's random module is not cryptographically secure. Use secrets.token_* for tokens and secrets.choice for sampling.
Weak hashing: hashlib.md5/sha1 used in auth context
mediumcode/py-weak-hash-password
hashlib.md5/sha1 for passwords or tokens is insecure. Use argon2-cffi/bcrypt/passlib for passwords.
Secret pattern80 rules
Curated patterns for common credential formats: cloud keys, OAuth tokens, payment provider keys, database URIs. Plus an entropy fallback for env-shaped values.
Adyen API Key
criticalsecret/adyen-api-key
Adyen payments API key.
Algolia Admin API Key
criticalsecret/algolia-admin-key
Algolia admin API key (full control over indices).
Anthropic API Key
criticalsecret/anthropic-api-key
Anthropic (Claude) API key. Incurs usage charges and grants model access.
AWS Access Key ID
criticalsecret/aws-access-key
Amazon Web Services access key. Grants programmatic access to AWS resources.
AWS Secret Access Key
criticalsecret/aws-secret-key
AWS secret key paired with an access key ID. Full compromise if leaked.
AWS Session Token
criticalsecret/aws-session-token
Short-lived STS session token. High value while active.
Azure AD Client Secret
criticalsecret/azure-client-secret
Azure Active Directory application client secret.
Azure Storage Account Key
criticalsecret/azure-storage-key
Azure Storage account primary/secondary key. Grants full access to blobs/tables/queues.
Cloudflare API Token
criticalsecret/cloudflare-api-token
Cloudflare scoped API token. Can modify DNS, firewall, workers.
DigitalOcean OAuth Token
criticalsecret/digitalocean-oauth
DigitalOcean OAuth access/refresh token.
DigitalOcean Personal Access Token
criticalsecret/digitalocean-token
DigitalOcean API token. Full control over droplets, databases, Spaces.
Docker Hub Personal Access Token
criticalsecret/docker-hub-pat
Docker Hub PAT. Can push images to any repo the user owns.
Fly.io API Token
criticalsecret/flyio-token
Fly.io access token. Full org/app control.
GCP Service Account Private Key
criticalsecret/gcp-service-account
Google Cloud service account JSON private key. Often grants broad project access.
GitHub Fine-Grained Token
criticalsecret/github-fine-grained-pat
Newer GitHub token with scoped permissions.
GitHub OAuth Access Token
criticalsecret/github-oauth
OAuth access token issued by GitHub (user-to-server).
GitHub Personal Access Token (classic)
criticalsecret/github-pat
Classic GitHub token granting repo, user, and potentially admin access.
GitHub Refresh Token
criticalsecret/github-refresh
GitHub OAuth refresh token.
GitHub Server-to-Server Token
criticalsecret/github-server-to-server
GitHub App installation token. Short-lived but highly privileged.
GitHub User-to-Server Token
criticalsecret/github-user-to-server
GitHub App user access token.
GitLab Personal Access Token
criticalsecret/gitlab-pat
GitLab PAT. Scopes may include api/write_repository/admin.
HashiCorp Vault Token
criticalsecret/hashicorp-vault-token
Vault auth token. Potential access to managed secrets.
Heroku API Key
criticalsecret/heroku-api-key
Heroku platform API key. Can deploy code and access add-on data.
Netlify Personal Access Token
criticalsecret/netlify-token
Netlify PAT. Full account access for sites, builds, team.
npm Access Token
criticalsecret/npm-access-token
npm granular/automation access token (publishing supply-chain risk).
.npmrc _authToken
criticalsecret/npmrc-authtoken
npm registry auth token inside .npmrc — often grants publish rights.
Okta API Token
criticalsecret/okta-api-token
Okta administrative API token.
OpenAI API Key
criticalsecret/openai-api-key
OpenAI API key. Can incur significant usage charges.
OpenAI API Key (legacy)
criticalsecret/openai-legacy-key
Legacy OpenAI API key format.
Braintree (PayPal) Access Token
criticalsecret/paypal-braintree-token
Braintree production access token.
Plaid Secret
criticalsecret/plaid-secret
Plaid API secret (production can initiate real financial data access).
Private Key (RSA / SSH / PGP / EC)
criticalsecret/private-key
Private cryptographic key material. Should never be committed.
PyPI API Token
criticalsecret/pypi-token
PyPI upload token (publishing supply-chain risk).
.pypirc Password
criticalsecret/pypirc-password
PyPI credentials in .pypirc — publish token or password.
Shopify Access Token
criticalsecret/shopify-access-token
Shopify Admin API access token.
Square Access Token
criticalsecret/square-access-token
Square production OAuth access token.
Stripe Live Secret Key
criticalsecret/stripe-live-secret
Stripe production secret key. Can charge real cards.
Stripe Restricted Live Key
criticalsecret/stripe-restricted-live
Stripe restricted key (rk_live_).
Supabase Service Role Key
criticalsecret/supabase-service-role
Supabase service_role JWT — bypasses Row-Level Security.
Terraform Cloud API Token
criticalsecret/terraform-cloud-token
Terraform Cloud user/team API token. Can apply infra changes.
Vercel API Token
criticalsecret/vercel-token
Vercel personal access token. Can deploy and read env vars.
Asana Personal Access Token
highsecret/asana-token
Asana PAT.
HTTP Basic Auth in URL
highsecret/basic-auth-url
HTTP(S) URL with embedded username:password Basic Auth.
Bitbucket App Password
highsecret/bitbucket-app-password
Bitbucket app password (ATBB-prefixed).
CircleCI Personal Token
highsecret/circleci-token
CircleCI API personal token.
Datadog API Key
highsecret/datadog-api-key
Datadog API key (32-char hex).
Datadog Application Key
highsecret/datadog-app-key
Datadog application key (40-char hex).
Discord Bot Token
highsecret/discord-bot-token
Discord bot token.
Dropbox Access Token
highsecret/dropbox-token
Dropbox OAuth 2 access token.
Google Cloud / Firebase API Key
highsecret/gcp-api-key
Google Cloud / Firebase API key. Can incur usage costs and expose data.
Google OAuth Client ID + Secret
highsecret/gcp-oauth-client-id
Google OAuth client credentials for server-to-server flows.
GitLab Runner Registration Token
highsecret/gitlab-runner-token
GitLab CI runner registration token.
Groq API Key
highsecret/groq-api-key
Groq Cloud inference API key.
HubSpot Private App Token
highsecret/hubspot-api-key
HubSpot private app access token.
Hugging Face Access Token
highsecret/huggingface-token
Hugging Face user access token. Can read private models/datasets.
Intercom Access Token
highsecret/intercom-access-token
Intercom access token.
JFrog Access Token
highsecret/jfrog-access-token
JFrog Artifactory access token.
Linear API Key
highsecret/linear-api-key
Linear.app API key.
Mailchimp API Key
highsecret/mailchimp-key
Mailchimp API key.
Mailgun API Key
highsecret/mailgun-key
Mailgun API key.
New Relic License Key
highsecret/newrelic-license
New Relic ingest license key (INSERT or USER).
PagerDuty API Key
highsecret/pagerduty-key
PagerDuty REST API key.
Password in Connection String
highsecret/password-in-url
Database or service URL with embedded password.
Perplexity API Key
highsecret/perplexity-api-key
Perplexity.ai API key.
Postmark Server Token
highsecret/postmark-token
Postmark server API token.
Render API Key
highsecret/render-api-key
Render platform API key.
Replicate API Token
highsecret/replicate-api-token
Replicate.com API token for model inference.
SendGrid API Key
highsecret/sendgrid-key
SendGrid email API key.
Shopify Shared Secret
highsecret/shopify-shared-secret
Shopify app shared secret.
Slack Token
highsecret/slack-token
Slack bot, user, or workspace token (xoxb/xoxp/xoxa/xoxr/xoxs).
Telegram Bot Token
highsecret/telegram-bot-token
Telegram Bot API token.
Twilio API Key
highsecret/twilio-api-key
Twilio API key SID.
Discord Webhook URL
mediumsecret/discord-webhook
Discord webhook URL.
JSON Web Token (JWT)
mediumsecret/jwt
Possible JWT. May or may not be sensitive depending on contents.
Segment Write Key
mediumsecret/segment-write-key
Segment.com source write key.
Sentry DSN (with secret)
mediumsecret/sentry-dsn
Sentry DSN containing a secret key (legacy format).
Slack Webhook URL
mediumsecret/slack-webhook
Slack incoming webhook. Allows posting to channels anonymously.
Stripe Test Secret Key
mediumsecret/stripe-test-secret
Stripe test key. Lower risk but still should not be public.
Twilio Account SID
mediumsecret/twilio-account-sid
Twilio account SID (paired with auth token elsewhere).
Stripe Publishable Live Key
lowsecret/stripe-publishable-live
Stripe publishable key — meant to be public, but flagged for inventory.
Sensitive file18 rules
Files that should never be committed (.pem, .env, .pfx, .keystore, database dumps). Detected by path / extension / content header, not regex over content.
AWS credentials file
criticalsensitive-file/aws-credentials
AWS shared credentials file (~/.aws/credentials). Typically holds one or more named profiles with access/secret keys.
Database dump
criticalsensitive-file/database-dump
Database dump file (SQL dump, .dump, compressed SQL). May contain PII, hashed passwords, and business data.
Docker auth config
criticalsensitive-file/docker-config
Docker CLI auth config containing base64-encoded registry credentials.
Production .env file
criticalsensitive-file/env-production
Production environment variable file. Typically contains DB credentials, API keys, and signing secrets.
GCP service-account key
criticalsensitive-file/gcp-service-account
Google Cloud service-account JSON key. Usually grants broad, long-lived project access.
git-credentials file
criticalsensitive-file/git-credentials
Git credential store (plain-text usernames/passwords/tokens for remotes).
KeePass database
criticalsensitive-file/keepass
KeePass password database file (.kdbx).
Keystore / certificate bundle
criticalsensitive-file/keystore
Binary key/certificate container (.pfx/.p12/.jks/.keystore). Usually holds private keys plus a password.
Kubernetes kubeconfig
criticalsensitive-file/kubeconfig
Kubernetes kubeconfig file with embedded cluster CA, user tokens, and/or client certs.
Private key file
criticalsensitive-file/private-key
Private cryptographic key file (.pem/.key). Should never be committed — used to sign tokens, authenticate to TLS endpoints, or decrypt data.
SSH private key
criticalsensitive-file/ssh-key
SSH private key (id_rsa/id_ed25519/id_ecdsa/id_dsa). Grants direct access to any host trusting the corresponding public key.
Terraform state
criticalsensitive-file/terraform-state
Terraform state files often contain decrypted secrets (DB passwords, IAM keys) alongside infra metadata.
Environment file (.env)
highsensitive-file/env-generic
Generic .env file. Commonly holds secrets; even dev .env files often leak into real infrastructure.
.htpasswd file
highsensitive-file/htpasswd
Apache/nginx basic-auth file with hashed user passwords. Easy to brute-force if the hash is MD5/SHA1.
.npmrc with auth
highsensitive-file/npmrc-auth
Commit of .npmrc — this file often contains `_authToken` granting publish rights on npm.
PostgreSQL .pgpass
highsensitive-file/pgpass
PostgreSQL credential cache (.pgpass). Plain-text host:port:db:user:password lines.
.pypirc with auth
highsensitive-file/pypirc-auth
.pypirc typically stores PyPI upload credentials or tokens (publishing supply-chain risk).
Backup file
mediumsensitive-file/backup
Backup file (.bak/.backup/.old). Often a snapshot of production state including secrets.
Dockerfile8 rules
Dockerfile hygiene checks: USER root, latest tags, ADD instead of COPY, unsafe shell escapes.
RUN pipes remote script to shell
highiac/dockerfile/dockerfile-curl-pipe-sh
curl|bash during image build downloads unverified code and executes it. Common malware-insertion vector.
Secret baked into ENV layer
highiac/dockerfile/dockerfile-secret-in-env
Values like API_KEY, TOKEN, PASSWORD, SECRET passed via ENV are stored in the image layer history and readable by anyone who pulls the image.
ADD from remote URL
mediumiac/dockerfile/dockerfile-add-url
ADD with an HTTP(S) URL executes without verifying integrity and leaves the downloaded content unpinned. Prefer RUN curl/wget with explicit checksum verification.
Container runs as root
mediumiac/dockerfile/dockerfile-user-root
No USER directive found, so the container's entrypoint runs as UID 0. Any container escape or mounted-volume bug becomes root-equivalent on the host kernel.
Container explicitly runs as root
mediumiac/dockerfile/dockerfile-user-root-explicit
USER is set to root (UID 0). Drop privileges with USER <non-root> after any root-only steps (apt install, etc.).
apt install without version pinning
lowiac/dockerfile/dockerfile-apt-noconfirm-no-pin
apt-get install without specific versions makes builds non-reproducible and can pick up vulnerable packages silently between builds.
World-writable files created
lowiac/dockerfile/dockerfile-chmod-777
chmod 777 grants read/write/execute to any user in the container. Usually a symptom of misunderstanding Unix permissions rather than a real requirement.
Base image pinned to :latest
lowiac/dockerfile/dockerfile-latest-tag
Using :latest (or no tag) means builds are non-reproducible and new vulnerabilities silently enter the image.
GitHub Actions4 rules
GitHub Actions workflow checks: pull_request_target with PR checkout, third-party actions pinned by tag instead of SHA, secrets in expressions.
pull_request_target checks out untrusted PR code
criticaliac/actions/gha-pull-request-target-checkout-head
pull_request_target runs with repository secrets available. Checking out the PR head (github.event.pull_request.head.sha / head.ref / github.head_ref) under this trigger executes attacker-controlled code with write access and exposes all secrets — the root cause of the GhostAction / s1ngularity wave of breaches.
Shell step interpolates GitHub event data
highiac/actions/gha-script-injection
`run:` steps that embed ${{ github.event.* }} values (issue titles, PR bodies, commit messages) expand before the shell parses them — anything an attacker can put in the field becomes shell code.
Workflow grants write-all permissions
mediumiac/actions/gha-permissions-write-all
`permissions: write-all` (or the older default where no `permissions:` block is set) gives GITHUB_TOKEN full repo write access for every step, including any compromised action.
Third-party action not pinned to a commit SHA
mediumiac/actions/gha-unpinned-action
`uses: someone/action@main` (or @master / @v1) fetches whatever the maintainer's branch points at today. A compromised maintainer can replace the code without notice. Pin to a full 40-char commit SHA.
Want a rule we don't have? Open an issue on GitHub.