HIGH data exposureapi keys

Data Exposure with Api Keys

How Data Exposure Manifests in API Keys

API keys are secrets that grant programmatic access to services, and when they are unintentionally leaked they become a direct vector for abuse. Common exposure paths include:

  • Hard‑coded keys in source code that is committed to public repositories.
  • Keys printed to debug logs or console output during development or troubleshooting.
  • Keys reflected in error messages or stack traces returned to the client (e.g., a 500 response that includes the authorization header).
  • Keys transmitted in URLs as query parameters, which may be logged by proxies, browsers, or referrer headers.
  • Keys embedded in client‑side JavaScript or mobile bundles that can be extracted by reverse‑engineering.

For example, a Node.js Express route that logs the full request header can accidentally write a key to a log file:

app.get('/data', (req, res) => {
  console.log('Incoming headers:', req.headers); // <-- may log Authorization: ApiKey xxx
  // …handler logic
});

If the log aggregation system is accessible to attackers or the repository is public, the key is exposed. Similar issues appear in error handling middleware that returns res.status(500).json({ error: err.message, headers: req.headers }), leaking the key in the response body.

Api Keys-Specific Detection

middleBrick’s Data Exposure check looks for API‑key material anywhere in the unauthenticated attack surface. It runs a set of regex patterns that match common key formats (e.g., AWS Access Key IDs, Stripe live keys, Google API keys, Azure storage account keys) against:

  • HTTP response bodies (including JSON, XML, HTML).
  • Response headers such as Authorization, X-Api-Key, or custom headers.
  • Query strings and URL paths (to catch keys placed as ?key=…).
  • JavaScript bundles fetched from the endpoint (passive scanning of static assets).
  • Error messages or stack traces that may be returned in 5xx responses.

When a match is found, the scanner flags it as a Data Exposure finding with severity based on the key’s privilege level (e.g., a key with write access to a production database is marked high). The finding includes the exact location (URL, header name, line number in a JS file) and a short snippet for context.

Real‑world incidents illustrate why this check matters. CVE‑2020-13943 exposed Docker Engine API credentials through daemon logs when users ran docker login with a misconfigured credential store. Similarly, CVE‑2021-22986 showed how an improperly secured F5 BIG‑IP iControl REST endpoint could leak authentication tokens via error responses. middleBrick’s automated checks would detect the leaked key material in the responses or logs associated with those endpoints.

Api Keys-Specific Remediation

The goal is to keep the secret out of any artifact that an attacker can observe. Below are language‑agnostic practices and concrete code snippets.

1. Store keys outside of source code

Use environment variables or a secret manager, and never commit the raw value.

// Node.js – using dotenv (development) or AWS Secrets Manager (production)
require('dotenv').config();
const apiKey = process.env.MY_API_KEY;
if (!apiKey) {
  throw new Error('Missing MY_API_KEY environment variable');
}
// …use apiKey in requests

For AWS Lambda:

const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager');
const secretsClient = new SecretsManagerClient({});

export const handler = async () => {
  const data = await secretsClient.send(new GetSecretValueCommand({
    SecretId: 'prod/my-api-key'
  }));
  const apiKey = JSON.parse(data.SecretString).key;
  // …call downstream API
};

2. Avoid logging or returning the key

Strip the Authorization header from logs and never echo it in error responses.

// Express middleware to sanitize logs
app.use((req, res, next) => {
  const safeHeaders = { ...req.headers };
  delete safeHeaders.authorization;
  delete safeHeaders['x-api-key'];
  console.log('Request headers (sanitized):', safeHeaders);
  next();
});

// Central error handler – do not include request headers
app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).json({ error: 'Internal Server Error' });
});

3. Do not place keys in URLs

Prefer header‑based authentication; if a third‑party API forces query‑string keys, use a proxy that injects the header and removes the query parameter before forwarding.

// Simple Node proxy that moves a query‑string key to a header
app.get('/proxy/*', async (req, res) => {
  const key = req.query.key;
  if (!key) return res.status(400).send('Missing key');
  const targetUrl = req.params[0];
  const proxyReq = http.request(targetUrl, {
    method: req.method,
    headers: { ...req.headers, 'x-api-key': key }
  }, proxyRes => {
    res.writeHead(proxyRes.statusCode, proxyRes.headers);
    proxyRes.pipe(res);
  });
  req.pipe(proxyReq);
});

4. Rotate and limit scope

Issue short‑lived keys or tokens, restrict them to the least privilege needed, and automate rotation via your secret manager’s lifecycle policies.

By applying these defenses, the Data Exposure check in middleBrick will no longer find API‑key material in the unauthenticated surface, and the overall security score will improve.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

How does middleBrick know whether a found string is a real API key and not a false positive?
middleBrick applies a combination of regex patterns that match known key formats (e.g., AWS AKIA..., SK_live..., AIza...) and then validates the context—such as appearing in an Authorization header or a query parameter named key—before issuing a finding. This reduces false positives while still catching genuine leaks.
If I scan a staging API and middleBrick reports a Data Exposure finding for an API key, what should I do first?
Immediately rotate the exposed key, then remove it from any source code, logs, or configuration files where it was stored. After rotation, rescan to confirm the finding is resolved before promoting the build to production.