mysql 的 general_log 需先确认是否开启(select @@global.general_log),再检查 log_output 是否为 'table' 或有效文件路径,且仅对新连接生效;日志量大、csv 表无索引,线上慎用。

怎么看 MySQL 的 general_log 有没有记录可疑 SQL
MySQL 默认不开启通用查询日志,所以直接查 general_log 表或读日志文件,大概率是空的。得先确认它开着没——连上数据库后执行:
SELECT @@global.general_log;返回
OFF 就白看了。开日志要两步:SET GLOBAL general_log = ON; 和 SET GLOBAL log_output = 'TABLE'(推荐存到 mysql.general_log 表,比文件好查);如果用文件,路径由 general_log_file 决定,默认在数据目录下,但权限不对时可能写失败,连日志都不生成。常见错误现象:开了 general_log 却查不到新语句,其实是 log_output 还是 'NONE';或者开了但没权限写文件,MySQL 错误日志里会报 Failed to open log file。
- 只对新连接生效,已有连接不受影响
- 日志量爆炸,线上环境慎开,尤其高并发场景
-
mysql.general_log表默认用CSV引擎,不支持索引,查大日志很慢,必要时导出后用 grep 或 awk 处理
PostgreSQL 怎么用 pg_audit 查登录和 DML 异常行为
pg_audit 不是默认内置模块,得先装扩展:CREATE EXTENSION pg_audit;,然后在 postgresql.conf 里配 pgaudit.log = 'read, write, role, ddl',再重启。注意:它只审计通过 PostgreSQL 协议进来的请求,比如 JDBC、psql,但绕过协议直连(如 Unix socket 被劫持)或中间件改写后的语句,它看不到。
容易踩的坑:没设 pgaudit.log_catalog = off,会导致大量系统表访问也被记下来,干扰判断;还有人把 pgaudit.log_parameter = on 忘了开,结果所有 WHERE id = ? 类参数全显示成 WHERE id = $1,根本看不出注入用的恶意值。
- 审计日志默认输出到服务器日志(
log_destination = 'stderr'),需配合logging_collector = on才能落盘 - 敏感操作如
DROP TABLE、UNION SELECT、EXECUTE IMMEDIATE(通过 dblink)可重点过滤 - 日志格式固定,字段包括
type、statement、parameter,用正则匹配;\s*--或UNION\s+ALL\s+SELECT更可靠,别只靠关键词“union”
SQL Server 审计日志里怎么识别堆叠注入(stacked query)
SQL Server 的 SERVER AUDIT 对 EXECUTE 和 BATCH STARTED 事件最管用。堆叠注入典型特征是单条语句里带分号 + 多个命令,比如 SELECT * FROM users; DROP TABLE orders;。但原生审计不拆分语句,整条 statement 字段才记录下来,得靠后续解析。
关键点在于:SQL Server 把这种语句当成一个 batch,审计事件类型是 BATCH STARTED,不是多个 EXECUTE。所以不能只盯 EXECUTE 事件,否则漏掉第二条命令。
- 启用时必须包含
AUDIT_ACTION_ID = 'BAS'(即 BATCH STARTED) - 日志里
statement字段若含多个分号、GO、或连续的SELECT/INSERT/UPDATE/DELETE,就要人工抽检 - 注意
application_name字段,Web 应用通常填的是Microsoft JDBC Driver或php_pdo,和 DBA 手动执行的sqlcmd或SSMS明显不同,可辅助判断是否异常来源
用日志做注入检测时最容易被忽略的盲点
日志本身不会告诉你“这是注入”,只会记录“这条 SQL 被执行了”。真正难的是区分正常业务逻辑和攻击载荷。比如 WHERE name LIKE '%admin%' 和 WHERE name LIKE '%admin%' OR '1'='1',结构高度相似,靠字符串匹配极易误报或漏报。
更麻烦的是编码绕过:URL 编码的 %27%3B%20SELECT%201--、宽字节注入的 %df%27、甚至 base64 嵌套在注释里——这些在数据库日志里已经解码还原,但原始请求体里的变形,日志根本不留痕。
- 数据库日志不记录 HTTP 请求头、原始 POST body、cookie,所以无法关联 Web 层 WAF 日志做交叉验证
- 预编译语句(
PreparedStatement)即使被绕过,日志里也只显示占位符,真实参数值不会出现(除非开了log_parameter = on且数据库支持) - 有些注入走的是存储过程调用,比如
EXEC sp_executesql N''SELECT * FROM users WHERE id = '' + @id,日志里只记EXEC,不展开拼接逻辑,得结合代码审计才能定位风险点










