Chapter 12 · Encryption, TLS, Secrets, Auditing, and Security Hardening

Hardening Checklist: Network Exposure, Local Files, Plugins, Accounts, and Patch Discipline

Convert security guidance into an evidence-driven MySQL hardening review covering network exposure, secure transport, local-file controls, plugins/components, accounts, privileges, logging, key material, backups, and patch discipline.

Intermediate130–180 minhardening audit capstoneMySQL Community Server 8.4.10 LTS · self-managed local instancesecurity / operationsLast reviewed: August 2026

Learning outcomes

Hardening is not a list of magical settings. A MySQL server may be safe on a loopback-only developer laptop with one configuration and unsafe on an Internet-reachable host with the same configuration. The final Chapter 12 exercise therefore starts from exposure and evidence, ranks risks, applies the minimum useful change, and records what still remains.

01

Inventory network/listen exposure, TLS enforcement, local-file capabilities, plugins/components, accounts, privileges, logs, and patch level.

02

Explain why local_infile, FILE privilege, secure_file_priv, and OS filesystem permissions form different security boundaries.

03

Identify anonymous/test accounts, wildcard administrative grants, unnecessary components/plugins, and stale identities without blindly deleting working dependencies.

04

Prioritize patching and release verification using the actual installed server/client versions and current Oracle security/release information.

05

Produce a repeatable hardening record with owner, evidence, decision, rollback, verification, and residual risk.

Start with exposure, not a canned checklist

The first question is “who can reach this server?” bind_address, network interfaces, container port publication, host firewall rules, cloud security groups, proxies, VPNs, and service meshes all participate. MySQL can only report part of that picture, so combine server variables with operating-system/network evidence.

sql · create a small disposable ServiceHub security schema
-- Run as a local administrator on a disposable MySQL instance.CREATE DATABASE IF NOT EXISTS servicehub_security_lab  CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;CREATE TABLE IF NOT EXISTS servicehub_security_lab.security_events (  event_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,  event_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),  actor VARCHAR(80) NOT NULL,  event_type VARCHAR(40) NOT NULL,  detail VARCHAR(255) NOT NULL) ENGINE=InnoDB;INSERT INTO servicehub_security_lab.security_events(actor,event_type,detail)VALUES ('chapter12','LAB_START','Chapter 12 disposable security lab');SELECT COUNT(*) AS event_rowsFROM servicehub_security_lab.security_events;
sql · capture the server-side network and transport posture
SELECT VERSION() AS server_version,       @@hostname AS server_host,       @@port AS port,       @@GLOBAL.bind_address AS bind_address,       @@GLOBAL.require_secure_transport AS require_secure_transport,       @@GLOBAL.skip_name_resolve AS skip_name_resolve;SHOW SESSION STATUS LIKE 'Ssl_cipher';SHOW GLOBAL STATUS LIKE 'Ssl_%';

A wide bind address is not automatically a vulnerability if an effective firewall restricts reachability, but it expands the consequences of a firewall mistake. Conversely, binding to loopback does not protect a database exposed through an SSH tunnel or proxy. Record the full path that clients use.

Local file features cross the SQL/filesystem boundary

MySQL has two frequently confused mechanisms. LOAD DATA LOCAL asks the client to send a local file; server and client both participate in enabling it. The global FILE privilege allows server-side file operations such as LOAD DATA without LOCAL and SELECT ... INTO OUTFILE, constrained by the mysqld operating-system identity and secure_file_priv.

sql · inspect the local-file posture
SHOW GLOBAL VARIABLES LIKE 'local_infile';SHOW GLOBAL VARIABLES LIKE 'secure_file_priv';SELECT GRANTEE, PRIVILEGE_TYPE, IS_GRANTABLEFROM INFORMATION_SCHEMA.USER_PRIVILEGESWHERE PRIVILEGE_TYPE = 'FILE'ORDER BY GRANTEE;

MySQL 8.4 disables server-side local_infile by default. Keep it disabled unless an actual workflow needs it, then constrain the client side as well. secure_file_priv is non-dynamic; a directory value limits relevant server-side import/export operations to that directory, while NULL disables them. An empty value imposes no such directory restriction and is explicitly considered insecure by the server documentation.

FILE is an administrative boundary

Do not grant FILE to an application just because an import feature is convenient. FILE can expose files readable by mysqld and can write files where mysqld has permission, subject to secure_file_priv. Prefer application-mediated uploads/staging when possible.

Inventory accounts, roles, and dangerous breadth

sql · audit accounts and privilege shape
SELECT User, Host, plugin, account_locked, password_expiredFROM mysql.userORDER BY User, Host;SELECT FROM_USER, FROM_HOST, TO_USER, TO_HOSTFROM mysql.role_edgesORDER BY FROM_USER, TO_USER;-- Review grants for each service/operator account individually.SHOW GRANTS FOR 'svc12_secret_b'@'127.0.0.1';

Look for anonymous users, obsolete test/service identities, hosts broader than the network requirement, locked accounts that should be removed after retention policy, and accounts with ALL ON *.* where a narrow role would work. Do not automate deletion solely from a name pattern; first map accounts to owners, applications, definers, events, replication, and backup jobs.

sql · safe negative authorization test
-- As the narrow application account, this should fail:CREATE DATABASE should_not_be_allowed;-- The correct response is NOT to grant global CREATE.-- Verify the account can still perform only its intended application work.SELECT COUNT(*) FROM servicehub_security_lab.security_events;

