HIGH llm data leakagehapiapi keys

Llm Data Leakage in Hapi with Api Keys

Llm Data Leakage in Hapi with Api Keys — how this specific combination creates or exposes the vulnerability

When an Hapi server exposes API keys in logs, error messages, or server-side debug output, it can enable LLM data leakage. An LLM-based endpoint hosted alongside or behind the Hapi service might inadvertently echo keys present in request context, training data, or runtime traces. Attackers can use prompt injection techniques to trick the LLM into revealing the keys or sensitive data that were inadvertently surfaced through the API layer, leading to unauthorized access or data exfiltration.

Hapi does not inherently leak keys, but common integration patterns do. For example, attaching API keys to request extensions, logging full request headers, or including credentials in error payloads can expose sensitive values to an LLM endpoint if the LLM processes or mirrors incoming data. Consider an Hapi route that forwards an API key in an Authorization header to a downstream service and also passes the entire request context to an LLM for analysis. If the LLM output is not carefully constrained, it might reproduce the key in its response, especially when probed via jailbreak or data exfiltration tests. This violates the principle of keeping secrets out of model inputs and outputs.

Another vector arises from environment variables and configuration files. If Hapi applications load API keys from environment variables and those values appear in logs, crash reports, or stack traces, an LLM endpoint that reads logs or crash data can be manipulated into extracting them. For instance, an attacker might send a crafted request that triggers an error, causing the Hapi server to log the key, and then use prompt injection to coax the LLM into repeating the logged key. This combination amplifies risk because the LLM becomes a channel for data exfiltration across service boundaries.

Middleware and pre-registered extensions that inspect or modify headers can also contribute to leakage. If an Hapi extension captures and stores API keys in request state for logging or monitoring, and an LLM handler later outputs state contents without redaction, keys can be exposed. This is particularly dangerous when the LLM endpoint is publicly accessible and subject to active prompt injection testing, as outlined in the LLM/AI Security checks which include system prompt leakage detection and active prompt injection probes. Without strict input and output controls, the API key moves from a protected credential to a potential prompt that an attacker can extract.

To understand the exposure, consider a realistic scenario: an Hapi route authenticates a request using an API key, then calls an LLM endpoint to summarize or classify the request. If the implementation serializes the full authenticated context—including the key—into the prompt or passes it as part of tool arguments, the LLM may include the key in its response. The LLM/AI Security checks specifically test for such leakage by scanning outputs for API keys and PII. This demonstrates why Hapi integrations must sanitize context before LLM consumption and enforce strict output validation to prevent inadvertent disclosure of credentials.

Api Keys-Specific Remediation in Hapi — concrete code fixes

Remediation focuses on preventing API keys from appearing in logs, error messages, and LLM inputs or outputs. In Hapi, use request sanitization, selective serialization, and output filtering to ensure keys are not propagated to downstream services or LLM endpoints.

Example: Configure Hapi to redact API keys from logs and error payloads. By customizing the logging and error handling, you prevent keys from being captured in places an LLM might read.

// server.js
const Hapi = require('@hapi/hapi');

const init = async () => {
  const server = Hapi.server({
    port: 3000,
    host: 'localhost'
  });

  // Log sanitization: remove sensitive headers before logging
  server.ext('onPreResponse', (request, h) => {
    const response = request.response;
    if (response.isBoom) {
      // Ensure API keys are not reflected in error output
      const sanitized = { ...response.output.payload };
      if (sanitized.headers && sanitized.headers['authorization']) {
        sanitized.headers['authorization'] = '[REDACTED]';
      }
      response.output.payload = sanitized;
    }
    return h.continue;
  });

  server.route({
    method: 'POST',
    path: '/api/query',
    options: {
      handler: (request, h) => {
        const apiKey = request.headers['authorization'];
        // Do not attach key to request state used by LLM
        const safeContext = {
          userId: request.auth.credentials && request.auth.credentials.userId
        };
        // Call downstream or LLM with safeContext only
        return h.response({ context: safeContext });
      },
      validate: {
        headers: Joi.object({
          authorization: Joi.string().required().description('API key for auth only, not forwarded')
        }).unknown()
      }
    }
  });

  await server.start();
  console.log('Server running on %s', server.info.uri);
};

init().catch(err => {
  console.error(err);
});

Example: Avoid echoing API keys in LLM prompts by explicitly excluding them from the prompt payload. Pass only necessary, non-sensitive data to the LLM handler.

// llmHandler.js
const callLlm = async (request) => {
  const { query } = request.payload;
  const apiKey = request.headers['authorization'];

  // Build prompt without including the key
  const prompt = `Classify the following query: ${query}`;

  // Send only the prompt and necessary metadata to the LLM endpoint
  const response = await fetch('https://llm.example.com/v1/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      // Do not forward API key to LLM endpoint
    },
    body: JSON.stringify({ prompt })
  });

  const data = await response.json();
  return data.choices[0].text;
};

// In your Hapi route
server.route({
  method: 'POST',
    path: '/ask',
    options: {
      handler: async (request) => {
        return await callLlm(request);
      }
    }
});

Example: Use environment variable access patterns that avoid logging. Load keys into memory without writing them to files or stdout, and ensure crash reporters do not capture them.

// config.js
require('dotenv').config();
const apiKey = process.env.API_KEY; // Keep key in memory, avoid logging

if (!apiKey) {
  throw new Error('API_KEY environment variable is required');
}

module.exports = { apiKey };

These practices reduce the likelihood of LLM data leakage by ensuring API keys stay within secure boundaries and are not inadvertently surfaced in logs, error responses, or LLM interactions.

Related CWEs: llmSecurity

CWE IDNameSeverity
CWE-754Improper Check for Unusual or Exceptional Conditions MEDIUM

Frequently Asked Questions

How can I test if my Hapi API is leaking API keys to an LLM endpoint?
Use active prompt injection probes and output scanning for API keys. Tools that include LLM/AI Security checks can send sequential probes (system prompt extraction, instruction override, DAN jailbreak, data exfiltration, cost exploitation) and inspect LLM responses for exposed keys. Ensure your Hapi routes do not pass API keys into LLM prompts or tool arguments, and verify sanitized logging and error handling.
Does middleBrick detect LLM data leakage involving API keys in Hapi integrations?
Yes, middleBrick includes LLM/AI Security checks that detect system prompt leakage and scan outputs for API keys and PII. It tests active prompt injection vectors and examines whether LLM endpoints inadvertently echo secrets from the API layer, helping identify data leakage risks in integrations that involve API keys.