Skip to content

security(db): Sequelize default console.log dumps bound parameters (including authKey values) to stdout #143

@CryptoJones

Description

@CryptoJones

Problem

app/config/db.config.js constructs the Sequelize instance without setting a logging option, which means Sequelize's default applies: logging: console.log. Every executed SQL statement — and every bound parameter value — is written to stdout.

That includes queries like:

Executing (default): SELECT "akCompId" FROM "dbo"."ApiKey" WHERE "akKey" = $1 AND "akArch" = $2
[ 'super-secret-authkey-value-here', false ]

Two consequences:

  1. Secret leakage. pino's redact paths (req.headers.authkey, *.authKey, etc.) only inspect HTTP request shapes; they never see Sequelize's SQL strings. The raw authKey value sails past every redaction layer and lands in stdout. Wherever stdout goes (terminal in dev, container logs in prod, log shipper, retention) so does the secret.
  2. Format mixing. Structured pino JSON lines and Sequelize's free-form multi-line console output share the same fd. Log shippers (Vector, Loki, CloudWatch) that parse line-by-line as JSON either fail to parse the Sequelize lines or fall back to a "raw" representation that defeats structured logging.

Proposed fix

Default logging: false. Operators who need query logs for debugging set DB_LOG_QUERIES=1, which routes queries through pino at debug level — silent at LOG_LEVEL=info (the default), visible at LOG_LEVEL=debug, and never emitted as bare console.log. Note that the opt-in mode still echoes parameter values into the structured log, just with the structured-log format / one-line-per-event property preserved.

Document in .env.example.

Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions