Skip to main content

SEC.CFG.LOCAL_INFILE_FILE_GRANT — The capability and an account that can use it

  • Category: security
  • Severity: high
  • Level: 0
  • Confidence: deterministic
  • Downtime class: none — the finding is about a server parameter and an account, not about a statement
  • Stability: stable
  • Suites: audit
  • Applies to: MySQL 8.4

Two halves of one route

SEC.CFG.LOCAL_INFILE reports the capability on its own: the server would name a path and have the client read it off its own disk and upload it. That needs a hostile or hijacked server to matter, and it touches nothing on the database host.

FILE on its own is the other end: an account that can read and write files as the server's operating-system user, bounded only by secure_file_priv.

Together they are a route rather than two settings — a connection that can be induced to upload a file, and an account that can place one where the host will read it.

Why this is a second rule and not a higher severity

Severity here is metadata on the rule, so "the same finding, more severe" is not expressible — and should not be. The escalation says something the first finding does not, and the deduplication key is rule id and location, so both survive into one report. That is only right because a reader learns something from the second: not "this is worse", but "and here is what exists alongside it."

What it looks like

# my.cnf: the server would ask a client for a file...
local_infile = ON

# ...and an account here can also write one on the server's own disk:
# GRANT FILE ON *.* TO 'reporting'@'%';

What to do about it

# Close the capability, and take FILE off any account that does not need it.
local_infile = OFF

# REVOKE FILE ON *.* FROM 'reporting'@'%';

Either half breaks the route. Which one to fix is a deployment question — an application that genuinely uses LOAD DATA LOCAL keeps the capability and loses the grant.

The condition this finding is careful about

The escalation is only made when the grant tables were actually readable. On a managed MySQL a refused grant read is the ordinary case, not the exception — and there the run reports that it could not check, with the reason, rather than quietly declining to escalate.

Those two are the same silence otherwise, and the one a reader assumes is the reassuring one. The medium finding from SEC.CFG.LOCAL_INFILE still stands beside it, so the report says two true things: the capability is on, and whether an account could exploit it is unknown.