mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-10-29 23:23:43 +00:00
Update 攻击技术.md
补充预处理语句在 MySQL 驱动中的执行方式。
This commit is contained in:
@@ -194,6 +194,14 @@ stmt.setString(2, password);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
```
|
||||
|
||||
需要注意的是,MySQL 的 JDBC 驱动(Connector/J)默认并不在服务器上预编译,而是在客户端把参数中的单引号等字符转义后,拼成完整的语句发送。在本机用 Connector/J 8.3 执行上面的查询,两个参数都传入 1' OR '1'='1,MySQL 通用查询日志中记录的是:
|
||||
|
||||
```text
|
||||
Query SELECT * FROM users WHERE name = '1'' OR ''1''=''1' AND pw = '1'' OR ''1''=''1'
|
||||
```
|
||||
|
||||
参数仍然只是一个普通的字符串,查询结果为空。连接参数加上 useServerPrepStmts=true 后,驱动才会先发送 Prepare、再发送 Execute。两种方式都能防止注入,关键在于参数由驱动或数据库处理,而不是由开发者拼接。表名、列名和 ORDER BY 的字段不能使用占位符,只能用白名单校验,见 [MyBatis 的 #{} 和 ${}](Spring.md#-和--的区别)。
|
||||
|
||||
#### 2. 单引号转换
|
||||
|
||||
将传入的参数中的单引号转换为连续两个单引号。PHP 的 Magic Quotes 曾经自动完成这个功能,但是因为不可靠已经被移除,应该使用数据库驱动提供的转义函数,并且只在无法使用参数化查询时使用。
|
||||
|
||||
Reference in New Issue
Block a user