Xml External Entities in Rails with Cockroachdb
Xml External Entities in Rails with Cockroachdb — how this specific combination creates or exposes the vulnerability
XML External Entity (XXE) injection occurs when an application processes XML input and allows an attacker to control the definition of external entities. In a Ruby on Rails application using CockroachDB as the backend, the vulnerability is introduced not by CockroachDB itself, but by libraries that parse XML and the configuration of the Rails app when handling XML payloads. If Rails is configured to parse XML parameters (for example via ActionDispatch::ParamsParser or legacy SOAP integrations), an attacker can supply a malicious XML document that defines an external entity referencing a sensitive local resource, such as a CockroachDB connection string or a file containing database credentials.
The combination is notable because CockroachDB connection strings often contain hostnames, ports, and database names that can be exfiltrated through an XXE channel. For instance, if the Rails app uses the cockroachdb adapter in database.yml and the connection parameters are accessible to the Rails process (e.g., via environment variables read into config), an attacker can craft an XML payload that causes the parser to open and read /var/secrets/database.yml or probe internal metadata endpoints. This can expose usernames, passwords, and hostnames specific to the CockroachDB cluster, which can then be used in further attacks. Even when using ActiveRecord with CockroachDB, if the application accepts XML input for business logic (for example, importing structured data via an XML upload), and that XML is parsed with entity expansion enabled, an attacker can trigger SSRF-like behavior to reach internal CockroachDB nodes that are not exposed publicly.
An example of a vulnerable Rails initializer might look like this, which inadvertently permits external entity expansion:
# config/initializers/xml_parser.rb
require 'rexml/document'
# Unsafe: enables DOCTYPE and external entities by default
Document.new(xml_string)
In this scenario, an attacker could send an XML payload such as:
<?xml version="1.0"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///var/secrets/database.yml" >]>
<root><data><![CDATA[<%= File.read("/var/secrets/database.yml") %>]]></data></root>
When parsed, the entity &xxe; would be expanded to the contents of the CockroachDB credentials file, leading to data exposure. Therefore, mitigating XXE in Rails with Cockroachdb requires strict control over XML parsing and limiting the exposure of database metadata through the application’s input surfaces.
Cockroachdb-Specific Remediation in Rails — concrete code fixes
To prevent XXE in a Rails application that uses CockroachDB, you must disable external entity processing in any XML parsing performed by the app. This involves changing how you initialize XML parsers and ensuring that any third-party gems that parse XML are configured securely. Below are specific code examples for safe handling of XML in Rails with CockroachDB-backed models.
1. Use a secure XML parser that disables external entities. For example, with Nokogiri, explicitly forbid DTD and entities:
# Safe XML parsing in a Rails service object
require 'nokogiri'
def parse_trusted_xml(xml_string)
# Disable external entities and DTDs
Nokogiri::XML(xml_string) do |config|
config.strict.noblanks
end
# Alternatively, use SAX or Reader APIs for streaming large payloads
end
2. Avoid parsing XML entirely if your use case permits; prefer JSON for API payloads. If you must accept XML, sanitize inputs before parsing:
# In a Rails controller
before_action :ensure_json_or_safe_xml, only: [:import]
def import
# Process only trusted formats
if request.content_type == 'application/json'
data = JSON.parse(request.body.read)
else
# Only parse if you've validated content-type and origin
data = parse_trusted_xml(request.body.read)
end
# Use parameterized attributes to build CockroachDB-backed models
Item.create!(item_params(data))
end
def ensure_json_or_safe_xml
head :unsupported_media_type unless %w[application/json application/xml].include?(request.content_type)
end
3. If your Rails app uses ActiveRecord with CockroachDB, ensure that database configuration is not exposed through user-controlled XML parsing. Store credentials in environment variables and reference them safely:
# config/database.yml (safe pattern)
development:
url: <%= ENV.fetch("COCKROACH_DATABASE_URL") { "postgresql://user:password@localhost:26257/mydb?sslmode=require" } %>
4. For background jobs or scripts that interact with CockroachDB, avoid passing raw XML to ActiveRecord. Instead, map sanitized data to permitted attributes:
# app/models/item.rb
class Item < ApplicationRecord
# Enforce strong parameters in service objects
def self.create_from_xml_data(data_hash)
create!(data_hash.slice(:name, :quantity, :price))
end
end
# Usage in a job or controller
xml_data = parse_trusted_xml(params[:xml])
attrs = { name: xml_data.at_css('name').text, quantity: xml_data.at_css('quantity').to_i }
Item.create_from_xml_data(attrs)
5. Harden the Rails XML parser globally by overriding default parsers in an initializer to reject DOCTYPE declarations:
# config/initializers/xml_security.rb
module ActionDispatch
class Request
def xml_parse
# Reject any XML that contains a DOCTYPE
if body.read.include?('
These steps ensure that XXE vectors cannot leverage Rails’ XML parsing to leak CockroachDB connection details or other sensitive runtime information. Always validate and sanitize XML input, and prefer JSON for new integrations.
Frequently Asked Questions
Can XXE in Rails directly compromise my CockroachDB database?
XXE itself does not directly compromise CockroachDB, but it can expose credentials or connection strings stored in files or environment variables that the Rails process uses to connect to CockroachDB. This can lead to unauthorized access to your database if those credentials are harvested via the XXE vector.
Does middleBrick detect XXE in Rails APIs that interact with Cockroachdb?
Yes, middleBrick scans APIs for XML External Entity injection as part of its Input Validation checks. If your Rails endpoint accepts XML and is vulnerable to XXE, middleBrick will surface this finding with severity and remediation guidance. You can run scans manually via the CLI (middlebrick scan <url>) or automate checks in CI/CD with the GitHub Action.