An expected denial is a security test result. Preserve it in the hardening record.

Plugins and components: reduce attack surface without breaking dependencies

sql · inventory loaded extensibility
SHOW PLUGINS;SELECT component_id, component_group_id, component_urnFROM mysql.componentORDER BY component_id;

“Uninstall everything unfamiliar” is not hardening. Authentication, keyring, password validation, cloning, audit, and other capabilities may be operational dependencies. For each loaded plugin/component, record why it is present, which edition/package supplied it, who owns it, how it is patched, and what breaks if it is removed. Remove only after dependency and rollback testing on a disposable or staging instance.

Check logging, key material, and backup exposure together

sql · capture security-relevant server settings
SHOW GLOBAL VARIABLES WHERE Variable_name IN (  'general_log','slow_query_log','log_output','log_raw',  'binlog_encryption','innodb_redo_log_encrypt','innodb_undo_log_encrypt',  'default_table_encryption','require_secure_transport');SELECT component_urn FROM mysql.componentWHERE component_urn LIKE '%keyring%';

A hardened server can still leak data through readable backups or logs. Ensure backup destinations, keyring files/services, TLS private keys, option files, and log directories have explicit ownership and retention. Test restores with the same key dependencies you expect during a disaster. Chapter 13 will turn that into a full backup and point-in-time-recovery workflow.

Patch discipline is a control, not an annual maintenance ritual

Start with the version actually running, then compare it with Oracle's current 8.4 download/release and security information. At the time this lesson was generated, Oracle's live Community Server page exposes 8.4.10 LTS; the online 8.4.11 release-note page is currently marked “Not yet released.” That is why this chapter declares 8.4.10 rather than freezing the sequential guide's earlier 8.4.11 note.

text · record the versions that matter
SELECT VERSION() AS server_version;-- Run outside SQL as applicable:mysql --versionmysqlsh --version

Server and client versions are independent. Connectors, MySQL Shell, Router, operating-system packages, OpenSSL, and plugins/components have their own lifecycles. A security review should inventory each component that processes credentials or database traffic.

Do not patch by surprise

Security patches are important, but production changes still require compatibility review, backups, restore confidence, staged rollout, and rollback/fail-forward planning. “Patch quickly” and “change safely” are complementary goals.

Turn findings into a prioritized hardening record

FindingEvidenceDecision pattern
Plaintext TCP possiblenegative --ssl-mode=DISABLED test succeedsFix clients/trust, then enforce secure transport
Application has global privilegesSHOW GRANTSReplace with scoped role/object grants
FILE granted to appUSER_PRIVILEGESRevoke unless explicitly required; constrain secure_file_priv
local_infile enabled without use@@global.local_infileDisable after confirming no workflow depends on it
Unknown plugin/componentSHOW PLUGINS / mysql.componentIdentify owner/dependency; remove only after test
Backups unencrypted or untestedartifact inspection + restore testProtect artifact and verify restore/key chain
Old patch levelVERSION() + vendor advisoryPlan staged supported update

Rank by plausible exploit path and impact, not by how easy a setting is to change. A remotely reachable passwordless/global-admin account is more urgent than a low-risk cosmetic finding. Record residual risk when a business dependency prevents immediate remediation.

Hands-on acceptance test

sql · final Chapter 12 evidence bundle
-- 1. Identity and privilege evidenceSELECT CURRENT_USER(), USER();SHOW GRANTS;-- 2. Transport evidenceSHOW SESSION STATUS LIKE 'Ssl_cipher';SHOW GLOBAL VARIABLES LIKE 'require_secure_transport';-- 3. File boundary evidenceSHOW GLOBAL VARIABLES LIKE 'local_infile';SHOW GLOBAL VARIABLES LIKE 'secure_file_priv';-- 4. Extensibility / keyring evidenceSELECT component_urn FROM mysql.component ORDER BY component_urn;-- 5. Log postureSHOW GLOBAL VARIABLES WHERE Variable_name IN  ('general_log','slow_query_log','log_output','log_raw');-- 6. Patch identitySELECT VERSION();

Save the output with the date, environment name, reviewer, and intended exceptions. Do not include passwords, private keys, or secret values in the evidence bundle. A hardening review is repeatable when another operator can rerun the same observations and understand why each exception exists.

Knowledge check

  1. Why is bind_address alone insufficient to prove network exposure?
  2. What is the difference between local_infile and FILE privilege?
  3. What does secure_file_priv=NULL do?
  4. Why should unknown plugins not be removed automatically?
  5. Why does patch discipline include restore planning?
Reveal answers
  1. Firewalls, containers, proxies, tunnels, and external network controls also determine reachability.
  2. local_infile controls the client-to-server LOCAL loading capability, while FILE authorizes server-side filesystem import/export operations.
  3. It disables the relevant server-side import/export file operations controlled by secure_file_priv.
  4. They may be dependencies for authentication, keyring, policy, or operations; removal can break the server or recovery path.
  5. A security update is still a production change. Safe rollout depends on compatibility checks, backups, recovery confidence, and a rollback/fail-forward plan.

Summary and bridge to Chapter 13

Security is now a layered operational system: authenticated least-privilege identities, verified TLS, controlled secrets, explicit at-rest/key boundaries, protected logs, constrained filesystem features, known plugins, and current patch state. Chapter 13 builds the recovery side of that security model—backups, restores, binary logs, and point-in-time recovery—because a secure database that cannot be recovered is not production-ready.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.