HIGH api key exposuresailssaml

Api Key Exposure in Sails with Saml

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

When Sails.js applications integrate SAML for authentication, developers often focus on the identity provider (IdP) flow and may inadvertently expose API keys or session material in areas that interact with SAML assertions or attributes. In a Sails app, configuration for SAML typically lives in config/saml.js or an environment-specific equivalent, and it may include values such as private keys, certificates, or metadata endpoints that should remain server-side. If these configuration values are accidentally serialized, logged, or passed to untrusted client-side code—such as embedded in views, exposed through REST endpoints, or returned in error messages—an API key or secret tied to the SAML integration can be disclosed.

Consider a Sails controller that retrieves a SAML setting for use in a downstream service. If the controller action returns the entire settings object to the browser or an unauthenticated endpoint, a consumer of the API can learn sensitive configuration details, including keys or URIs that should be protected. This becomes particularly risky when the SAML setup uses per-service keys or when metadata is fetched dynamically at runtime and cached insecurely. The exposure may not be limited to configuration: if SAML assertions are transformed into session tokens or JWTs and the generation process includes a static secret or key material, that material must never be reflected in responses or logs.

Additionally, in a service-oriented architecture, Sails services may call external APIs that require keys for authorization. If those keys are stored in Sails configuration files that are inadvertently exposed through source control or build artifacts, and if the application also exposes SAML-related endpoints without proper access controls, an attacker who can view logs, error pages, or metadata endpoints may piece together both the SAML configuration and associated API credentials. This combination elevates the severity of otherwise low-severity misconfigurations because it can allow an attacker to assume identity or escalate privileges across integrated systems. The risk is compounded when the SAML integration relies on signed assertions and the signing key is mishandled alongside other credentials.

Another vector involves the handling of SAML metadata. Some Sails implementations expose metadata at runtime via an unauthenticated route for service discovery or federation. If metadata retrieval is not strictly guarded and if the application uses a static key pair for signing metadata or assertions, the key material may be inferable or derivable from public endpoints when combined with other exposed information. Even when metadata is intended to be public, any embedded key references or configuration hints should be stripped before exposure. Runtime inspection of requests and responses using the middleBrick CLI tool can reveal whether SAML-related configuration or keys appear in unauthenticated scan results, helping to confirm whether exposure is occurring.

To detect these patterns, scanning with middleBrick against the Sails endpoint can surface whether SAML configuration details or related API keys appear in responses, headers, or error payloads. The scanner runs multiple checks in parallel, including Authentication, Data Exposure, and Unsafe Consumption, which can identify improper exposure of sensitive data in unauthenticated contexts. By correlating scan findings with your SAML configuration, you can pinpoint whether keys or secrets are being reflected in application behavior and prioritize remediation around configuration isolation and strict access controls.

Saml-Specific Remediation in Sails — concrete code fixes

Remediation centers on ensuring that SAML configuration and any derived keys remain server-side and are never returned to the client. Start by auditing config/saml.js and related environment files to confirm that private keys, certificates, and secrets are not referenced in views, responses, or logs. Use environment variables for sensitive values and restrict access to configuration endpoints.

Below is a minimal, secure SAML configuration for a Sails app that avoids exposing keys in responses. The configuration is loaded from environment variables and is not serialized into views or API payloads.

// config/saml.js
module.exports.saml = {
  entryPoint: process.env.SAML_ENTRY_POINT,
  issuer: process.env.SAML_ISSUER || 'https://sails.example.com',
  cert: process.env.SAML_CERT_PUBLIC,
  privateCert: process.env.SAML_PRIVATE_KEY,
  callbackUrl: 'https://sails.example.com/auth/saml/callback',
  identifierFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
  validateInResponseTo: false,
  disableRequestedAuthnContext: true
};

In your controller, avoid returning configuration objects. Instead, use a lightweight action that confirms authentication status without exposing settings.

// api/controllers/AuthController.js
module.exports = {
  status: async function (req, res) {
    // Do not send SAML configuration or keys to the client
    return res.ok({
      authenticated: req.isAuthenticated(),
      user: req.user ? { id: req.user.id, email: req.user.email } : null
    });
  }
};

If your app generates or caches SAML metadata, serve it only over authenticated admin routes and strip any key references from metadata intended for general federation.

// api/actions/saml-metadata.js
module.exports = async function (req, res) {
  if (!req.isAuthenticated || !req.user.isAdmin) {
    return res.unauthorized('Access denied');
  }
  const metadataBuilder = require('saml-metadata');
  const metadata = metadataBuilder({
    entityID: process.env.SAML_ISSUER,
    cert: process.env.SAML_CERT_PUBLIC,
    signKey: process.env.SAML_PRIVATE_KEY,
    callbackUrl: 'https://sails.example.com/auth/saml/callback'
  });
  return res.type('text/xml').send(metadata);
};

Ensure that any logging in Sails does not include sensitive configuration values. Wrap the SAML strategy initialization to prevent accidental logging of keys during development.

// config/passport.js
const passport = require('passport');
const SamlStrategy = require('passport-saml').Strategy;
const samlConfig = require('../config/saml');

passport.use(new SamlStrategy(
  {
    entryPoint: samlConfig.entryPoint,
    issuer: samlConfig.issuer,
    cert: samlConfig.cert,
    privateCert: samlConfig.privateCert,
    callbackUrl: samlConfig.callbackUrl,
    identifierFormat: samlConfig.identifierFormat
  },
  function(profile, done) {
    // Do not log profile or keys
    return done(null, profile);
  }
));

Finally, review routes and policies to ensure that SAML endpoints and configuration routes are not exposed to unauthenticated users and that sensitive values are omitted from any client-facing payloads. Use the middleBrick CLI to scan your deployed Sails endpoints and verify that no API keys or configuration details appear in unauthenticated responses.

Frequently Asked Questions

Can SAML metadata endpoints expose API keys in Sails?
Yes, if metadata is served from an unauthenticated route and includes key references or hints, it can expose sensitive information. Serve metadata only over authenticated admin routes and remove private key material before exposure.
How can I detect accidental API key exposure in SAML flows using middleBrick?
Run the middleBrick CLI against your Sails endpoints to check whether configuration values or keys appear in responses. The Data Exposure and Unsafe Consumption checks can highlight reflective leaks in unauthenticated contexts.