skills/sentinel/skills/race-conditions/SKILL.md
Detect race condition vulnerabilities. Use when the user asks to "check for race conditions", "find TOCTOU bugs", "analyze concurrency issues", "detect double-spend vulnerabilities", "check for check-then-act patterns", or mentions "race condition", "TOCTOU", "double-spend", "concurrency", "atomicity", or "thread safety" in a security context. Invoke with /sentinel:race-conditions.
npx skillsauth add 0x1337c0d3/claude-security race-conditionsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
Key CWEs in scope:
STRIDE mapping: T (Tampering), E (Elevation of Privilege)
Prioritize these file patterns:
**/services/**, **/handlers/**, **/models/**)**/payments/**, **/billing/**, **/wallet/**)**/storage/**, **/upload/**, **/fs/**)**/workers/**, **/tasks/**, **/jobs/**)**/counters/**, **/state/**, **/cache/**)Check for and run:
semgrep — run with semgrep scan --config auto --json --quiet <target>, filter for race/TOCTOU/concurrency rulesgo vet -race ./... — Go race detection (if Go project)bandit -r <target> -f json -q — Python threading issues (if Python project)Record which scanners ran and which are missing.
Regardless of scanner availability, analyze for these patterns:
Any pattern where a condition is checked and the result is assumed to hold when the action executes — without atomic guarantees.
# Vulnerable: balance checked then debited in separate non-atomic steps
if user.balance >= amount: # check
user.balance -= amount # act (race window between check and act)
db.save(user)
File existence or permission checks followed by file operations in a separate call.
# Vulnerable: attacker can replace file between check and open
if os.path.exists(filename):
with open(filename) as f: # file could be different now
data = f.read()
Mutable state read before an await point and used after it without re-validation.
// Vulnerable: balance could change while awaiting payment processor
const balance = await getBalance(userId); // read
await chargePaymentProcessor(amount); // yield — balance may change
await deductBalance(userId, balance); // act on stale value
Counter increments, sequence generators, or flag toggles without synchronization.
// Vulnerable: two concurrent requests both read 5, both write 6
let count = await getCount();
count++;
await setCount(count);
Financial operations using default (READ COMMITTED) isolation when SERIALIZABLE or row-level locking is needed.
# Vulnerable: SELECT then UPDATE without FOR UPDATE lock
balance = db.query("SELECT balance FROM accounts WHERE id = ?", user_id)
if balance >= amount:
db.execute("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, user_id)
# Should use: SELECT ... FOR UPDATE or SERIALIZABLE transaction
Lack of idempotency or deduplication on payment/credit operations.
Modifying a shared list, map, or set from concurrent goroutines, threads, or async tasks.
[RACE-XXX] Title
Severity: CRITICAL/HIGH/MEDIUM/LOW | CWE: CWE-362/CWE-367
Location: file:line | Confidence: HIGH/MEDIUM/LOW
Race window: [what happens between check and act]
Exploit scenario:
1. [Request 1 reads state]
2. [Context switch / await — Request 2 reads same state]
3. [Both requests proceed with stale value]
4. [Impact: double-spend / bypass / corruption]
Evidence:
[vulnerable code snippet]
Fix:
[corrected code using atomic operation, lock, or SELECT FOR UPDATE]
| Severity | Criteria | |----------|----------| | 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 |
Race condition findings complement Sentinel's SAST scan. Map findings to the
Sentinel consolidated report as RACE-XXX entries. Race conditions often
correspond to OWASP A04:2021 (Insecure Design) or A07:2021 (Auth Failures)
when they affect authentication or financial flows.
Format your final output following the standard Sentinel report structure defined in
${CLAUDE_SKILL_DIR}/../../templates/report.md. Use your skill's domain-specific
finding IDs (e.g. STRIDE-SPOOF-001, RT-SK-001, API-001) in the Finding ID column.
Include the Security Scorecard and Findings sections as a minimum. Omit the
Cross-Validation Summary section if you ran only AI analysis (no tool comparison).
development
STRIDE threat modeling. Use when the user asks to "run STRIDE", "threat model with STRIDE", "check for spoofing/tampering/repudiation/info disclosure/DoS/ privilege escalation", or invokes /sentinel:stride. Analyzes the codebase across all 6 STRIDE threat categories (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege).
data-ai
Adversarial analysis from 6 attacker personas. Use when the user asks to "red team this", "think like an attacker", "simulate an attack", "threat model as an adversary", or wants to understand how their app would be attacked by a script kiddie, insider, organized crime, nation-state, hacktivist, or supply chain attacker. Invoke with /sentinel:red-team.
testing
Detect business logic security vulnerabilities. Use when the user asks to "check business logic security", "find logic flaws", "audit workflow security", "check for coupon abuse", "detect negative amount exploits", "analyze state machine security", or mentions "business logic", "workflow bypass", "negative amount", "coupon abuse", "self-referral", "state manipulation", or "price manipulation" in a security context. Invoke with /sentinel:business-logic.
tools
Intelligence-driven security analysis — the reasoning layer that complements Sentinel's tool-based scanning. Use this skill when the user says "analyze these findings", "explain this vulnerability", "is this exploitable", "false positive?", "fix this security issue", "threat model this", "audit my Dockerfile/Terraform/k8s/GitHub Actions", "harden this config", "review my auth code", "is this JWT safe", "check for secrets", or pastes Sentinel's consolidated.json for deeper analysis. Also trigger on any security question after `/sentinel:sentinel` has run. Works without any tools installed — pure Claude intelligence. Part of the Sentinel plugin (github.com/alissonlinneker/sentinel-claude-skill).