HIGH api key exposuresailsjavascript

Api Key Exposure in Sails (Javascript)

Api Key Exposure in Sails with Javascript — how this specific combination creates or exposes the vulnerability

In Sails applications written in JavaScript, API keys often live in configuration files, environment variables, or are passed into frontend code during builds. Because Sails encourages convention-over-configuration and rapid development, developers sometimes embed keys directly in code or expose them through controller actions and policies. When these keys reach the client—whether through views, JSON responses, or auto-documented endpoints—they become exposed to anyone who can inspect network traffic or source maps.

JavaScript running in Node.js on the server can accidentally leak keys through verbose error messages, debug logs, or improper serialization. Sails blueprints and REST routes may return full model instances that include attributes holding key-like strings if the model definition or model lifecycle callbacks are not carefully scoped. Inconsistent use of select or projection when querying can cause sensitive columns to be included in results served to the client or logged by the framework.

Another common pattern is using environment variables via process.env in Sails configuration files. If these files are committed to version control or served statically, the keys become discoverable. Sails’ hook system can also expose keys if custom hooks or third-party hooks do not properly restrict access to configuration. During local development, the REPL and debug consoles in Sails provide interactive access to the app’s models and configuration, which can inadvertently surface keys if a developer runs commands without considering the security context.

Because Sails can generate OpenAPI specs dynamically or expose API documentation in development mode, keys that appear in query parameters, headers, or request bodies may be reflected in these documents. If authentication is not enforced on documentation routes, an unauthenticated attacker can harvest keys directly from the spec. The JavaScript runtime does not inherently redact sensitive values, so any logging or serialization that includes the full request or response objects can propagate keys to logs, error trackers, or browser consoles.

When conducting an unauthenticated scan with middleBrick, the API Security checks targeting API Key Exposure analyze configuration endpoints, error payloads, and documentation routes. The scanner looks for patterns where keys are returned in JSON structures, present in HTTP headers, or embedded in client-side assets. Findings include the specific route, the method, and the location of the exposure, along with remediation guidance focused on scoping, redaction, and access controls.

Javascript-Specific Remediation in Sails — concrete code fixes

To reduce API key exposure in Sails with JavaScript, start by ensuring keys are never serialized into responses or views. Use selective attributes when fetching records and avoid returning entire model instances to the client. Below are concrete code examples that demonstrate secure patterns.

1. Restrict attributes in blueprint responses

Configure models to exclude sensitive attributes from default JSON output. In your model file, use toJSON to strip keys before serialization.

// api/models/User.js
module.exports = {
  attributes: {
    username: { type: 'string' },
    email: { type: 'string' },
    apiKey: { type: 'string', select: false } // hidden by default
  },
  toJSON: function(obj, ret, options) {
    ret.apiKey = undefined;
    return ret;
  },
  toJSONExtended: function(obj, ret, options) {
    ret.apiKey = undefined;
    return ret;
  }
};

2. Use policies to enforce authentication on sensitive routes

Protect endpoints that could expose configuration or key material with a policy that checks for valid session or token presence.

// api/policies/ensureAuthenticated.js
module.exports = function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated && req.user) {
    return next();
  }
  return res.unauthorized('Access denied.');
};

// config/policies.js
module.exports.policies = {
  'UserController': {
    'viewKey': 'ensureAuthenticated'
  }
};

3. Safely load environment variables without exposing them

Keep keys out of version control and avoid logging them. Use environment variables and reference them in configuration without assigning them to global or shared objects inadvertently.

// config/env/development.js
module.exports = {
  sails: {
    hookTimeout: 5000
  },
  api: {
    key: process.env.API_KEY || 'dev-key-placeholder'
  }
};

4. Scopes blueprint actions and limit data returned

Override blueprint actions to return only necessary fields and ensure queries use projection to exclude sensitive columns.

// api/controllers/UserController.js
module.exports = {
  findOne: async function(req, res) {
    const result = await User.findOne(req.params.id).select(['id', 'username', 'email']);
    if (!result) return res.notFound();
    return res.ok(result);
  }
};

5. Disable or protect API documentation in production

Ensure Swagger/OpenAPI endpoints are not publicly accessible in production and do not reflect sensitive parameter values.

// config/routes.js
module.exports.routes = {
  '/docs': {
    controller: 'DocumentationController',
    skipAssets: true
  }
};

// config/swagger.js
module.exports.swagger = {
  enabled: false // set to true only in trusted environments
};

6. Sanitize error messages to avoid key leakage

Custom error handlers should avoid echoing raw inputs or configuration details that might contain keys.

// config/errors.js
module.exports.errors = {
  custom: {
    'E_VALIDATION': function(errors) {
      // Return generic messages, never include raw values or keys
      return 'Validation error.';
    }
  }
};

Frequently Asked Questions

How can I verify that API keys are not exposed in error responses in my Sails JavaScript app?
Trigger controlled error scenarios and inspect responses for keys. Use middleBrick to scan your endpoints; it checks error payloads and documentation routes for exposed sensitive values and will report any findings with remediation guidance.
Does Sails JavaScript automatically redact API keys from logs and browser console?
No, the JavaScript runtime does not redact values. You must explicitly exclude sensitive attributes in model serializers and avoid logging full request or response objects. middleBrick findings can highlight routes where keys appear in responses or documentation.