HIGH injection flawssailsbearer tokens

Injection Flaws in Sails with Bearer Tokens

Injection Flaws in Sails with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Injection flaws in Sails applications that rely on Bearer Tokens for authentication occur when untrusted input is concatenated into commands or queries without proper validation or parameterization. A Bearer Token is typically passed in the Authorization header as Authorization: Bearer <token>; while this header itself is not directly responsible for injection, its presence can shift developer attention away from treating other inputs as untrusted. For example, a route like /user/:userId/reports that uses the token for auth might still embed userId directly into a database query or a NoSQL selector. If userId is controlled by an attacker and is not validated, it can lead to Injection, including `Prototype Pollution` in JavaScript contexts or query manipulation in ORM/ODM layers.

In Sails, which is built on Waterline ORM, injection often manifests through improperly constructed Waterline queries. Consider a service that builds a query using user input combined with token-derived metadata: Report.find({ owner: req.token.orgId, id: req.param('id') }). If req.param('id') is user-supplied and not sanitized, an attacker might supply { id: { '>': 0 } } or a string-based injection payload depending on the adapter, potentially bypassing intended filters. Similarly, with native queries, concatenation such as `SELECT * FROM reports WHERE org_id = ${req.token.orgId} AND name = '${req.body.name}'` is hazardous if any part of the input flows from the request.

Bearer Tokens themselves do not cause injection, but they can encourage unsafe patterns when developers assume authenticated requests are automatically safe. For instance, using token attributes directly in dynamic queries without type checks can lead to Server-Side Request Forgery (SSRF) when a token-controlled field is used to build URLs or access internal resources. An attacker who can influence a token-associated field (e.g., a tenant identifier) might coerce the server into making internal network calls. This is compounded when token validation is decoupled from input validation, and the developer trusts the token’s embedded claims without re-validating against the specific operation’s constraints.

Another scenario involves logging or error handling. If a Bearer Token is reflected in logs alongside unchecked user input, an attacker might inject crafted strings intended to be stored and later rendered in an admin UI or exported report, leading to stored XSS or log injection. While Sails does not inherently introduce injection, its flexibility around adapters and policies means developers must consistently apply parameterization and strict schema validation across all inputs, regardless of the presence of a Bearer Token.

Real-world parallels include CVEs affecting Node.js ORM layers where string-based query fragments were improperly handled. Although Sails-specific CVEs are rare, the pattern aligns with the broader OWASP API Top 10 category A03:2021 — Injection. The risk is elevated when APIs accept complex filter objects that are merged with token-derived context, especially in bulk update or aggregation operations. Attackers probe such endpoints with nested objects or unusual operators to test whether injection is possible. Proper mitigation requires treating all user-influenced data as hostile, even when an authenticated Bearer Token is present, and enforcing schema-based validation and strict type checks before constructing any command or query.

Bearer Tokens-Specific Remediation in Sails — concrete code fixes

Remediation focuses on strict input validation, parameterized queries, and avoiding direct concatenation of user or token data into commands. For Bearer Token usage, ensure tokens are validated through a standard library or middleware and not manually parsed or concatenated into responses or logs. Below are concrete, working examples for Sails that demonstrate secure handling.

Example 1: Parameterized Waterline Query

Instead of building queries via string interpolation or unsafe object merging, use Waterline’s built-in parameterization. This ensures that user input is treated as values, not executable code.

// api/controllers/ReportController.js
module.exports = {
  async getReport(req, res) {
    // Validate and cast input
    const id = parseInt(req.param('id'), 10);
    if (isNaN(id)) {
      return res.badRequest('Invalid report ID');
    }

    // Use Waterline criteria safely; values are parameterized
    const report = await Report.findOne({
      where: {
        orgId: req.token.orgId,
        id: id
      }
    });

    if (!report) {
      return res.notFound();
    }
    return res.ok(report);
  }
};

Example 2: Sanitized Native Query with Token Context

When using native queries, use placeholders and pass values separately to avoid injection. This applies even when using token-derived fields like orgId.

// api/services/ReportService.js
async function getReportsForOrg(req) {
  const orgId = req.token.orgId;
  const name = req.body.name;

  // Use parameterized query with ? placeholders
  const results = await sails.sendNativeQuery(
    'SELECT * FROM reports WHERE org_id = $1 AND name = $2',
    [orgId, name]
  );
  return results.rows;
}

module.exports = { getReportsForOrg };

Example 3: Input Validation and Schema Enforcement

Use a validation library or Sails’ built-in policies to enforce types and constraints before processing. This prevents malicious payloads from reaching query builders.

// api/policies/validateReportInput.js
const Ajv = require('ajv');
const ajv = new Ajv();

const schema = {
  type: 'object',
  required: ['id'],
  properties: {
    id: { type: 'integer', minimum: 1 },
    filter: {
      type: 'string',
      pattern: '^[a-zA-Z0-9_]+$'
    }
  },
  additionalProperties: false
};

module.exports = async function (req, res, proceed) {
  const valid = ajv.validate(schema, req.allParams());
  if (!valid) {
    return res.badRequest({ errors: ajv.errors });
  }
  return proceed();
};

Example 4: Securing Token Usage in Logging

Avoid reflecting raw tokens or unchecked user input in logs. If logging is necessary, sanitize and separate sensitive fields.

// api/services/audit.js
function safeLog(action, token, userInput) {
  // Do not concatenate token directly with unescaped userInput
  const sanitizedInput = userInput.replace(/[\\\n\r]/g, '_');
  sails.log.info(`[${new Date().toISOString()}] action=${action} userOrg=${token.orgId} input=${sanitizedInput}`);
}

module.exports = { safeLog };

Example 5: Policy to Enforce Token Binding

Ensure that operations respect token-derived context by binding requests to validated tenant or org identifiers early in the lifecycle.

// api/policies/ensureTokenBinding.js
module.exports = async function (req, res, next) {
  if (!req.token || !req.token.orgId) {
    return res.unauthorized('Missing token context');
  }

  // Attach validated orgId to request for downstream use
  req.orgId = req.token.orgId;
  return next();
};

Frequently Asked Questions

How does middleBrick detect injection risks related to Bearer Tokens in Sails APIs?
middleBrick runs 12 parallel security checks, including Input Validation and Property Authorization, scanning unauthenticated attack surfaces. It analyzes OpenAPI/Swagger specs (with $ref resolution) and runtime behavior to identify places where user input may be improperly concatenated into commands or queries, even when Bearer Tokens are used for authentication. Findings include severity, CWE references, and remediation guidance mapped to frameworks like OWASP API Top 10.
Can middleBrick be integrated into CI/CD to fail builds if an API’s risk score is too high?
Yes. The Pro plan includes a GitHub Action that adds API security checks to your CI/CD pipeline and can fail builds if the security score drops below your configured threshold. This helps prevent risky changes from reaching production while using the same scanning engine that evaluates Bearer Token handling and injection surfaces.