race-conditions
Race Conditions (RACE)
Analyze source code for race condition vulnerabilities including time-of-check to time-of-use (TOCTOU), double-spend, check-then-act without locking, file system race conditions, shared state across async boundaries, and non-atomic counter operations. Race conditions are among the hardest bugs to detect through testing because they depend on timing, making static analysis essential.
Supported Flags
Read ../../shared/schemas/flags.md for the full flag specification. This skill
supports all cross-cutting flags. Key flags for this skill:
--scopedetermines which files to analyze (default:changed)--depth standardreads code and checks for common race patterns--depth deeptraces shared state across call graphs and async boundaries--severityfilters output (race conditions are oftenhighorcritical)
Framework Context
Key CWEs in scope:
- CWE-362: Concurrent Execution Using Shared Resource with Improper Synchronization
- CWE-367: Time-of-Check Time-of-Use (TOCTOU) Race Condition
- CWE-820: Missing Synchronization
- CWE-821: Incorrect Synchronization
- CWE-829: Inclusion of Functionality from Untrusted Control Sphere
Detection Patterns
Read references/detection-patterns.md for the full catalog of code patterns,
search heuristics, language-specific examples, and false positive guidance.
Workflow
1. Determine Scope
Parse flags and resolve the file list per ../../shared/schemas/flags.md.
Filter to files likely to contain race-prone logic:
- Database transaction handlers (
**/services/**,**/handlers/**,**/models/**) - Payment and financial logic (
**/payments/**,**/billing/**,**/wallet/**) - File system operations (
**/storage/**,**/upload/**,**/fs/**) - Async/concurrent code (
**/workers/**,**/tasks/**,**/jobs/**) - Counter and state management (
**/counters/**,**/state/**,**/cache/**)
2. Check for Available Scanners
Detect scanners per ../../shared/schemas/scanners.md:
semgrep-- primary scanner for concurrency patternsgo vet-- Go-specific race detection heuristicsbandit-- Python threading and synchronization issues
Record which scanners are available and which are missing.
3. Run Scanners (If Available)
If semgrep is available, run with rules targeting concurrency:
semgrep scan --config auto --json --quiet <target>
Filter results to rules matching race condition, TOCTOU, and concurrency patterns. Normalize output to the findings schema.
4. Claude Code Analysis
Regardless of scanner availability, perform manual code analysis:
- Check-then-act audit: Find patterns where a condition is checked and then acted on without atomic guarantees (e.g., check balance then debit).
- File TOCTOU: Find file existence checks followed by file operations without locking or atomic alternatives.
- Shared state across await: Identify mutable state read before an await point and used after it without re-validation.
- Non-atomic counters: Find counter increments (read-modify-write) without locking or atomic operations.
- Database transactions: Verify financial and state-changing operations use proper isolation levels and row-level locking.
- Async/parallel iteration: Find shared mutable state accessed in parallel loops, goroutines, or thread pools.
When --depth deep, additionally trace:
- Full data flow of shared variables across async boundaries
- Database isolation level configuration
- Lock acquisition ordering (deadlock potential)
5. Report Findings
Format output per ../../shared/schemas/findings.md using the RACE prefix
(e.g., RACE-001, RACE-002).
Include for each finding:
- Severity and confidence
- Exact file location with code snippet
- The race window (what happens between check and act)
- Exploit scenario describing how timing can be abused
- Concrete fix with diff when possible
- CWE references
What to Look For
These are the high-signal patterns specific to race conditions. Each maps
to a detection pattern in references/detection-patterns.md.
-
TOCTOU in file operations -- Checking file existence or permissions then operating on the file in a separate call.
-
Double-spend / check-then-debit -- Reading a balance, comparing it, then debiting in separate non-atomic steps.
-
Check-then-act without lock -- Any pattern where a condition is checked and the result is assumed to hold when the action executes.
-
Shared state across await -- Reading mutable state, yielding execution (await/yield), then using the stale value.
-
Non-atomic read-modify-write -- Counter increments, sequence generators, or flag toggles without synchronization.
-
Missing database transaction isolation -- Financial operations using default (READ COMMITTED) isolation when SERIALIZABLE is needed.
-
Parallel iteration over shared collection -- Modifying a shared list, map, or set from concurrent goroutines, threads, or async tasks.
Scanner Integration
| Scanner | Coverage | Command |
|---|---|---|
| semgrep | TOCTOU file ops, non-atomic patterns | semgrep scan --config auto --json --quiet <target> |
| go vet | Go race condition heuristics | go vet -race ./... |
| bandit | Python threading issues | bandit -r <target> -f json -q |
Fallback (no scanner): Use Grep with patterns from references/detection-patterns.md
to find check-then-act patterns, file stat calls, counter operations, and
async state access. Report findings with confidence: medium.
Output Format
Use the findings schema from ../../shared/schemas/findings.md.
- ID prefix:
RACE(e.g.,RACE-001) - metadata.tool:
race-conditions - metadata.framework:
specialized - metadata.category:
RACE - references.cwe:
CWE-362,CWE-367 - references.stride:
T(Tampering) orE(Elevation of Privilege)
Severity guidance for this category:
- critical: Double-spend in financial operations, authentication bypass via race
- high: TOCTOU in security-sensitive file operations, check-then-act on authorization
- medium: Non-atomic counters affecting business logic, shared state across await
- low: Theoretical races with no clear exploit path, cosmetic counter inaccuracies