HIGH crlf injectionsailsapi keys

Crlf Injection in Sails with Api Keys

Crlf Injection in Sails with Api Keys — how this specific combination creates or exposes the vulnerability

Crlf Injection occurs when an attacker can inject carriage return (CR, \r) and line feed (\n) characters into a header or log entry, causing header splitting or log forging. In Sails.js, this risk is compounded when API keys are handled in a way that incorporates untrusted input into headers or response lines. For example, if a Sails controller uses an API key from a request header and directly reflects it into another header or log without sanitization, an attacker can supply a key containing \r\n sequences to inject additional headers or manipulate the protocol flow.

Consider a Sails endpoint that forwards requests to an upstream service using an API key passed via a custom header like X-API-Key. If the application constructs a new header by concatenating user input, such as a value from req.headers['x-forwarded-apikey'], an attacker can supply a key like: valid_key_value\r\nX-Admin: true. When the Sails app forwards or logs this header, the injected CRLF can create an additional header or split a log line, enabling response splitting, HTTP response smuggling, or log injection. This is especially dangerous when combined with logging mechanisms that write the API key and related headers to files, as the injected lines may appear as separate log entries, bypassing simple log-based monitoring.

In Sails, middleware and policies often process API keys and route logic in a way that may not enforce strict input validation on header values. If an API key is extracted from headers and used in templated responses or server-side logs, CRLF injection can distort structured outputs. For instance, an attacker might include \r\nSet-Cookie: session=stolen in the API key and, if the server embeds the key into a response header without sanitization, the injected line can execute in the client’s browser context. The risk is not in the API key itself being secret, but in how the Sails application handles and reflects the key when it includes newline characters.

OpenAPI specifications used by middleBrick can help identify endpoints that accept or return headers containing API keys, and the runtime checks can detect whether reflected API key values are properly sanitized. During a scan, middleBrick tests whether inputs that contain CRLF sequences are escaped before being placed into headers or logs. This is part of the broader Input Validation and Data Exposure checks that run in parallel, which help surface places where newline characters in API keys or header values can lead to injection or log forgery.

Api Keys-Specific Remediation in Sails — concrete code fixes

To mitigate Crlf Injection when handling API keys in Sails, ensure that any user-supplied or reflected values are sanitized before being used in headers, logs, or responses. The core principle is to disallow or neutralize CR and LF characters in API key values that are processed by Sails controllers, policies, or services.

One approach is to validate API key values at the point they enter your Sails application, such as in a request hook or a custom policy. For instance, you can define a policy that rejects API keys containing \r or \n:

// api/policies/validate-api-key.js
module.exports = function validateApiKey(req, res, next) {
  const apiKey = req.headers['x-api-key'] || '';
  if (/[\r\n]/.test(apiKey)) {
    return res.status(400).send({ error: 'Invalid API key' });
  }
  return next();
};

Apply this policy to relevant routes in config/policies.js:

// config/policies.js
module.exports.policies = {
  '*': ['validateApiKey'],
  'ApiController': {
    'create': ['validateApiKey', 'findOrCreate']
  }
};

When you need to forward or log API keys, ensure they are normalized by stripping or encoding problematic characters. For example, if you must log the key, explicitly remove CRLF before writing to logs:

// api/helpers/logger.js
const cleanForLog = (value) => {
  if (typeof value !== 'string') return value;
  return value.replace(/[\r\n]+/g, '');
};

module.exports = {
  logApiKey: (key) => {
    const safeKey = cleanForLog(key);
    sails.log.info('API key processed:', { key: safeKey });
  }
};

If your Sails app proxies requests using an API key, avoid directly concatenating user input into header strings. Instead, use a map of allowed headers and explicitly set known-safe values:

// api/services/forward-service.js
const axios = require('axios');

module.exports.forwardService = async function forwardService(apiKey, userData) {
  const headers = {
    'X-API-Key': apiKey.replace(/[\r\n]/g, ''),
    'Content-Type': 'application/json'
  };
  try {
    const response = await axios.post('https://upstream.example.com/resource', userData, { headers });
    return response.data;
  } catch (err) {
    sails.log.error('Forward error:', err);
    throw err;
  }
};

For applications using middleBrick, the CLI can be run as part of your workflow to detect endpoints where API keys are reflected in headers or logs. Use middlebrick scan <url> to identify potential injection issues and review the findings in the Web Dashboard or via JSON output. The Pro plan’s continuous monitoring can help ensure that new endpoints or changes to header handling do not reintroduce CRLF risks when API keys are involved, and the GitHub Action can gate merges if a scan detects problematic patterns.

Frequently Asked Questions

How can I test my Sails API for CRLF injection using API keys?
You can use the middleBrick CLI to scan your endpoint: middlebrick scan https://your-api.example.com/endpoint. Include API keys in requests as headers, and review the report for input validation findings related to CRLF sequences.
Does middleBrick fix CRLF injection in Sails when API keys are involved?
middleBrick detects and reports CRLF injection risks and provides remediation guidance. It does not fix or patch your code; you must apply the suggested input validation and sanitization fixes in your Sails application.