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.