Skip to main content

SEC.CFG.LOCAL_INFILE — The server may ask the client for a file

  • Category: security
  • 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

Which way it points

LOAD DATA LOCAL INFILE does not read a file on the server.

The server sends the client a request naming a path. A compliant client reads that path off its own disk and uploads the contents. The client does not choose the path — it is told one.

So a server that is compromised, or one an application was pointed at by mistake, can ask for an .env, a key file or /etc/passwd, and a client with the capability enabled hands it over. Your application does not have to run a single LOAD DATA statement for this to happen: the request comes from the other end of the connection.

This is why a reader who takes the statement name at face value reaches the wrong conclusion — "we never call LOAD DATA, so this cannot touch us" — and it is the whole reason the rule exists.

Why medium

Exploiting it needs a hostile or hijacked server, which is a larger precondition than most findings in this suite carry.

What it does not need is any privilege on the account. The capability is negotiated at connection time, not granted — so no GRANT anywhere makes a difference to it.

What this rule cannot see

It reads the server's side of the negotiation. A client can refuse independently: PHP's mysqli.allow_local_infile and PDO's PDO::MYSQL_ATTR_LOCAL_INFILE both default to off on current builds. The finding says the server would ask, not that anybody would answer.

What it looks like

# my.cnf: the server may ask the client to send it a file.
local_infile = ON

What to do about it

# Off is the vendor default on 8.4, and costs an application nothing.
local_infile = OFF

A data-import job that genuinely uses LOAD DATA LOCAL INFILE is the one case worth checking first — it can be enabled for the single session that needs it.

The variable is GLOBAL-only and dynamic: SET GLOBAL local_infile = OFF takes effect without downtime, but no individual session may set it.

Not the same as SEC.CFG.SECURE_FILE_PRIV

They point in opposite directions and neither implies the other. secure_file_priv bounds what the server may read and write on its disk; local_infile decides whether the server may ask the client for a file.

The fix material this rule carries

A finding from this rule carries a payload whose strategy is none: this rule has looked, and there is no safe standard sequence. That is a conclusion rather than an omission — a finding with no payload at all says only that nobody wrote one.

The payload is material for you or an agent to apply. SQLens writes no migration and runs no DDL. See the remediation payload for every field, the placeholder semantics, and the version rules a consumer has to follow.