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.

  1. Security — FLAW0xx (24 rules)
  2. AI-slop hygiene — FLAW100FLAW108
  3. Design & accessibility
  4. Cross-language security sinks — FLAW1xx
  5. CI/CD & GitHub Actions — FLAW144, FLAW145
  6. LLM / MCP app security — FLAW149FLAW157

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 — FLAW100FLAW108

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 — FLAW149FLAW157

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