A lightweight CLI tool for systematically detecting and exploiting race conditions in web applications, APIs, and modern services.
Race conditions represent one of the highest-impact security vulnerabilities in modern applications, yet they remain poorly covered by automated scanners. While tools like Nuclei, ffuf, and sqlmap excel at finding static vulnerabilities, they are fundamentally blind to concurrency-based issues.
Pentesters today face a choice: manually write throwaway scripts for each engagement, or skip race condition testing entirely. Neither option is scalable or professional.
RatRace solves this by providing a polished, repeatable workflow for race condition testing—transforming what was once ad-hoc scripting into a systematic process that integrates with CI/CD pipelines and generates professional reports.
Race condition vulnerabilities frequently appear in high-impact areas:
- E-commerce: Duplicate orders, inventory overselling, discount stacking
- Fintech: Double transfers, race-based privilege escalation, transaction replay
- Authentication: Token draining, session fixation, concurrent password resets
- Rate Limiting: Bypass via concurrent requests, distributed abuse
These bugs consistently earn the highest bounties in bug bounty programs because they directly threaten business revenue and customer trust.
Define race scenarios once in YAML, reuse across projects. Format mirrors Nuclei templates for familiarity:
id: checkout-race
info:
name: Checkout Duplicate Order Race
severity: critical
race:
mode: burst
concurrency: 20
request:
method: POST
path: /api/v1/checkout
headers:
Authorization: "Bearer {{session}}"
body: '{"item_id": "SKU-001"}'
validate:
follow_up:
method: GET
path: /api/v1/orders?user={{user_id}}
expect:
json_field: "orders.length"
condition: equals
value: 1Burst Mode — Goroutine-based parallel requests with precise synchronization (stable, production-ready)
- Launches N goroutines that synchronize at microsecond precision
- Ideal for most applications with >5ms race windows
Last-Byte Sync — HTTP/1.1 TCP-level attack (implementation ready, testing phase)
- Holds all connections at request body's final byte
- Release via close() broadcast for sub-millisecond windows
- Effective against load-balanced and rate-limited targets
Single-Packet — HTTP/2 frame-based attack (implementation ready, testing phase)
- Sends all requests in a single TCP segment
- Leverages multiplexing for near-simultaneous server reception
- Bypasses some rate limiting mechanisms
RatRace automatically:
- Fingerprints responses by status code + body hash to detect anomalies
- Clusters results to identify statistically significant differences
- Calculates confidence scores based on anomaly frequency and magnitude
- Executes follow-up requests to confirm state changes (e.g., "was the item really purchased twice?")
- Supports conditional validation with operators:
equals,not_equals,greater_than,contains
Import existing requests:
# From curl commands
ratrace import --curl 'curl -X POST https://api.example.com/checkout ...' -o template.yaml
# From Burp exported HAR files
ratrace import --har session.har -o template.yamlCI/CD automation:
ratrace race -u $TARGET -t template.yaml --silent
echo $? # Exit code 10 = race found, 0 = cleanProfessional reporting:
# JSON for automation
ratrace race -u $TARGET -t template.yaml -o results/
# HTML reports (planned V2)
ratrace report --input results.json --format htmlgit clone https://github.com/bogdanticu88/ratrace.git
cd ratrace
go build ./cmd/ratrace
./ratrace --helpRequirements: Go 1.24+
docker build -t ratrace:latest .
docker run --rm -it ratrace:latest race -u https://api.example.com -t template.yaml# 1. Import from curl or use existing template
ratrace import --curl 'curl -X POST https://api.example.com/checkout ...' -o checkout.yaml
# 2. Execute the race
ratrace race -u https://api.example.com -t checkout.yaml -m burst -c 20
# 3. Review findings
# Output shows:
# 🔴 [CRITICAL] Checkout Duplicate Order Race
# Anomaly Rate: 91.7%
# Confidence: 84%ratrace race \
-u https://shop.example.com \
-t examples/templates/checkout-race.yaml \
-m burst \
-c 25 \
--output results/# Runs without verbose logs, exits with semantic code
ratrace race -u https://api.example.com -t template.yaml --silent
# Check exit code
if [ $? -eq 10 ]; then
echo "Race condition found!"
exit 1
firatrace race -u <url> -t <template> [options]
Options:
-m, --mode string burst|lastbyte|singlepacket (default from template)
-c, --concurrency int Goroutine count (default 20)
-H, --header strings Custom headers (repeatable)
-x, --proxy string Proxy URL for requests
-o, --output string Output directory for results
--timeout duration Request timeout (default 10s)
--insecure Skip TLS certificate verification
--dry-run Parse template and exit
--silent Suppress logs, show findings only
ratrace import [--curl <command> | --har <file>] -o <output.yaml>
Converts existing requests (curl commands or HAR exports) into RatRace templates.
Useful for integrating with existing workflows.
ratrace report --input results.json --format [html|json] --output report.html
Generates human-readable reports from race test results.
ratrace ratelimit -u <url> -c <concurrency>
Tests if endpoints are vulnerable to concurrent rate limit bypass.
Templates are YAML files that define a race scenario. Full reference:
id: unique-identifier
info:
name: "Human-readable name"
severity: critical|high|medium|low|info
tags: [tag1, tag2]
race:
mode: burst|lastbyte|singlepacket
concurrency: 20
request:
method: POST|GET|PUT|DELETE|PATCH
path: /api/endpoint
headers:
Authorization: "Bearer {{token}}"
Custom-Header: "value"
body: '{"json": "body", "user": "{{user_id}}"}'
validate:
follow_up:
method: GET
path: /api/orders?user={{user_id}}
expect:
json_field: "orders.length"
condition: equals|greater_than|contains|not_equals
value: 1Variables (use {{name}} placeholders):
- Substituted via command-line headers or hardcoded in template
- Example:
ratrace race ... -H "Authorization: Bearer {{session_token}}"
Clean, color-coded logging shows test progress:
[INF] Loading template path=checkout-race.yaml
[INF] Template loaded id=checkout-race mode=burst
[RUN] Firing burst attack concurrency=20
[INF] All requests completed total=20
[RUN] Clustering responses baseline=17 anomalous=3
[RACE] Race condition detected anomaly_rate=15% confidence=94%
[CONF] Validation passed field=orders.length expected=1
[INF] Race test complete findings=1
Templates: 1 Requests: 20 Time: 3.2s
🔴 [CRITICAL] Checkout Duplicate Order Race
Anomaly Rate: 15.0%
Confidence: 94%
Status Diff: 201 → 200
Field Diffs: order_id (100 → 101)
Full results saved to results_<timestamp>.json for automation and archival:
{
"TemplateID": "checkout-race",
"Target": "https://api.example.com/api/v1/checkout",
"Mode": "burst",
"Concurrency": 20,
"TotalRequests": 20,
"Duration": 3200000000,
"Findings": [
{
"TemplateName": "Checkout Duplicate Order Race",
"Severity": "critical",
"AnomalyRate": 0.15,
"Confidence": 0.94,
"Diff": {
"StatusChanged": true,
"BaselineStatus": 201,
"AnomalousStatus": 200
}
}
]
}Used for CI/CD integration and automation:
| Code | Meaning |
|---|---|
| 0 | Success — no race conditions found |
| 3 | Data error — template not found, parse error |
| 4 | Execution error — network failure, engine error |
| 10 | Race condition found — action required |
| 11 | Rate limit bypass confirmed |
| 12 | Anomaly detected but validation inconclusive |
make build # Compile binarymake test # All tests
make test-unit # Unit tests only
make test-int # Integration tests
make coverage # Coverage report (HTML)make lint # Run lintermake run-race # Build and run examplecmd/ratrace/
└── main.go Entrypoint, CLI definition
internal/
├── cmd/ Subcommand implementations
├── engine/ Race attack modes (burst, lastbyte, singlepacket)
├── validator/ Response clustering, diffing, follow-up checks
├── importer/ HAR and curl parsers
├── reporter/ JSON and HTML output
├── template/ YAML parsing and templating
├── log/ Structured color logging
└── models/ Shared data types
- ✅ Burst mode with goroutine synchronization
- ✅ Response clustering and anomaly detection
- ✅ Confidence scoring
- ✅ Follow-up validation with conditions
- ✅ HAR/curl import
- ✅ JSON output
- ✅ Silent mode for CI/CD
- ⏳ Last-byte sync mode (implementation ready, needs testing)
- ⏳ Single-packet mode (implementation ready, needs testing)
- HTML report generation
- PoC script generation
- Rate limit bypass specialization
- Burp Suite XML import
- gRPC race testing
- WebSocket race testing
- Template registry and community templates
- Nuclei integration
Issues, PRs, and template contributions welcome. Please ensure:
- Code follows existing patterns in the codebase
- Tests pass:
make test - Linter passes:
make lint
MIT
RatRace is designed for authorized security testing, bug bounty programs, and penetration tests. Only use on systems you own or have explicit written permission to test. Unauthorized testing of others' systems is illegal.
Bogdan Ticu — Security Research & Engineering
For issues, questions, or security reports: GitHub Issues