MySQL FILE Privilege Detection
The FILE privilege in MySQL allows a user to read files from the server filesystem using LOAD_FILE() and write files using SELECT ... INTO OUTFILE or SELECT ... INTO DUMPFILE. On a web server where MySQL runs with sufficient OS permissions, FILE privilege enables reading sensitive files like /etc/passwd and writing webshells to the web root. It is one of the most impactful misconfigurations in a MySQL deployment and is frequently present on over-provisioned application database accounts.
Check Current User Grants
The fastest check once connected is to inspect the grants for the current user:
+---------------------------------------------------------------------------+ | Grants for app@% | +---------------------------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE, DELETE, FILE ON *.* TO 'app'@'%' | +---------------------------------------------------------------------------+
FILE appearing in the grant list confirms the privilege is held. Even on a non-root account, FILE privilege enables reading any file the MySQL process user can access and writing to any directory the process user can write to.
Query the Privilege Directly
Check the mysql.user table for the FILE column on the current account:
+------+------+-----------+ | user | host | File_priv | +------+------+-----------+ | app | % | Y | +------+------+-----------+
File_priv = Y confirms FILE privilege. If the mysql.user table is not accessible with the current account, use the SHOW GRANTS approach instead.
Confirm MySQL FILE Privilege Detection with a Safe Read Test
Verify FILE privilege is actually functional by reading a file that is always readable:
+-------------------------+
| LOAD_FILE('/etc/hostname') |
+-------------------------+
| webserver01 |
+-------------------------+
A non-null result confirms LOAD_FILE is working. A NULL result despite the privilege being present usually means the secure_file_priv variable is restricting the read path. Check it:
+------------------+-------+ | Variable_name | Value | +------------------+-------+ | secure_file_priv | | +------------------+-------+
The three possible secure_file_priv states:
- Empty string: no path restriction, LOAD_FILE and INTO OUTFILE reach any path the MySQL process user can access
- Specific directory path: file operations restricted to that directory only
NULL: file operations disabled entirely regardless of FILE privilege
Check the MySQL Process User on the Host
The FILE privilege operates with the permissions of the OS user running MySQL. On Linux this is typically mysql but on misconfigured systems it may be root. If you have shell access confirm:
mysql 1482 0.5 4.2 1234567 87654 ? Sl 09:12 0:42 /usr/sbin/mysqld
MySQL running as root combined with FILE privilege and no secure_file_priv restriction means the account can read any file on the system and write to any directory. This is the highest-severity FILE privilege configuration and enables direct webshell deployment to the web root. Exploitation is covered in the FILE read and INTO OUTFILE pages.
References
-
MySQL: FILE privilege referenceDOCS: MySQL: FILE privilege reference, dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_file (opens in new tab)
FILE privilege scope, secure_file_priv interaction, and OS permission behavior
-
MySQL: secure_file_priv variableDOCS: MySQL: secure_file_priv variable, dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_secure_file_priv (opens in new tab)
Path restriction behavior and NULL disabling reference