Skip to main content

SEC.CFG.GENERAL_LOG_PERSONAL_DATA — Row values are being written to the query log

  • Category: privacy
  • Severity: medium
  • Level: 0
  • Confidence: deterministic
  • Downtime class: none — the finding is about a server setting, not about a statement
  • Stability: stable
  • Suites: audit
  • Applies to: MySQL 8.4

Why this reads the same setting as SEC.CFG.GENERAL_LOG

Because one setting raises two questions, and a project usually cares about exactly one of them.

The hardening view is about secrets: CREATE USER … IDENTIFIED BY 'secret' goes into the log with the password, and a credential in a log stays valid until somebody rotates it.

This one is about the rows: every WHERE email = … with its value, every name and address an INSERT carries, every parameter of every job.

They are gated by different categories and usually read by different people. A team hardening a server filters on --category=security; a team answering a data-protection question filters on --category=privacy. One rule can carry only one category, so a single rule would be invisible to whichever half did not pick it — and a report missing a category looks exactly like a clean report.

What makes it a compliance problem rather than an untidiness

The log file outlives the row. An erasure request removes a record from the table; the statement that wrote it, values and all, stays in a file that is commonly readable by people who were never granted access to the tables, and that log shipping has already copied elsewhere under its own retention.

The log does not redact, because it is a debugging tool: it records what was sent.

Only on production, and that is deliberate

The general query log is exactly how people debug on a laptop. A rule that could not tell a developer machine from a production server would be muted within a week — taking the production case with it. So this reports only where the run can establish it is looking at production.

Where it cannot establish that, the answer is undetermined with the reason named. Never a quiet pass: "I could not tell" and "there is nothing here" are different answers, and only one of them is a result.

What it does not claim

  • It reads the running value, not the file. A setting changed on disk and not yet reloaded is invisible here.
  • It cannot see where the log goes. A log going to a table nobody can read is a different exposure from one shipped to an aggregator a whole team queries — and the destination, not this switch, decides how far the values travel.

What it looks like

# my.cnf: every statement written down, verbatim — values included.
general_log = ON

What to do about it

# Off is the vendor default, and where a production server belongs.
general_log = OFF

When it is a false positive

A server with the log deliberately on while somebody debugs, which is measured in minutes. This rule reports only on production, so a laptop or a staging box that the run can place is silent; where it cannot place the environment it answers undetermined rather than guessing.