Base64编码本身不防SQL注入,它仅是字符转换,解码后原始恶意载荷不变;漏洞根源在于解码后未经类型校验或参数化即拼入SQL,唯有参数化查询(如prepare+bind)能彻底防御。

Base64编码本身不防SQL注入,解码后必须走参数化查询
Base64不是安全机制,只是编码格式。攻击者传入YW5kIDE9MQ==,服务端base64_decode()得到and 1=1,再拼进"WHERE id = '$id'",漏洞照旧。真正起作用的只有参数化查询——无论输入是否编码、编码几层,只要最终执行用的是prepare()+bind_param()(PHP)、cursor.execute("SELECT ... WHERE id = %s", (val,))(Python)或connection.execute("...", [val])(Node.js),数据库引擎就不会把值当SQL语法解析。
别在解码后做关键词过滤,时机和上下文全错了
常见错误是:先base64_decode($_GET['q']),再preg_match('/(union|select)/i', $decoded)。问题在于:
- 过滤发生在解码后,但WAF或日志系统可能只检查原始Base64字符串,
Ym9yIDE9MQ==根本不会触发规则 - 如果参数是JSON字段值:
{"name": "a' OR 1=1 --"}→ Base64 → 解码后才json_decode(),此时过滤早已错过注入点 - 大小写/Unicode混淆有效:传
b2IgMQoxPTE=(换行分隔的ob 1\n1=1),小写or检测就失效 - 正则性能差:高并发下对每个Base64参数跑一遍
preg_match,CPU飙升还易被超长串拖垮
警惕多重解码、字符集错配和空字节截断
攻击者会利用服务端实现缺陷绕过校验:
- 重复编码:
YmFzZTY0X2RlY29kZShvciAxPTEp(即base64_decode(or 1=1)),若后端写base64_decode(base64_decode($input)),直接还原payload - 混合编码:先URL编码
%27%20OR%201%3D1,再Base64得JTJ3JTIwT1IlMjAxJTNEMSUyMC0t,绕过只查ASCII单引号的WAF - 空字节截断:旧版
base64_decode()遇到\x00提前终止,构造admin\x00' OR 1=1 --编码后可能只解出admin,看似安全实则埋雷 - MySQL连接字符集设为
latin1,但传输UTF-8字节流,%C0%BC这类无效序列可能被解释成特殊字符,绕过基于UTF-8的WAF规则
ORDER BY/LIMIT等位置不能参数化,需白名单校验
预编译无法覆盖标识符类动态SQL,例如ORDER BY $column或LIMIT $offset, $count。这里不能用参数占位符,否则ORDER BY 'name'会被当字符串常量而非列名处理。必须用白名单约束:
-
$column只能是['id', 'name', 'created_at']中的一个,用in_array($column, $whitelist, true)校验 -
$limit必须是整型且有上限:$limit = (int)$limit; if ($limit > 100) $limit = 100; - 避免用
mysql_real_escape_string()或addslashes()拼接这些位置——它们对宽字节注入(如%df')完全无效
最危险的不是Base64,而是把它当成“已消毒”的信号。解码后的字符串,必须当作完全不可信的原始输入,只允许走参数化路径进入SQL执行环节。任何拼接、eval、exec()或反射式调用,都是在给攻击者留门。











