# MySQL FILE Privilege Detection

- **URL:** https://hackindex.io/services/mysql/vulnerability-discovery/mysql-file-privilege-detection
- **Path:** MySQL > Vulnerability Discovery
- **Up:** [Vulnerability Discovery](https://hackindex.io/services/mysql/vulnerability-discovery.md)
- **Published:** 2026-03-26
- **Updated:** 2026-03-26

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:

```bash
mysql -h $TARGET_IP -P ${PORT:-3306} -u $USER -p$PASSWORD -e "SHOW GRANTS FOR 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:

```bash
mysql -h $TARGET_IP -P ${PORT:-3306} -u $USER -p$PASSWORD -e "SELECT user, host, File_priv FROM mysql.user WHERE user = CURRENT_USER();"
# +------+------+-----------+
# | 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:

```bash
mysql -h $TARGET_IP -P ${PORT:-3306} -u $USER -p$PASSWORD -e "SELECT LOAD_FILE('/etc/hostname');"
# +-------------------------+
# | 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:

```bash
mysql -h $TARGET_IP -P ${PORT:-3306} -u $USER -p$PASSWORD -e "SHOW VARIABLES LIKE 'secure_file_priv';"
# +------------------+-------+
# | 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:

```bash
ps aux | grep mysqld
# 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 reference](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_file) - FILE privilege scope, secure_file_priv interaction, and OS permission behavior
- [MySQL: secure_file_priv variable](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_secure_file_priv) - Path restriction behavior and NULL disabling reference
