Mysql数据库安全性问题【防注入】

来源:互联网 发布:时间旅行 美剧 知乎 编辑:程序博客网 时间:2024/05/16 11:54

一、SQL注入实例

后台的插入语句代码:

$unsafe_variable = $_POST['user_input'];   mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");  

当POST的内容为:

value'); DROP TABLE table;--

以上的整个SQL查询语句变成:

INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')  

二、防止SQL注入措施

1.使用预处理语句和参数化查询。(‘Use prepared statements and parameterized queries.’)
SQL语句和查询的参数分别发送给数据库服务器进行解析。这种方式有2种实现:
(1)使用PDO(PHP data object)

$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');  $stmt->execute(array('name' => $name));  foreach ($stmt as $row) {      // do something with $row  }  

(2)使用MySQLi

$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');  $stmt->bind_param('s', $name);  $stmt->execute();  $result = $stmt->get_result();  while ($row = $result->fetch_assoc()) {      // do something with $row  }  

2.对查询语句进行转义(最常见的方式)

$unsafe_variable = $_POST["user-input"];  $safe_variable = mysql_real_escape_string($unsafe_variable);  mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");  
$mysqli = new mysqli("server", "username", "password", "database_name");  // TODO - Check that connection was successful.  $unsafe_variable = $_POST["user-input"];  $stmt = $mysqli->prepare("INSERT INTO table (column) VALUES (?)");  // TODO check that $stmt creation succeeded  // "s" means the database expects a string  $stmt->bind_param("s", $unsafe_variable);  $stmt->execute();  $stmt->close();  $mysqli->close();  

3.限制引入的参数

$orders  = array("name","price","qty"); //field names  $key     = array_search($_GET['sort'],$orders)); // see if we have such a name  $orderby = $orders[$key]; //if not, first one will be set automatically. smart enuf :)  $query   = "SELECT * FROM `table` ORDER BY $orderby"; //value is safe  

4.对引入参数进行编码

SELECT password FROM users WHERE name = 'root'            --普通方式  SELECT password FROM users WHERE name = 0x726f6f74        --防止注入  SELECT password FROM users WHERE name = UNHEX('726f6f74') --防止注入  set @INPUT =  hex("%实验%");  select * from login where reset_passwd_question like unhex(@INPUT) ;  

有一些讨论意见,所以我最后想弄清楚。这两种方法非常相似,但它们在某些方面有点不同:
x前缀只能用于数据列如char、varchar、文本块,二进制,等等。
其使用也有点复杂,如果你要插入一个空字符串。你必须完全替代”,或者你会得到一个错误。
任何列工作;您不必担心空字符串。

这里写图片描述

参考stackoverflow:http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php

1 0
原创粉丝点击