Rules
flaw ships 83 rules across two ID ranges. Each lives in its own
folder under rules/
with the detector, fixtures, metadata, and per-rule docs. The
per-rule README for each rule
goes deeper on what, why, and how to fix.
- Security —
FLAW0xx(24 rules) - AI-slop hygiene —
FLAW100–FLAW108 - Design & accessibility
- Cross-language security sinks —
FLAW1xx - CI/CD & GitHub Actions —
FLAW144,FLAW145 - LLM / MCP app security —
FLAW149–FLAW157
Security — FLAW0xx (24 rules)
Real vulnerabilities. Default severity is medium+; designed for
--fail-on high in CI.
| ID | Severity | Flaw |
|---|---|---|
| FLAW001 | critical | Command built from string interpolation |
| FLAW002 | high | Hardcoded secret literal |
| FLAW003 | high | SQL built via interpolation or concatenation |
| FLAW004 | high | Non-cryptographic RNG for security-sensitive value |
| FLAW005 | medium | YAML parsed from untrusted input |
| FLAW006 | high | File access with user-controlled path |
| FLAW007 | medium | Redirect to user-supplied URL without allowlist |
| FLAW008 | high | Deserialization of untrusted data |
| FLAW009 | high | Weak hash (MD5/SHA1) for password or integrity |
| FLAW010 | high | TLS certificate verification disabled |
| FLAW011 | high | Outbound HTTP to user-controlled URL (SSRF) |
| FLAW012 | medium | Secret compared with == (timing attack) |
| FLAW013 | medium | Tempfile created without atomic O_EXCL |
| FLAW014 | high | XML parsed without disabling external entities (XXE) |
| FLAW015 | medium | Privilege field exposed through Serializable |
| FLAW016 | medium | TLS minimum version set to a deprecated protocol |
| FLAW017 | low | Regex with nested quantifiers (ReDoS) |
| FLAW018 | high | Secret-named value written to log or stdout |
| FLAW019 | medium | Cookie without Secure / HttpOnly / SameSite |
| FLAW020 | high | ECB cipher mode used |
| FLAW021 | high | Hardcoded IV / nonce / salt |
| FLAW022 | high | Archive entry extracted without normalization (zip-slip) |
| FLAW023 | critical | JWT with alg:none or verification disabled |
| FLAW024 | high | CORS wildcard / echoed origin with credentials |
AI-slop hygiene — FLAW100–FLAW108
Detect unedited LLM paste-through. Novel territory: no other linter
looks for these. Low/medium severity, meant for --fail-on medium in
CI once the codebase is clean.
| ID | Severity | Flaw |
|---|---|---|
| FLAW100 | low | Explanatory narration comment (“This function does X”) |
| FLAW101 | medium | AI assistant boilerplate in strings or comments |
| FLAW102 | medium | Placeholder value left in source (your-api-key-here) |
| FLAW103 | medium | Unfinished stub (raise NotImplementedError) |
| FLAW104 | low | Broad swallow rescue (rescue Exception; nil) |
| FLAW105 | high | Commented-out authorization / auth check |
| FLAW108 | low | AI-slop marker left in source |
Design & accessibility
Token drift and a11y — these catch regressions in token files,
Tailwind, and semantic HTML. Low/info severity; run on design system
repos with --include-tag design or --include-tag a11y.
| ID | Severity | Flaw |
|---|---|---|
| FLAW106 | low | Raw color literal outside token file |
| FLAW109 | low | Low color contrast (WCAG AA fail) |
| FLAW111 | low | Mixed CSS units within one property family |
| FLAW118 | low | <img> without alt attribute |
| FLAW119 | info | Overuse of !important in stylesheet |
| FLAW120 | low | Positive tabindex breaks tab order |
| FLAW121 | low | Conflicting Tailwind utilities on same element |
| FLAW127 | low | <html> without lang attribute |
| FLAW128 | low | Click handler on non-interactive element |
| FLAW130 | low | Hardcoded font-family outside token file |
Cross-language security sinks — FLAW1xx
Vulnerabilities found in web/JS/Python/YAML/config files beyond Crystal.
Default severity is medium+; --include-tag security if you want to
cut to just these.
| ID | Severity | Flaw |
|---|---|---|
| FLAW107 | low | Hardcoded external URL or IP in source |
| FLAW110 | info | Magic number — name it as a constant |
| FLAW112 | high | Dynamic code execution sink (eval, Function()) |
| FLAW113 | high | DOM XSS sink (innerHTML, document.write) |
| FLAW114 | medium | Insecure http:// download |
| FLAW115 | medium | Permissive file mode (chmod 0777) |
| FLAW116 | high | Unsafe deserialization sink (cross-language) |
| FLAW117 | low | target="_blank" without rel="noopener" |
| FLAW122 | high | Server-side template injection |
| FLAW123 | high | Prototype pollution sink |
| FLAW124 | low | Log injection |
| FLAW125 | medium | TOCTOU race condition |
| FLAW126 | high | Shell execution with string interpolation |
| FLAW129 | low | Inline event-handler attribute (onclick=) |
| FLAW132 | critical | Log4Shell JNDI payload |
| FLAW133 | high | NoSQL injection sink |
| FLAW134 | medium | Debug enabled in production config |
| FLAW135 | medium | PII written to log |
| FLAW136 | medium | Cloud metadata endpoint access |
| FLAW137 | high | Possible provider token literal |
| FLAW138 | high | PowerShell encoded / hidden command |
| FLAW139 | high | Remote script piped to shell (curl \| bash) |
| FLAW140 | high | LOLBIN abuse signature |
| FLAW141 | medium | Large base64 blob (opaque payload) |
| FLAW142 | high | Obfuscated code-execution chain |
| FLAW143 | high | Docker socket mounted into container |
| FLAW146 | high | Kubernetes security boundary disabled |
| FLAW147 | high | Security-group 0.0.0.0/0 ingress |
| FLAW148 | medium | Source map shipped in production artifact |
CI/CD & GitHub Actions — FLAW144, FLAW145
Workflow and supply-chain hazards.
| ID | Severity | Flaw |
|---|---|---|
| FLAW144 | high | pull_request_target + PR-head checkout |
| FLAW145 | high | Unsafe github.event expression in workflow |
LLM / MCP app security — FLAW149–FLAW157
AI-stack footguns. These exist because the LLM-app ecosystem shipped
before the security patterns did. Run with --include-tag security
on any repo that uses an MCP server, builds prompts, or calls an LLM
with user input.
| ID | Severity | Flaw |
|---|---|---|
| FLAW149 | high | Unpinned MCP / agent source |
| FLAW150 | high | Project-local config grants execution |
| FLAW151 | high | User input interpolated into system / assistant role |
| FLAW152 | medium | Tool result appended to prompt without fence |
| FLAW153 | medium | Model output rendered with images enabled |
| FLAW154 | high | Prefix check without canonicalization |
| FLAW155 | medium | User-controlled LLM max_tokens without clamp |
| FLAW156 | high | Tool handler outbound request to non-literal URL |
| FLAW157 | medium | AI-tool project config committed to repo |