mysql防注入

所谓SQL注入,就是通过把SQL(结构化查询语句)命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句 比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入攻击。原理SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。根据相关技术原理,SQL注入可以分为平台层注入和代码层注入。前者由不安全的数据库配置或数据库平台的漏洞所致;后者主要是由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。基于此,SQL注入的产生原因通常表现在以下几方面:

①不当的类型处理;

②不安全的数据库配置;

③不合理的查询集处理;

④不当的错误处理;

⑤转义字符处理不合适;

⑥多个提交处理不当。


攻击当应用程序使用输入内容来构造动态sql语句以访问数据库时,会发生sql注入攻击。如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生sql注入。sql注入可能导致攻击者使用应用程序登陆在数据库中执行命令。相关的SQL注入可以通过测试工具pangolin进行。如果应用程序使用特权过高的帐户连接到数据库,这种问题会变得很严重。在某些表单中,用户输入的内容直接用来构造动态sql命令,或者作为存储过程的输入参数,这些表单特别容易受到sql注入的攻击。而许多网站程序在编写时,没有对用户输入的合法性进行判断或者程序中本身的变量处理不当,使应用程序存在安全隐患。这样,用户就可以提交一段数据库查询的代码,根据程序返回的结果,获得一些敏感的信息或者控制整个服务器,于是sql注入就发生了。


防护 归纳一下,主要有以下几点:

 1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和双"-"进行转换等。

2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。

3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。

4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。

5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装

6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。

动手实践

 1.php.ini中配置PHP magic_quotes_gpc=on,魔术引号,这个特性在PHP5.3.0中已经废弃并且在5.4.0中已经移除了,所以没有理由再使用魔术引号,因为它不再是 PHP 支持的一部分。 不过它帮助了新手在不知不觉中写出了更好(更安全)的代码。 但是在处理代码的时候,最好是更改你的代码而不是依赖于魔术引号的开启。

2.addslashes();一个使用 addslashes() 的例子是当你要往数据库中输入数据时。 例如,将名字 O'reilly 插入到数据库中,这就需要对其进行转义。 强烈建议使用 DBMS 指定的转义函数 (比如 MySQL 是 mysqli_real_escape_string(),PostgreSQL 是 pg_escape_string()),但是如果你使用的 DBMS 没有一个转义函数,并且使用 \ 来转义特殊字符,你可以使用这个函数。 仅仅是为了获取插入数据库的数据,额外的 \ 并不会插入。 当 PHP 指令magic_quotes_sybase 被设置成 on 时,意味着插入 ' 时将使用 ' 进行转义。PHP 5.4 之前 PHP 指令 magic_quotes_gpc 默认是 on, 实际上所有的 GET、POST 和 COOKIE 数据都用被 addslashes() 了。 不要对已经被magic_quotes_gpc 转义过的字符串使用 addslashes(),因为这样会导致双层转义。 遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。

3.mysqli::real_escape_string() example

这个面向对象的例子

<?php

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");


/* check connection */

if (mysqli_connect_errno()) {

    printf("Connect failed: %s\n", mysqli_connect_error());

    exit();

}


$mysqli->query("CREATE TEMPORARY TABLE myCity LIKE City");


$city = "'s Hertogenbosch";


/* this query will fail, cause we didn't escape $city */

if (!$mysqli->query("INSERT into myCity (Name) VALUES ('$city')")) {

    printf("Error: %s\n", $mysqli->sqlstate);

}


$city = $mysqli->real_escape_string($city);


/* this query with escaped $city will work */

if ($mysqli->query("INSERT into myCity (Name) VALUES ('$city')")) {

    printf("%d Row inserted.\n", $mysqli->affected_rows);

}


$mysqli->close();

?></pre><p><span style="color: rgb(51, 51, 51); font-family: arial, 宋体, sans-serif; font-size: 14px; line-height: 24px; text-indent: 28px; background-color: rgb(255, 255, 255);"></span>面向过程的例子<br/></p><pre class="brush:php;toolbar:false"><?php

$link = mysqli_connect("localhost", "my_user", "my_password", "world");


/* check connection */

if (mysqli_connect_errno()) {

    printf("Connect failed: %s\n", mysqli_connect_error());

    exit();

}


mysqli_query($link, "CREATE TEMPORARY TABLE myCity LIKE City");


$city = "'s Hertogenbosch";


/* this query will fail, cause we didn't escape $city */

if (!mysqli_query($link, "INSERT into myCity (Name) VALUES ('$city')")) {

    printf("Error: %s\n", mysqli_sqlstate($link));

}


$city = mysqli_real_escape_string($link, $city);


/* this query with escaped $city will work */

if (mysqli_query($link, "INSERT into myCity (Name) VALUES ('$city')")) {

    printf("%d Row inserted.\n", mysqli_affected_rows($link));

}


mysqli_close($link);

?>

上面例子运行结果是

Error: 42000

1 Row inserted.


nickname
content