Cors Wildcard in Rails with Cockroachdb
Cors Wildcard in Rails with Cockroachdb — how this specific combination creates or exposes the vulnerability
A CORS wildcard in a Rails application that uses CockroachDB can expose your data and schema even when database controls are strict. In Rails, a common misconfiguration is setting config.action_dispatch.allowed_origins = ['*'] or using resource '*', '*', '*' in routes for API endpoints. When combined with CockroachDB-backed services, this allows any origin to make authenticated requests on behalf of users, leveraging database sessions or tokens issued after initial (perhaps accidental) authentication.
Because CockroachDB is often used in distributed and multi-region deployments, Rails APIs frequently proxy requests to database services via service-to-service calls. If the API’s CORS policy is open, an attacker website can make browser-based requests to the Rails API. Those requests may include credentials (cookies, authorization headers) that the Rails app uses to construct CockroachDB queries. Even if the database enforces role-based access, the Rails layer acts as a permissive proxy, effectively bypassing intended origin restrictions.
This combination is especially risky when the Rails app exposes endpoints that return sensitive CockroachDB data or allow mutation based on user-supplied parameters. Because the browser enforces CORS, a wildcard allows malicious JavaScript to invoke these endpoints, potentially leveraging the authenticated session to issue queries that return PII or enable unauthorized transactions. The vulnerability is not in CockroachDB itself, but in the Rails CORS configuration that permits cross-origin access to endpoints that interact with the database.
In practice, this can lead to scenarios aligned with the OWASP API Top 10 categories such as Broken Object Level Authorization (BOLA) and Excessive Data Exposure, because the open CORS policy lowers the barrier for unauthorized data access through the API layer. Since middleBrick scans test CORS and authentication configurations in parallel, it can detect permissive origins and flag the associated risk with remediation guidance.
Cockroachdb-Specific Remediation in Rails — concrete code fixes
To secure a Rails API backed by CockroachDB, tighten CORS at the application level and ensure database access patterns follow least privilege. Below are specific, actionable fixes with real code examples.
1. Restrict allowed origins explicitly
Replace wildcard origins with a list of trusted domains. In production, avoid '*'.
# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'https://app.example.com', 'https://admin.example.com'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head],
expose: ['X-Total-Count', 'X-Page-Number'],
max_age: 1800
end
end
2. Use environment-aware configuration
Keep wildcard out of production by using environment variables.
# config/initializers/cors.rb
allowed_origins = if Rails.env.production?
['https://app.example.com']
else
['*']
end
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins *allowed_origins
resource '/api/*',
headers: :any,
methods: [:get, :post]
end
end
3. Apply controller-level CORS and authorization
For endpoints that query CockroachDB, enforce both CORS and per-action authorization.
class Api::V1::AccountsController < ApplicationController
before_action :authorize_user!
def index
accounts = current_user.accounts CockroachDB::Database.new('postgres://user:pass@cockroachdb:26257/mydb')&.exec_query('SELECT id, name FROM accounts WHERE user_id = $1', [current_user.id])
render json: accounts
end
private
def authorize_user!
head :forbidden unless current_user
end
end
4. Use Rails credentials for CockroachDB connection strings
Never hardcode connection details. Store them in encrypted credentials and reference them safely.
# config/credentials.yml.enc
cockroachdb:
url: "postgres://myuser:[email protected]:26257/mydb?sslmode=require"
# config/database.yml (or an initializer)
production_cockroach:
url: Rails.application.credentials.dig(:cockroachdb, :url)
ActiveRecord::Base.establish_connection(Rails.env.production? ? :production_cockroach : 'postgresql://localhost/mydev')
5. Validate and parameterize all DB queries
Prevent injection and ensure strict mapping to authenticated user context.
class Api::V1::ReportsController < ApplicationController
def show
report_id = params.fetch(:id)
report = CockroachDB::Database.new('postgres://user:pass@cockroachdb:26257/mydb')&.exec_query(
'SELECT id, title, user_id FROM reports WHERE id = $1 AND user_id = $2',
[report_id, current_user&.id]
)
head :not_found unless report
render json: report.first
end
end
6. Add rate limiting and monitoring at the API layer
Even with correct CORS, limit abuse by integrating Rack-based throttling.
# Gemfile: gem 'rack-attack'
# config/initializers/rack_attack.rb
class Rack::Attack
throttle('requests/ip', limit: 30, period: 60) do |req|
req.ip unless req.path.start_with?('/health')
end
self.throttled_response = ->(env) {
[429, {}, ['Rate limit exceeded']]
}
end
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 |