Xml External Entities in Restify with Hmac Signatures
Xml External Entities in Restify with Hmac Signatures — how this specific combination creates or exposes the vulnerability
XML External Entity (XXE) injection occurs when an XML parser processes external entity references embedded in XML data. In Restify, if an API endpoint accepts XML payloads and does not disable external entity resolution, an attacker can leverage DTDs (Document Type Definitions) to read local files, trigger SSRF, or cause denial of service. When Hmac Signatures are used for request authentication, the presence of XXE can undermine integrity checks and lead to bypass scenarios.
Consider a Restify service that validates an Hmac Signature header to ensure request authenticity. The signature is typically computed over selected parts of the request, such as selected headers and the request body. If the body contains an external entity, the XML parser may expand the entity before the request body is hashed for the Hmac calculation. This can result in a mismatch between the client’s signature and the server’s computed signature if the server’s parser resolves entities differently. Conversely, an attacker may supply a benign Hmac that passes server-side verification while the expanded entity causes unintended behavior on the server or backend systems.
In practice, an attacker might send an XML payload like the following to a Restify endpoint expecting JSON but configured to accept XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >] >
<root>&xxe;</root>
If the Restify XML parser resolves &xxe;, the server may read /etc/passwd. Even when Hmac Signatures are enforced, the server might still process the expanded entity before signature validation, depending on middleware ordering. Moreover, the Hmac key itself could be exfiltrated if the server’s response incorporates data derived from the entity expansion, allowing the attacker to learn secret material indirectly. This combination highlights that Hmac Signatures do not inherently prevent XXE; they must be paired with secure XML handling to avoid bypass.
Another scenario involves an attacker probing for unauthenticated LLM endpoints or using XXE to infer internal network topology via SSRF induced by external entities. While middleBrick scans detect such patterns in unauthentated LLM endpoints and data exposure, developers must ensure XML parsers are hardened and that Hmac verification occurs after input validation and entity resolution is disabled.
Hmac Signatures-Specific Remediation in Restify — concrete code fixes
To remediate XXE in Restify when using Hmac Signatures, configure the XML parser to disallow external entities and perform Hmac verification on safe, normalized input. Below are concrete, working examples for Restify that demonstrate secure handling.
First, ensure your XML parser is set to not resolve external entities. For example, using the xml2js parser with explicit options:
const xml2js = require('xml2js');
const parser = new xml2js.Parser({
explicitArray: false,
ignoreAttrs: false,
entityReplacement: '' // prevent external entity expansion
});
function parseXmlSafe(xml, callback) {
parser.parseString(xml, (err, result) => {
if (err) return callback(err);
callback(null, result);
});
}
Second, compute and verify the Hmac Signature after safely parsing the XML. This ensures the signature covers the normalized data you intend to validate, not the raw XML that may include external references:
const crypto = require('crypto');
const sharedSecret = process.env.HMAC_SECRET; // store securely
function computeHmac(data) {
return crypto.createHmac('sha256', sharedSecret).update(data).digest('hex');
}
function verifyRequest(req) {
const received = req.headers['x-hmac-signature'];
// Use normalized string representation of the parsed payload
const normalized = JSON.stringify(req.safeParsedBody);
const expected = computeHmac(normalized);
return crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
}
In a Restify route, combine safe parsing and Hmac verification:
const restify = require('restify');
const server = restify.createServer();
server.post('/api/resource', (req, res, next) => {
if (req.headers['content-type'] && req.headers['content-type'].includes('xml')) {
parseXmlSafe(req.body, (err, parsed) => {
if (err || !verifyParsedRequest(req, parsed)) {
return res.send(400, { error: 'Invalid signature or unsafe XML' });
}
req.safeParsedBody = parsed;
// proceed with business logic
res.send(200, { status: 'ok' });
return next();
});
} else {
// handle non-XML paths or reject
return res.send(415, { error: 'Unsupported media type' });
}
});
Key remediation steps include:
- Disable external general entities and parameter entities in the XML parser.
- Normalize the parsed structure before Hmac computation to ensure deterministic input.
- Perform Hmac verification after parsing and validation, not on raw XML.
- Use environment variables for Hmac secrets and rotate them regularly.
By applying these measures, the API maintains the integrity guarantees of Hmac Signatures while eliminating the XXE attack surface. Note that findings such as these are surfaced by middleBrick scans, which provide prioritized findings with severity and remediation guidance to help you address such issues.