错误日志本身不记录SQL或用户数据,但敏感信息可能因权限与配置不当间接泄露;需撤销PROCESS/FILE权限、禁用super_priv、设log_error_verbosity≤3、确保log_error文件权限为600并隔离路径。
error_log 本身不记录 SQL 或用户数据,但敏感信息仍可能间接进入——这不是日志功能缺陷,而是权限与配置没对齐导致的“行为泄露”。真正要堵的不是日志文件,是那些能让敏感内容被写进去的操作源头。
应用若把 SHOW PROCESSLIST 结果当错误上下文打印,或在异常处理中拼接了含路径/用户名的调试信息,再写进日志,就可能暴露敏感字段。PROCESS 权限允许查看其他线程的 SQL,FILE 权限则支撑 LOAD DATA INFILE 类操作,失败时路径名(如 /tmp/user_12345.csv)可能进日志。
执行以下命令回收权限:
REVOKE PROCESS ON *.* FROM 'app_user'@'%';REVOKE FILE ON *.* FROM 'app_user'@'%';SHOW GRANTS FOR 'app_user'@'%';,确认输出不含 PROCESS 或 FILE
super_priv 是高危权限,拥有它意味着可动态修改全局变量、绕过 SQL 模式限制、甚至把 general_log 写进 error_log 文件。一旦被滥用,错误日志就变成“多合一”日志容器。
配合收紧日志粒度:
SELECT @@log_error_verbosity;,值必须 ≤ 3;若为 4 或 5,说明 SQL 上下文会被记录[mysqld] 段添加 log_error_verbosity = 3 并重启 mysqldlog_error_suppression_list —— 填错正则反而放大风险,比如误匹配所有含括号的提示如果你开了 binlog_encryption=ON 却没配好密钥环,MySQL 会静默降级为明文 binlog,并在 error_log 里记一条警告:Failed to initialize binlog encryption keyring。这条警告本身虽不带敏感字段,但暴露了加密未生效的事实,且后续 binlog 明文存储等于给攻击者留了后门。
验证三步走:
SELECT VERSION();
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'keyring_file';,状态必须是 ACTIVE
SELECT @@binlog_encryption;,返回 ON 才算真生效;否则重查 keyring_file_data 路径权限(属主必须是 mysql 用户,目录权限建议 750)MySQL 不会自动设日志文件权限,log_error 默认可能被其他用户读取。哪怕所有权限和配置都正确,一个宽松的文件权限就能让日志内容被拖走。
实操要点:
SELECT @@log_error;,常见位置如 /var/log/mysqld.log 或 /var/lib/mysql/hostname.err
ls -l /var/log/mysqld.log,权限必须是 -rw-------(即 600);如果不是,立即执行:sudo chown mysql:mysql /var/log/mysqld.log && sudo chmod 600 /var/log/mysqld.log
log_error 设成 /var/lib/mysql/error.log —— 数据目录通常权限更松,且容易随备份一并导出真正难控的不是参数开关,是自定义函数里那句 SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = CONCAT('用户', @uid, '身份证校验失败');。这类逻辑不会被权限拦住,也不会被 log_error_verbosity 过滤,它直接触发 MySQL 把拼好的字符串写进错误日志。审查所有 SIGNAL 和 RESIGNAL 语句,比调参数更重要。