您的位置:首页 > 数据库

Web安全之SQL注入

2015-09-05 08:56 483 查看
SQL注入攻击是通过非友好的SQL语句拼接来获取该用户没有权限访问的数据。

当应用程序将用户输入的内容,拼接到SQL语句中,一起提交给数据库执行时,就会产生SQL注入威胁。

由于用户的输入,也是SQL语句的一部分,所以攻击者可以利用这部分可以控制的内容,注入自己定义的语句,改变SQL语句执行逻辑,让数据库执行任意自己需要的指令。通过控制部分SQL语句,攻击者可以查询数据库中任何自己需要的数据,利用数据库的一些特性,可以直接获取数据库服务器的系统权限。

本来SQL注入攻击需要攻击者对SQL语句非常了解,所以对攻击者的技术有一定要求。但是几年前,已经出现了大量SQL注入利用工具,可以让任何攻击者,只要点几下鼠标,就能达到攻击效果,这使得SQL注入的威胁,极大增加。

攻击

我们先来看看攻击案例,一段普通的java查询数据库代码如下:

HttpServletRequest request, HttpServletResponse response) {
JdbcConnection conn = new JdbcConnection();
final String sql = "select * from product where pname like '%"
        + request.getParameter("pname") + "%'";
conn.execqueryResultSet(sql);


PHP查询数据库代码如下:

$sql = "select * from product where pname like '%"
        .$_REQUEST["pname"] . "%'";
mysqli_query($link,$sql);


这两段表达的意思都是将用户输入的pname拼接到SQL语句中。但是都可以进行SQL注入攻击。

攻击者在攻击时访问url为:

http://localhost:8080/struts1/listProduct.htm?pname=e' and 1=2 union select 1,name,pass,4 from user where ''<>'


这时数据库执行的语句为:

select * from product where pname like '%e'  and 1=2 union select 1,name,pass,4 from user where ''<>'%'


就会执行关联查询,显示出user表中的name和pass字段。其他用户信息也就泄露了。

防御

还是那句话,有攻击就会有防御。我们可以通过预处理执行SQL语句,并对所有传入SQL语句中的变量做绑定。java代码如下:

com.mysql.jdbc.Connection conn = db.JdbcConnection.getConn();
final String sql = "select * from product where pname like ?";
java.sql.PreparedStatement ps = (java.sql.PreparedStatement) conn.prepareStatement(sql);
ps.setObject(1, "%"+request.getParameter("pname")+"%");
ResultSet rs = ps.executeQuery();


PHP代码如下:

$query = "INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("sss", $val1, $val2, $val3);
$val1 = 'Stuttgart';
$val2 = 'DEU';
$val3 = 'Baden-Wuerttemberg';
/* Execute the statement */
$stmt->execute();


这样用户拼接的变量无论内容是什么,都会被当做替代符号?所替代的值,数据库也不会将用户拼接进来的数据,当做部分SQL语句去解析。

由于ORM框架的流行,很容易让人误解该漏洞没有了。其实ORM框架即使通过模型来做数据操作,还是支持用户把变量拼接到SQL中去的,所以我们要注意。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: