HIGH api key exposureexpresspostgresql

Api Key Exposure in Express with Postgresql

Api Key Exposure in Express with Postgresql — how this specific combination creates or exposes the vulnerability

In an Express application that connects to Postgresql, api key exposure typically occurs when secrets are handled as request parameters, logged in detail, or embedded in client-side assets served by the framework. Because Express often routes requests directly to downstream services or databases, a misconfigured endpoint can reflect or forward raw keys through query strings, headers, or response bodies. When the app uses a shared Postgresql instance or schema, the same route that exposes the key may also execute dynamic queries that inadvertently return sensitive metadata, increasing the blast radius.

For example, an endpoint like /api/integration/connect might accept a service key in the body and immediately store or validate it against Postgresql without proper normalization. If the developer uses string concatenation to build queries instead of parameterized statements, the key can leak through error messages or verbose logs, especially when the database returns constraint violations or type mismatches. This is particularly risky when the same Postgresql database holds audit or log tables, because a compromised endpoint can expose keys through seemingly benign read operations.

Another vector involves OpenAPI spec generation and runtime mismatch. If the spec describes a parameter as in: header but the Express route reads it from the query, the tool may flag this as an exposure because the key can appear in URLs that are recorded in server logs or browser history. Postgresql extensions like pg for Node.js may propagate these raw values in stack traces or debug output when connection pooling or query retries occur. Because middleBrick scans the unauthenticated attack surface and cross-references spec definitions with runtime behavior, it can detect these inconsistencies and highlight how an attacker might harvest keys via SSRF or error-driven enumeration.

The LLM/AI Security checks are especially relevant here, because prompt injection probes can test whether an Express endpoint echoes keys back in model inputs or tool calls. For instance, a system prompt that contains a hardcoded Postgresql connection string might be extracted if the app concatenates user input into diagnostic messages. Output scanning then checks whether returned text contains patterns resembling api keys, credentials, or connection strings, which is critical when the service uses LLM integrations to generate documentation or responses.

middleBrick’s inventory management and unsafe consumption checks complement this by verifying whether the Express app declares its dependencies and whether third-party packages introduce known vulnerabilities that facilitate key exfiltration. Data exposure and encryption checks confirm whether keys are transmitted over TLS in practice and whether sensitive fields in Postgresql rows are masked or encrypted at rest. Together, these scans provide a prioritized list of findings with severity and remediation guidance, without modifying the application state.

Postgresql-Specific Remediation in Express — concrete code fixes

Remediation focuses on strict input handling, parameterized queries, and separation of secrets from runtime logic. In Express, avoid placing api keys in query strings or URL fragments; use HTTP-only cookies or encrypted request bodies with strict validation. When interacting with Postgresql, always use prepared statements or an ORM that enforces parameterization to prevent injection paths that could expose keys through error messages.

Example: Safe Connection and Query Handling

Use environment variables for secrets and a connection pool configured with ssl where applicable. Never concatenate user input into SQL strings.

const { Pool } = require('pg');
require('dotenv').config();

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
});

app.post('/api/integration/store-key', async (req, res) => {
  const { serviceKey, metadata } = req.body;

  // Validate input strictly
  if (typeof serviceKey !== 'string' || !/^[A-Za-z0-9\-_]+$/.test(serviceKey)) {
    return res.status(400).json({ error: 'Invalid key format' });
  }

  try {
    // Parameterized query prevents injection and reduces exposure in logs
    const result = await pool.query(
      'INSERT INTO integrations (service_key, metadata) VALUES ($1, $2) RETURNING id',
      [serviceKey, metadata]
    );
    res.json({ id: result.rows[0].id });
  } catch (err) {
    // Avoid exposing raw errors; log securely and return generic message
    console.error('Integration store failed');
    res.status(500).json({ error: 'Internal error' });
  }
});

// Retrieve without exposing key
app.get('/api/integration/:id', async (req, res) => {
  const { id } = req.params;
  try {
    const result = await pool.query(
      'SELECT id, metadata FROM integrations WHERE id = $1',
      [id]
    );
    if (!result.rows.length) {
      return res.status(404).json({ error: 'Not found' });
    }
    // Explicitly omit service_key from response
    res.json(result.rows[0]);
  } catch (err) {
    console.error('Integration fetch failed');
    res.status(500).json({ error: 'Internal error' });
  }
});

For enhanced security, rotate keys regularly and use Postgresql roles with minimal privileges. Create a dedicated read/write user for the integration table and avoid granting superuser access. If your schema includes sensitive columns, consider using application-level encryption before storage, and ensure TLS is enforced for all connections. middleBrick’s Pro plan supports continuous monitoring and CI/CD integration, so you can automatically fail builds if risky patterns are detected in your repository or if scans reveal regressions in how keys are handled.

Schema and Validation Practices

Define your Postgresql schema with constraints that reject malformed or overly permissive values. For example, enforce length limits and character classes on key columns.

-- Safer schema for storing keys
CREATE TABLE integrations (
  id SERIAL PRIMARY KEY,
  service_key TEXT NOT NULL CHECK (length(service_key) BETWEEN 32 AND 128),
  metadata JSONB,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Revocation helper
CREATE OR REPLACE FUNCTION revoke_integration(int_id INT)
RETURNS void AS $$
BEGIN
  UPDATE integrations SET service_key = NULL WHERE id = int_id;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

In Express, validate against the schema before insertion and prefer middleware that normalizes headers and body fields. middleBrick’s Property Authorization checks help ensure that only authorized contexts can access or modify key-bearing resources, reducing BOLA/IDOR risks. By combining strict Postgresql rules with disciplined Express routing, you minimize the conditions under which api keys can be exposed.

Frequently Asked Questions

Can middleBrick prevent api key exposure in Express with Postgresql?
middleBrick detects and reports exposure but does not fix, patch, block, or remediate. It provides findings with remediation guidance so you can adjust your Express routes and Postgresql usage.
Does the free plan include scans for LLM-related key exposure in Express?
The free plan includes 3 scans per month and covers standard checks; LLM/AI Security is available in higher tiers and adds specific probes for prompt injection and key leakage in model outputs.