flaw
A fast static analysis tool for finding security flaws in Crystal code.
flaw reads your Crystal source and holds it up to the light. Each rule looks for a specific flaw — hardcoded secrets, command-injection sinks, SQL built from interpolation, weak randomness used for tokens, untrusted YAML loads, LLM-app footguns. Findings print with file and line, and can be emitted as JSON or SARIF for CI and GitHub Code Scanning.
Why flaw
Most Crystal projects either go unscanned entirely or get run through general-purpose linters that don’t know the language’s footguns. flaw is Crystal-first and opinionated:
- Crystal-native. Rules know about
Process.run,YAML.parse,DB.execwith interpolation,RandomvsRandom::Secure,OpenSSLverification toggles — written by someone who ships Crystal. - One static binary.
shards build --releaseand you’re done. No Python venv, no node_modules, no runtime. Ships for linux-amd64, linux-arm64, macos-arm64. - Catches AI-slop. 6 novel rules (FLAW100–FLAW108) detect unedited LLM paste-through — narration comments, assistant boilerplate, placeholder secrets, commented-out auth checks. No other linter does this.
- Covers the AI stack too. FLAW149–FLAW157 catch LLM-app security
bugs: unpinned MCP sources, user input injected into system prompts,
unfenced tool results, user-controlled
max_tokens, tool handlers making outbound calls to non-literal URLs. - CI-ready.
--fail-on high,--baseline,--since HEAD~1 --since-lines, SARIF 2.1.0 for GitHub Code Scanning, a reusable GitHub Action,lint-rulesas a gatekeeper for rule contributions.
Get running in 60 seconds
# From source
git clone https://github.com/kdairatchi/flaw && cd flaw
shards build --release --no-debug --production
./bin/flaw version
# Scan your project
./bin/flaw scan path/to/your/project
Or grab a prebuilt static binary from
Releases
(linux-amd64, linux-arm64, macos-arm64).
flaw is in v0.1 — the rule contract is stable but the CLI surface is still small. See the changelog for the running log and the roadmap at the bottom of this page.
Rule catalog at a glance
Security
FLAW001–FLAW024 · 24 rulesInjection, secrets, crypto, auth, CORS, XXE, SSRF, zip-slip, JWT
alg:none. Default severity medium+; designed for --fail-on high.
AI-slop hygiene
FLAW100–FLAW108 · 9 rulesUnedited LLM paste-through: narration comments, assistant boilerplate, placeholders, unfinished stubs, silenced rescues, commented-out auth.
Design & a11y
FLAW106, 109, 111, 118–121, 127–131 · 11 rulesRaw color literals, WCAG contrast fails, mixed CSS units, missing
alt/lang, Tailwind conflicts, positive tabindex.
Security sinks
FLAW112–FLAW148 · 29 rulesEval, DOM XSS, SSTI, prototype pollution, Log4Shell, NoSQL injection, PII in logs, debug-in-prod, cloud metadata, LOLBIN, insecure GitHub Actions, open security groups, shipped source maps.
Full list with severity, tags, OWASP, and CWE mapping is in the
rule catalog and at
rules/README.md.
What to read next
- Getting Started — install paths, your first scan, baseline + CI wiring.
- CLI Reference — every subcommand, flag, and env var.
- Rules — full catalog with severity pills and grouping.
- CI Integration — GitHub Action, SARIF upload,
gating on
--fail-on high. - Writing a rule — scaffold + contract +
lint-rulesvalidation.
Roadmap
| Version | Theme |
|---|---|
| v0.2 | 10 more rules, --fix autofix expansion, better SARIF provenance |
| v0.3 | LSP server (real-time flaws in your editor) |
| v0.4 | Baseline file with per-rule / per-severity gating |
| v0.5 | Custom rule DSL (community rules in YAML) |
| v0.6 | Cross-file taint tracking (sources → sinks) |
| v1.0 | Plugin system, hosted rule docs at flaw.prowlrbot.com, Caido integration |
License
MIT. See LICENSE.