Skip to main content

SEC.PRIV.GRANT_SERVER_ADMIN — The account administers the server, not a database

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

Why a check for SUPER finds nothing on a modern server

This is the part worth reading even if you skip the rest.

MySQL deprecated SUPER in 8.0 and split its powers across a family of dynamic privileges. An account on a correctly configured 8.4 can change every global variable, end anybody else's session, and have the server run code as another user — while holding no SUPER at all.

A rule that looks for SUPER therefore comes back empty, and reads exactly like a rule with nothing to report. That is the failure this rule is built to avoid, so it judges the whole family.

Bad

-- Neither of these needs SUPER, and both make the account a server administrator.
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'app'@'10.0.0.%';
GRANT SET_ANY_DEFINER ON *.* TO 'app'@'10.0.0.%';

Good

-- Whatever the application actually uses, and nothing that reaches the server itself.
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'app'@'10.0.0.%';

-- On an account that already holds one:
REVOKE SYSTEM_VARIABLES_ADMIN, SET_ANY_DEFINER ON *.* FROM 'app'@'10.0.0.%';

Where the list comes from, and why that matters

The privileges are a shipped data artifact, not a list inside the rule — and a test asks a real MySQL 8.4 to accept every name in it. A hand-kept list of engine vocabulary rots silently: it goes on looking correct while the engine renames things underneath it.

That is not a hypothetical. The list was first written carrying SET_USER_ID, and the reconciliation rejected it on its first run — 8.4 refuses the name outright, because it was split into SET_ANY_DEFINER and ALLOW_NONEXISTENT_DEFINER. A rule reading the old name would have matched nothing on the engine this package targets, and nothing would have said so.

What is not reported

GRANT OPTION, which is in the same vocabulary but is a property of a grant rather than an administrative power over the server. It has its own rule, and one fact reported under two ids reads as two problems — so the artifact marks it unjudged here, making the exclusion a property of the data rather than of a rule remembering to skip something.

A grant the engine ships. Every server ships administrative accounts by design.

A grant that could not be read in full is undetermined, never a clean bill.

The legitimate case

A DBA or backup account holds some of these on purpose. The finding is the list of accounts for which that was a decision — and the useful question is rarely is this account an administrator but does the application account need to be one.

  • SEC.PRIV.ROLE_SUPERUSER — the same question asked of the account the audit connected as, rather than of a grant.