Features β’ Installation β’ Quick Start β’ Usage Guide β’ Examples β’ Tutorial
- What is CorsOne?
- Features
- Performance Comparison
- Installation
- Quick Start
- Usage Guide
- CLI Options
- Examples
- Tutorial
- Output Explanation
- Contributing
- Acknowledgment
- License
- Developer
- Support
- Additional Resources
CorsOne is a specialized security testing tool designed to detect and identify Cross-Origin Resource Sharing (CORS) misconfigurations in web applications. It automates the process of testing for CORS vulnerabilities that could allow attackers to:
- Access sensitive data from authenticated users
- Perform unauthorized actions on behalf of users
- Bypass Same-Origin Policy (SOP) restrictions
- Steal credentials and session tokens
Unlike generic security scanners, CorsOne:
- β Tests 40+ CORS bypass techniques automatically
- β Provides accurate results with low false positives
- β High-performance async scanning using asyncio and aiohttp
- β DNS caching with aiodns for repeated hostname efficiency
- β Easy integration - supports STDIN and file input
- β Flexible customization - supports custom headers, proxies, and methods
- β Color-coded output - easy to identify vulnerabilities
- β Docker support - no dependency installation needed
- Automatic CORS Misconfiguration Detection - Tests multiple bypass techniques
- Multiple Input Methods
- Single URL with
-uflag - Multiple URLs from file with
-lflag - STDIN piping for easy integration
- Single URL with
- Customizable Origin Testing - Test with custom domains instead of default "attacker.com"
- Custom Headers Support - Add authentication cookies and headers for protected endpoints
- Flexible HTTP Methods - Support for GET, POST, PUT, DELETE, etc.
- Rate Limiting - Control request frequency to avoid detection
- Proxy Support - Route requests through HTTP/HTTPS proxies
- Stop-on-First Detection - Exit immediately after finding first vulnerability
- Multiple Output Formats - TXT, JSON, and SARIF for advanced reporting
- No False Positives - Checks for both ACAO header and credentials flag
- Async HTTP Engine - Built on aiohttp for non-blocking, concurrent requests
- DNS Caching - Uses aiodns caching to reduce repeated hostname lookups
- URL Validation - Automatically validates and formats URLs
- Color-Coded Output - Green for vulnerable, red for not vulnerable
- Error Handling - Graceful handling of network errors and timeouts
- SARIF Export - Standards-compliant security reporting format
- Keyboard Interrupt Support - Safely cancel operations with Ctrl+C
- Reflected Origin - Direct origin reflection
- Breaking TLS - HTTP/HTTPS protocol mixing
- Trusted Subdomains - Subdomain bypasses
- Null Origin - Testing null origin header
- Domain Ending Bypasses - Various character injections
- Localhost Edge Cases - Localhost regex bypasses
- Domain Separation Bypasses - 20+ variants with special characters
- Advanced Regexp Bypasses - Regex metacharacter injections
CorsOne has been significantly optimized for speed with a complete async HTTP refactor. The current version uses asyncio and aiohttp with DNS caching for better throughput, lower latency, and reduced thread overhead.
Test Command: python3 CorsOne.py -u target.com -s
- v0.9.8 (Previous Version): ~5.5 seconds (real time)
- v1.0.0 beta (Current Version): ~0.8 seconds (real time)
Improvement: Approximately 7x faster execution time, now powered by an async aiohttp engine and cached DNS resolution.
The easiest way to run CorsOne without installing dependencies:
# Pull the official Docker image
docker pull omranisecurity/corsone:latest
# Run a quick scan
docker run --rm omranisecurity/corsone:latest -u https://example.com/
β οΈ Note: The Docker image is currently unavailable. Please use the alternative installation methods until it becomes accessible again.
Prerequisites
- Python 3.7 or higher
- pip (Python package manager)
- git (for cloning the repository)
Installation Steps
# 1. Clone the Repository
git clone https://github.com/omranisecurity/CorsOne.git
cd CorsOne
# 2. Create Virtual Environment (Recommended)
python3 -m venv corsone-env
source corsone-env/bin/activate # On Windows: corsone-env\Scripts\activate
# 3. Install Dependencies
pip install -r requirements.txt
# 4. Verify Installation
python3 CorsOne.py --help
> Note: `requirements.txt` now includes `aiohttp` and `aiodns` for the async HTTP engine and DNS caching support.
> The legacy `requests` dependency has been removed.
# 5. Deactivate When Done
deactivategit clone https://github.com/omranisecurity/CorsOne.git
cd CorsOne
pip install -r requirements.txt
python3 CorsOne.py -u https://example.com/# Using Docker
docker run --rm omranisecurity/corsone:latest -u https://example.com/
# Or with Python (after installation)
python3 CorsOne.py -u https://example.com/# Create a file with URLs (one per line)
echo "https://example1.com/" > targets.txt
echo "https://example2.com/" >> targets.txt
# Scan them
python3 CorsOne.py -l targets.txt# Using with other tools
echo "https://example.com/" | python3 CorsOne.py
# Using with cat command
cat url_list.txt | python3 CorsOne.py
# Combine with other security tools
tool-name | python3 CorsOne.py# Stop after finding the first vulnerability
python3 CorsOne.py -u https://example.com/ -sofpython3 CorsOne.py [OPTIONS]Single URL:
python3 CorsOne.py -u https://example.com/
python3 CorsOne.py --url https://example.com/api/dataMultiple URLs from File:
python3 CorsOne.py -l urls.txt
python3 CorsOne.py --list targets.txtFrom STDIN (Piped Input):
cat urls.txt | python3 CorsOne.py
echo "https://example.com/" | python3 CorsOne.pySave Results to File:
python3 CorsOne.py -u https://example.com/ -o results.txt
python3 CorsOne.py -u https://example.com/ --output findings.txt
python3 CorsOne.py -u https://example.com/ -o results.json -f json -voSpecify Output Format (TXT, JSON, or SARIF):
# TXT format (default)
python3 CorsOne.py -u https://example.com/ -o results.txt
# JSON format for parsing
python3 CorsOne.py -u https://example.com/ -o results -f json
# SARIF format for advanced reporting
python3 CorsOne.py -u https://example.com/ -o results -f sarif
# Explicit format takes precedence over file extension
python3 CorsOne.py -u https://example.com/ -o results.json # β results.json
python3 CorsOne.py -u https://example.com/ -o results.txt # β results.json when --format json is setSave Debug Logs:
# Only creates log file if specified (no extra files otherwise)
python3 CorsOne.py -u https://example.com/ --log scan.log
python3 CorsOne.py -u https://example.com/ --log debug_info.log -v
# Combined with results output and SARIF format
python3 CorsOne.py -u https://example.com/ -o results -f sarif --log debug.logDisable Color Output:
python3 CorsOne.py -u https://example.com/ -nc
python3 CorsOne.py -u https://example.com/ --no-colorCustom Domain for Testing:
# Instead of "attacker.com", use your domain
python3 CorsOne.py -u https://example.com/ -cd attacker.com
python3 CorsOne.py -u https://example.com/ --custom-domain your-domain.comCustom HTTP Method:
# Default is GET, change to POST, PUT, DELETE, etc.
python3 CorsOne.py -u https://example.com/ -m POST
python3 CorsOne.py -u https://example.com/ --method PUTRate Limiting:
# Add delay between requests (in seconds)
python3 CorsOne.py -l urls.txt -rl 2
python3 CorsOne.py -l urls.txt --rate-limit 1.5Proxy Support:
# Route requests through a proxy
python3 CorsOne.py -u https://example.com/ -p http://127.0.0.1:8080
python3 CorsOne.py -u https://example.com/ --proxy https://proxy.company.com:3128Stop on First Vulnerability:
# Exit after finding the first vulnerability
python3 CorsOne.py -u https://example.com/ -sof
python3 CorsOne.py -l urls.txt --stop-on-firstCustom Headers:
# Add custom headers to requests
python3 CorsOne.py -u https://example.com/ -H "Cookie: session=321cba"
python3 CorsOne.py -u https://example.com/ --headers "Cookie: session=abc123"| Option | Short | Type | Description | Default | Example |
|---|---|---|---|---|---|
| URL | -u |
string | Target URL to scan | - | -u https://example.com/ |
| List | -l |
file | File containing URLs | - | -l targets.txt |
| Output | -o |
file | Save results to file | - | -o results.txt |
| Format | -f |
choice | Output format (txt/json/sarif) | txt | -f sarif |
| Headers | -H |
string | Custom headers as JSON | - | `-H '{"Cookie": "session=abc123"}' |
| Log | --log |
file | Save debug logs to file | - | --log scan.log |
| Vulnerable Only | -vo, --vuln-only |
flag | Show and save only vulnerable endpoints | false | -vo |
| No Color | -nc |
flag | Disable colored output | false | -nc |
| Domain | -cd |
string | Custom domain for testing | attacker.com | -cd attacker.com |
| Method | -m |
string | HTTP method to use | GET | -m POST |
| Workers | -w |
int | Concurrent workers | 5 | -w 10 |
| Rate Limit | -rl |
float | Delay between requests (sec) | 0 | -rl 2 |
| Timeout | -t |
int | Request timeout (seconds) | 10 | -t 15 |
| Retries | -r |
int | Number of retries | 3 | -r 3 |
| Proxy | -p |
string | HTTP/HTTPS proxy URL | - | -p http://proxy:8080 |
| Stop on First | -sof |
flag | Exit after first vulnerability | false | -sof |
| Verbose | -v |
flag | Verbose logging | false | -v |
| Silent | -s |
flag | No banner output | false | -s |
| Help | -h |
flag | Show help message | - | -h |
| Version | --version |
flag | Show version information | - | --version |
python3 CorsOne.py -u https://api.example.com/
# Output:
# [VULNERABLE] Reflected Origin: https://attacker.com]
# [VULNERABLE] Breaking TLS: http://api.example.com
# [SAFE] Null Origin: null
# ...# Create targets file
cat > targets.txt << EOF
https://api1.example.com/
https://api2.example.com/
https://api3.example.com/
EOF
# Scan all targets
python3 CorsOne.py -l targets.txt -o results.txt
# Output saved to results.txt# Save results as JSON for parsing
python3 CorsOne.py -u https://example.com/ -o results.json
# Or specify format explicitly
python3 CorsOne.py -u https://example.com/ -o results -f json
# Use with jq to filter vulnerable endpoints
jq '.[] | select(.is_vulnerable==true)' results.json# Generate SARIF report
python3 CorsOne.py -u https://example.com/ -o scan_results -f sarif
# With authentication headers
python3 CorsOne.py -u https://api.example.com/ \
-H '{"Cookie": "session=abc123"}' \
-f sarif \
-o results.json
# Only vulnerable findings in SARIF format
python3 CorsOne.py -u https://example.com/ -f sarif -o results -vo# Save debug logs to file (only creates if specified)
python3 CorsOne.py -u https://example.com/ --log scan.log
# Combine with verbose output
python3 CorsOne.py -u https://example.com/ -v --log debug.log
# Results + Logs together
python3 CorsOne.py -u https://example.com/ -o findings.txt --log activity.log# Stop after finding first vulnerability
python3 CorsOne.py -u https://example.com/ -sof -cd evil.com# Test CORS on POST endpoints
python3 CorsOne.py -u https://api.example.com/api/data -m POST# Route through Burp Suite for inspection
python3 CorsOne.py -u https://example.com/ -p http://127.0.0.1:8080 -nc# Get URLs from subfinder and scan them
subfinder -d example.com | python3 CorsOne.py -rl 1
# Get URLs from other tools
cat urls.txt | python3 CorsOne.py -o cors_findings.txt
# Test endpoints requiring authentication with cookie
python3 CorsOne.py -u https://api.example.com/ \
-H '{"Cookie": "sessionid=abc123"}'
# Multiple custom headers
python3 CorsOne.py -u https://api.example.com/ \
-H '{"Cookie": "session=abc123", "User-Agent": "Custom Agent"}'
# Docker with multiple options
docker run --rm omranisecurity/corsone:latest \
-u https://example.com/ \
-m POST \
-cd malicious.com \
-nc
# Scan from file with Docker (mount volume)
docker run --rm -v $(pwd):/app omranisecurity/corsone:latest \
-l /app/targets.txt \
-o /app/results.txtStep 1: Install Dependencies
# Clone the repository
git clone https://github.com/omranisecurity/CorsOne.git
cd CorsOne
# Create virtual environment
python3 -m venv corsone-env
source corsone-env/bin/activate
# Install requirements
pip install -r requirements.txtStep 2: Run Your First Scan
# Test with a public website
python3 CorsOne.py -u https://example.com/
# Watch the output for [VULNERABLE] or [SAFE] messagesStep 3: Understand the Output
[VULNERABLE] Reflected Origin: https://attacker.com] β CORS vulnerability found!
[SAFE] Breaking TLS: http://example.com β Not vulnerable
[SAFE] Null Origin: null β This bypass didn't work
Scenario: You want to save results in specific format for automation or reporting
Step 1: JSON Output for Automation
# Save as JSON for programmatic parsing
python3 CorsOne.py -u https://example.com/ -o scan_results.json
# Filter vulnerable endpoints with jq
jq '.[] | select(.is_vulnerable==true) | .bypass_name' scan_results.json
# Get count of vulnerabilities
jq '[.[] | select(.is_vulnerable==true)] | length' scan_results.jsonStep 2: TXT Output for Reporting
# Save as text for human-readable reports
python3 CorsOne.py -u https://example.com/ -o scan_results.txt
# View results
cat scan_results.txt
# Filter vulnerable lines
grep "VULNERABLE" scan_results.txtStep 3: Enable Debug Logging
# Save detailed logs for troubleshooting
python3 CorsOne.py -u https://example.com/ --log scan_debug.log
# View logs
cat scan_debug.log
# Combine with verbose output
python3 CorsOne.py -u https://example.com/ -v --log detailed.log -o results.txtStep 1: Create a Target File
cat > my_targets.txt << 'EOF'
https://api.company1.com/
https://api.company2.com/
https://app.company3.com/api
EOFStep 2: Run Batch Scan
python3 CorsOne.py -l my_targets.txt -o cors_report.txtStep 3: Review Results
# View all results
cat cors_report.txt
# View only vulnerable endpoints
grep "Vulnerable" cors_report.txt
# Count vulnerabilities
grep "Vulnerable" cors_report.txt | wc -lScenario: You want to test CORS with your own domain instead of "attacker.com"
Step 1: Prepare
# Create target list
echo "https://api.target.com/" > targets.txt
# Make sure you own or control the domain you'll use
# For this example, let's use "evil.domain.com"Step 2: Run Scan with Custom Domain
python3 CorsOne.py -l targets.txt -cd evil.domain.com -o results.txt Step 3: Analyze Results
# Results will show bypasses like:
# [VULNERABLE] Reflected Origin: https://evil.domain.com]
# This means the server reflects back your custom domainScenario: Your target uses cookie-based authentication - test with custom headers
Step 1: Obtain Session Cookie
# Get your session cookie from the application
# Extract the cookie value from browser or interceptor
SESSION_COOKIE="sessionid=abc123def456xyz"Step 2: Scan with Cookie Header (JSON Format)
# Pass headers as JSON string
python3 CorsOne.py -u https://api.example.com/ \
-H '{"Cookie": "sessionid=abc123def456xyz"}'
# Multiple headers
python3 CorsOne.py -u https://api.example.com/ \
-H '{"Cookie": "sessionid=abc123def456xyz", "User-Agent": "Custom"}'Step 3: Analyze Results
# The scan will use your authenticated session with the cookie
# This helps find CORS issues in protected endpoints
# Save results with SARIF format
python3 CorsOne.py -u https://api.example.com/ \
-H '{"Cookie": "sessionid=abc123def456xyz"}' \
-f sarif -o auth_scan_results.jsonScenario: You want to intercept and inspect requests in Burp Suite
Step 1: Start Burp Suite
- Launch Burp Suite
- Go to Settings β Network β Proxy and note the port (usually 8080)
Step 2: Run CorsOne Through Proxy
python3 CorsOne.py -u https://example.com/ \
-p http://127.0.0.1:8080 \
-nc # Disable color for clarity in BurpStep 3: Inspect in Burp Suite
- All requests will appear in Burp's Proxy β HTTP History
- You can see the Origin headers being tested
- Inspect responses for CORS headers
Scenario: Target has rate limiting or IDS detection
Step 1: Identify Optimal Rate
# Start slow - 1 request per second
python3 CorsOne.py -u https://example.com/ -rl 1Step 2: If Getting Blocked, Increase Delay
# Wait 2 seconds between each request
python3 CorsOne.py -l targets.txt -rl 2 -o results.txtStep 3: Monitor for Rate Limit Errors
# Check if you're getting rate limit errors
python3 CorsOne.py -l targets.txt -rl 3 | tee scan.log
# Analyze log for errors
grep -i "error\|429\|rate" scan.logScenario: API supports multiple HTTP methods (GET, POST, PUT, DELETE)
Step 1: Test GET Requests (default)
python3 CorsOne.py -u https://api.example.com/users -m GETStep 2: Test POST Requests
python3 CorsOne.py -u https://api.example.com/users -m POSTStep 3: Test Other Methods
# PUT method
python3 CorsOne.py -u https://api.example.com/users/123 -m PUT
# DELETE method
python3 CorsOne.py -u https://api.example.com/users/123 -m DELETE
# OPTIONS method (often reveals CORS configuration)
python3 CorsOne.py -u https://api.example.com/users -m OPTIONSScenario: You want to export CORS scan results in SARIF format for advanced analysis and integration
Step 1: Understand SARIF Format SARIF (Static Analysis Results Interchange Format) is an industry-standard format for security findings that enables integration with various security tools and platforms.
Step 2: Generate SARIF Report
# Basic SARIF output
python3 CorsOne.py -u https://example.com/ -f sarif -o scan_results
# With authentication headers
python3 CorsOne.py -u https://api.example.com/ \
-H '{"Cookie": "session=abc123"}' \
-f sarif \
-o api_scan_results
# Only vulnerable findings
python3 CorsOne.py -u https://example.com/ -f sarif -o results -voStep 3: Analyze Results
# View SARIF results with jq
jq '.runs[0].results[] | select(.level=="warning")' scan_results.json
# Count vulnerable findings
jq '[.runs[0].results[] | select(.level=="warning")] | length' scan_results.json
# Extract all vulnerability details
jq '.runs[0].results[] | {rule: .ruleId, level: .level, message: .message.text}' scan_results.jsonStep 4: Integration SARIF files can be imported into security platforms and tools for centralized vulnerability management and reporting. The generated SARIF file contains all necessary metadata including vulnerability severity, location, and detailed properties for comprehensive security analysis.
[VULNERABLE] Reflected Origin: https://attacker.com]
[SAFE] Breaking TLS: http://example.com
[VULNERABLE] Trusted Subdomains: https://subdomain.example.com
[VULNERABLE] (Green in terminal)
- The server responded with
Access-Control-Allow-Origin: [origin]ANDAccess-Control-Allow-Credentials: true - This is a real CORS vulnerability
- An attacker could exploit this
[SAFE] (Red in terminal)
- The server did NOT respond with both required headers
- Either the origin wasn't allowed OR credentials flag wasn't set
- This bypass technique didn't work
https://api.example.com/ [VULNERABLE] Reflected Origin: https://attacker.com]
https://api.example.com/ [VULNERABLE] Breaking TLS: http://api.example.com
https://api.example.com/ [SAFE] Null Origin: null
https://api.example.com/ [SAFE] Trusted Subdomains: https://subdomain.example.com
We welcome contributions! Here's how you can help:
Found a bug? Have a feature request?
- Visit: https://github.com/omranisecurity/CorsOne/issues
- Provide detailed description of the problem
- Include example commands and output
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- Thanks to hacktricks.xyz for sharing the resources.
- Thanks to PortSwigger and the security researchers for providing and collecting the test cases.
This project is licensed under the MIT License - see LICENSE file for details.
CorsOne is developed and maintained by:
- Mohammad Reza Omrani
- Twitter/X: @omranisecurity
- LinkedIn: Mohammad Reza Omrani
- GitHub: omranisecurity
If you find CorsOne helpful:
- β Star the repository on GitHub
- π Report bugs and suggest features
- π’ Share with your security community
- π¬ Provide feedback and improvements
- OWASP CORS Documentation
- MDN CORS Guide
- CWE-942: Permissive Cross-domain Policy
- What is CORS (cross-origin resource sharing)?
Happy CORS Testing! π‘οΈ
For questions or support, visit the GitHub repository or contact the developer.