flaw
A fast static analysis tool for finding security flaws in Crystal code.
Installation • Quickstart • GitHub Action • Rules • Contributing • Changelog
flaw reads your Crystal source and holds it up to the light. Each rule looks for a specific security flaw — hardcoded secrets, command injection sinks, SQL built from interpolation, weak randomness used for tokens, untrusted YAML loads. Findings print with file and line, and can be emitted as JSON or SARIF for CI and GitHub Code Scanning.
Features
Scanning
- Five built-in rules covering the common high-impact Crystal footguns
- Per-rule severity override and path ignore via
.flaw.yml - Fail-on threshold for CI gating (
--fail-on high) - Recurses any directory of
.crfiles, skipslib/andspec/by default
Output
- Pretty (colored, grouped by file, with snippet)
- JSON for pipelines and agents
- SARIF 2.1.0 for GitHub Code Scanning upload
Integration
- Single static binary, zero runtime dependencies
- Reusable GitHub Action (
uses: kdairatchi/flaw@v0.1.0) - Non-zero exit on finding-at-threshold
Installation
From source
git clone https://github.com/kdairatchi/flaw.git
cd flaw
shards build --release --no-debug --production
./bin/flaw version
Homebrew (coming with v0.1.0 release)
brew install kdairatchi/tap/flaw
Pre-built binaries
Download from the Releases page — linux-amd64, linux-arm64, macos-arm64.
Quickstart
flaw scan . # scan current directory, pretty output
flaw scan src/ --format json # JSON for agents / pipelines
flaw scan . --format sarif > flaw.sarif
flaw scan . --fail-on high # CI: exit 1 if any high+ finding
flaw rules # list built-in rules, grouped by tag
flaw rules FLAW001 # show rule detail
flaw lint-rules # validate rules/ directory contract
flaw init config # drop a .flaw.yml config stub
flaw init rule FLAW011 my-new-rule # scaffold a new rule folder + detector
GitHub Action
# .github/workflows/flaw.yml
name: flaw
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: kdairatchi/flaw@v0.1.0
with:
args: scan . --fail-on high --format sarif > flaw.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: flaw.sarif
Rules
Security (FLAW0xx)
| 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 | Weak RNG near security-sensitive identifier |
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 |
AI-slop / hygiene (FLAW1xx)
Detects unedited LLM paste-through — the smell of vibe-coded Claude/ChatGPT output shipped without review. Novel territory: no other linter looks for these.
| ID | Severity | Flaw |
|---|---|---|
FLAW100 |
low | Explanatory narration comment ("This function does X") |
FLAW101 |
medium | AI assistant boilerplate leaked into source |
FLAW102 |
medium | Placeholder value left in source (your-api-key-here, REPLACE_ME) |
Every rule lives in its own folder under rules/ with the detector, a vulnerable fixture (bad.cr), a fixed version (good.cr), metadata (rule.yml), and docs. Add one with flaw init rule FLAW011 my-rule.
Rule validator
flaw lint-rules enforces the rule contract — every folder matches FLAWNNN, has all four required files, the rule.yml parses and has the required keys, the detector file exists, and each bad.cr + good.cr behaves as claimed. Run it in CI as the gatekeeper for rule contributions.
Configuration
.flaw.yml in your repo root:
version: 1
exclude:
- spec/
- lib/
- vendor/
rules:
FLAW002:
ignore:
- "examples/fake-keys.cr"
FLAW004:
severity: critical
FLAW005:
disabled: true
Roadmap
- v0.2 — 10 more rules,
--fixautofix for trivial cases, better SARIF provenance - v0.3 — LSP server (real-time flaws in your editor)
- v0.4 — Baseline file (gate only on new findings)
- 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
Contributing
flaw is an open-source project built by one person and improved by many. See CONTRIBUTING.md for how to add a rule, report a false positive, or suggest a roadmap item.
Why "flaw"?
In gemology, a flaw is a fracture, inclusion, or imperfection inside a crystal — the thing a trained eye spots by catching the light right. flaw does the same for Crystal code: it holds your program up to the light and shows you the fractures before someone else does.
Security
Report suspected vulnerabilities privately — see SECURITY.md.
License
MIT © kdairatchi
flaw
- 1
- 1
- 0
- 0
- 0
- about 6 hours ago
- April 13, 2026
MIT License
Sun, 19 Apr 2026 00:11:26 GMT