HIGH api key exposurenestjsmysql

Api Key Exposure in Nestjs with Mysql

Api Key Exposure in Nestjs with Mysql — how this specific combination creates or exposes the vulnerability

When an API built with NestJS interacts with a MySQL database, improper handling of sensitive values such as API keys can lead to exposure through multiple vectors. A common pattern is storing third-party service keys in a database table, such as integration_keys, and retrieving them at runtime. If the NestJS application does not enforce strict field-level filtering, a weakly designed GraphQL or REST endpoint may return rows that include the key column to unauthenticated or insufficiently authorized users.

Another path involves logging and error handling. If a MySQL error reveals query text or table structures, and the NestJS handler includes the full query or raw database response in logs or error messages, an API key may be leaked through stack traces or application logs. Misconfigured TypeORM or raw query result serialization can also expose columns that should be omitted, especially when using SELECT * patterns.

SSRF scenarios compound this risk. A compromised endpoint that accepts a hostname or URL parameter could be directed toward internal MySQL-compatible services, and a leaked API key might be used to pivot to other systems. MiddleBrick’s checks include unauthenticated endpoint detection and data exposure analysis, which can surface endpoints that return credentials or overly broad data sets without authentication.

Additionally, if the NestJS application uses environment variables to build MySQL connection strings and those values are mistakenly interpolated into responses or debug output, the key can be exposed in transit. MiddleBrick’s encryption and data exposure checks look for such leakage in both application responses and metadata returned by the API surface.

Mysql-Specific Remediation in Nestjs — concrete code fixes

Apply strict column selection and omit sensitive fields in queries. Instead of SELECT *, explicitly list columns and exclude API keys. Use parameterized queries to prevent injection and accidental exposure through error messages.

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { IntegrationKey } from './integration-key.entity';

@Injectable()
export class SecretsService {
  constructor(
    @InjectRepository(IntegrationKey)
    private readonly keysRepo: Repository,
  ) {}

  async getPublicConfig(tenantId: string) {
    // Explicitly exclude the key column from general queries
    return this.keysRepo
      .createQueryBuilder('ik')
      .select(['ik.id', 'ik.tenantId', 'ik.serviceName', 'ik.createdAt'])
      .where('ik.tenantId = :tenantId', { tenantId })
      .getMany();
  }

  async getKeyById(id: number) {
    // Retrieve key only when necessary and with proper authorization checks
    const row = await this.keysRepo
      .createQueryBuilder('ik')
      .select(['ik.id', 'ik.keyValue'])
      .where('ik.id = :id', { id })
      .getRawOne();
    if (!row) {
      throw new NotFoundException('Key not found');
    }
    return row;
  }
}

Ensure MySQL user permissions follow least privilege. The application connection user should not have broader rights than required, and sensitive operations should be isolated.

-- Example MySQL account for the NestJS app (run in MySQL shell)
CREATE USER 'nest_app'@'app-host' IDENTIFIED BY 'StrongPassword123!';
GRANT SELECT (id, tenant_id, service_name, created_at), INSERT, UPDATE ON app_db.integration_keys TO 'nest_app'@'app-host';
-- Explicitly deny SELECT on the key column for non-privileged roles
REVOKE SELECT ON app_db.integration_keys.key_value FROM 'nest_app'@'app-host';
FLUSH PRIVILEGES;

Use environment-based configuration without echoing values in logs. Avoid logging full query results that may contain sensitive columns. MiddleBrick’s CLI can be used in your pipeline to validate that endpoints do not inadvertently return keys.

// Good practice: sanitize output before logging or returning
const safeForLogging = {
  id: result.id,
  service: result.serviceName,
  hasKey: !!result.keyValue,
};
console.info('Key access checked', safeForLogging);

Map findings to compliance frameworks such as OWASP API Top 10 A01:2023 broken object level authorization and A05:2021 insecure deserialization. MiddleBrick’s BOLA/IDOR and Property Authorization checks help surface endpoints that expose database rows without appropriate constraints.

Frequently Asked Questions

How can I test whether my NestJS endpoints expose API keys without logging into the system?
Use an unauthenticated scan with a tool that performs black-box testing against your public endpoints. MiddleBrick’s free tier allows limited scans to detect endpoints that return sensitive columns such as API keys in responses.
Does scanning with MiddleBrick require credentials or access to my MySQL instance?
No. MiddleBrick scans the unauthenticated attack surface by submitting requests to your API endpoints and does not require credentials, agents, or direct access to your MySQL database.