HIGH xpath injectionfeathersjsjwt tokens

Xpath Injection in Feathersjs with Jwt Tokens

Xpath Injection in Feathersjs with Jwt Tokens — how this specific combination creates or exposes the vulnerability

XPath Injection occurs when an attacker can manipulate an XPath expression used for querying XML or structured data stores. In FeathersJS, services often rely on external adapters or custom logic that may build XPath strings dynamically. If user-controlled input such as query parameters, route tokens, or request bodies is concatenated into an XPath expression without proper sanitization or parameterization, an attacker can alter the intended logic of the query.

When JWT Tokens are involved, the risk surface changes in two important ways. First, FeathersJS commonly uses JWT payloads to carry user roles, scopes, or identifiers that downstream code may incorporate into data access decisions. If a developer builds an XPath expression using claims from a JWT — for example, userId or role — and does not treat those values as untrusted, the token’s data becomes a conduit for injection. Second, JWT authentication in FeathersJS is typically enforced by hooks that verify the token and attach the decoded payload to the request context. If those hooks expose decoded claims to service logic that builds XPath expressions, an attacker who can influence the token’s payload (via a compromised client or a confused deputy scenario) may indirectly manipulate XPath evaluation.

Consider a FeathersJS service that retrieves user preferences from an XML store. A developer might write a custom adapter that constructs an XPath like this:

<?xml version="1.0" encoding="UTF-8"?>
<preferences>
  <user id="123" theme="dark" />
  <user id="456" theme="light" />
</preferences>

If the code builds the expression using string interpolation based on a JWT claim such as payload.userId, an attacker who can tamper with the token could submit 123" or "1"="1 as the user identifier, causing the XPath to return all user nodes and bypass intended isolation. Even if JWT validation ensures the token is well-formed, the data it carries must still be treated as untrusted input. The combination of FeathersJS service hooks, JWT-based identity propagation, and dynamic XPath construction creates a chain where a single missing sanitization step can lead to unauthorized data access or logic bypass.

middleBrick detects such patterns during unauthenticated scans by analyzing the OpenAPI contract and runtime behavior of the service. It flags places where external input can reach XPath construction paths, even when those paths are downstream of JWT verification. The scanner does not fix the code, but its findings include concrete remediation guidance to help developers separate data from expression logic and enforce strict allowlists on values used in XPath predicates.

Jwt Tokens-Specific Remediation in Feathersjs — concrete code fixes

To prevent XPath Injection when JWT Tokens are used in FeathersJS, treat all data derived from the token as untrusted and avoid building XPath expressions through string concatenation. Instead, use parameterized queries or a safe builder API provided by the underlying XML or database library. Below are concrete examples that demonstrate secure patterns.

Example 1: Using a Parameterized XPath builder

If your XML library supports parameterized queries, bind values explicitly rather than interpolating them.

const xpath = require('xpath');
const { DOMParser } = require('xmldom');

// Safe: using a function that resolves a user ID from the request context
function getUserPreferences(userId) {
  const expr = xpath.select(
    `/preferences/user[@id=${xpath.quote(userId)}]`,
    new DOMParser().parseFromString(xmlData)
  );
  return expr;
}

// In a FeathersJS hook, you would call this with a sanitized value
app.service('preferences').hooks({
  before: {
    get: [context => {
      const userId = context.params.userId; // Ensure this is validated
      context.data = getUserPreferences(userId);
      return context;
    }]
  }
});

Example 2: Strict allowlist validation of JWT claims

Validate JWT-derived values against a strict allowlist before using them in any data access logic.

const jwt = require('jsonwebtoken');

function validateAndExtractUserId(token) {
  const decoded = jwt.verify(token, process.env.JWT_SECRET);
  // Only accept userId if it matches expected pattern
  if (!/^\d{1,10}$/.test(decoded.userId)) {
    throw new Error('Invalid user identifier');
  }
  return decoded.userId;
}

// Usage in a FeathersJS hook
app.hooks({
  before: {
    all: [context => {
      const token = context.headers.authorization?.split(' ')[1];
      if (token) {
        context.params.userId = validateAndExtractUserId(token);
      }
      return context;
    }]
  }
});

// Later, use the validated ID in a service method that queries XML safely
app.service('data').hooks({
  before: {
    find: [context => {
      const userId = context.params.userId;
      // Use parameterized or builder-based access here
      return context;
    }]
  }
});

Example 3: Isolating XPath construction behind a dedicated adapter

Encapsulate XML interactions so that only vetted, parameterized calls reach the XPath layer.

class SafeXmlAdapter {
  constructor(xmlData) {
    this.xmlData = xmlData;
  }

  findUserById(userId) {
    const expr = xpath.select(
      `/preferences/user[@id=${xpath.quote(String(userId))}]`,
      new DOMParser().parseFromString(this.xmlData)
    );
    return expr;
  }
}

// In your FeathersJS service
app.service('users').hooks({
  before: {
    get: [async context => {
      const userId = context.params.query.safeId;
      const adapter = new SafeXmlAdapter(xmlStore.get());
      const result = adapter.findUserById(userId);
      context.result = result;
      return context;
    }]
  }
});

These approaches ensure that JWT-derived values never directly reach XPath expressions. middleBrick can help identify where JWT claims propagate into data access paths by correlating authentication hooks with service logic in unauthenticated scans, providing findings that highlight risky patterns and remediation steps.

Frequently Asked Questions

How does middleBrick handle JWT token validation during scans?
middleBrick performs unauthenticated scans and does not validate JWT tokens itself. It analyzes the API surface to identify places where JWT-derived data could reach sensitive operations such as XPath construction, and reports those findings without assuming token validity.
Can the CLI or GitHub Action fail a build if XPath-related findings are detected?
Yes. With the Pro plan, you can configure the GitHub Action to fail builds when security scores drop below your chosen threshold or when specific finding categories are present, including issues related to data access logic that may involve XPath usage.