php如何防止sql注入
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php如何防止sql注入相关的知识,希望对你有一定的参考价值。
php防止sql注入是一个比较低级的问题了,这个问题其实在我大一上学期做第一个个人博客的时候就已经关注过了,不过简单的说一下关于PHP防注入的方式吧。
使用PDO防注入。
这是最简单直接的一种方式,当然低版本的PHP一般不支持PDO方式去操作,那么就只能采用其它方式。
采用escape函数过滤非法字符。
escape可以将非法字符比如 斜杠等非法字符转义,防止sql注入,这种方式简单粗暴,但是不太建议这么用。
自己手写过滤函数,手写一个php sql非法参数过滤函数来说还是比较简单的,但是你的函数需要非常的健壮,不让仍然有可能被非法黑客攻击;你的Coding水平直接决定了你的函数的健壮性。
各种框架里面其实都有对于非法字符过滤的支持,最简单的比如ThinkPHP,你可以直接防止注入。
写一个PHP扩展对于进入参数进行有选择的过滤。 开发一个PHP扩展是对于一个PHP高级程序员必备的技能,将你需要的功能打包在PHP扩展里面,就像黑词过滤一样进行检查,是非常方便的。一般都是用在自己写框架路由器转发的时候,如果你用扩展实现框架的路由器转发的话,可以顺便将参数过滤加入到PHP扩展里面,通过C去实现。
对于现在的防注入技术其实已经成熟了,对于一个站点该关心的不是防注入了,而是大规模高并发如何处理的问题,或者关于各种其他漏洞,比如现在世界上仍然有百分之80使用redis的站点存在redis漏洞,通过redis漏洞可以直接拿到机器的访问权限,一般来说都是直接给你种一个挖矿机器人来。
参考技术A这个方法比较多,这里简单举个例子:
提交的变量中所有的 ' (单引号), " (双引号), \\ (反斜线) and 空字符会自动转为含有反斜线的转义字符,给SQL注入带来不少的麻烦。
请看清楚:“麻烦”而已~这并不意味着PHP防范SQL注入,书中就讲到了利用改变注入语句的编码来绕过转义的方法,比如将SQL语句转成ASCII编码(类似:char(100,58,92,108,111,99,97,108,104,111,115,116…)这样的格式),或者转成16进制编码,甚至还有其他形式的编码,这样以来,转义过滤便被绕过去了
// 去除转义字符
function stripslashes_array($array)if (is_array($array))
foreach ($array as $k => $v)
$array[$k] = stripslashes_array($v);
else if (is_string($array))
$array = stripslashes($array);
return $array;
@set_magic_quotes_runtime(0); // 判断 magic_quotes_gpc 状态
if (@get_magic_quotes_gpc())
$_GET = stripslashes_array($_GET);
$_POST = stripslashes_array($_POST);
$_COOKIE = stripslashes_array($_COOKIE);
PHP防范SQL注入的代码
str_replace("_","\\_",$keywords);//转义掉”_” $keywords =
str_replace("%","\\%",$keywords);//转义掉”%” 参考技术B 额,这是我老师给的答案
答:过滤一些常见的数据库操作关键字,
select ,insert,update,delete,and,*等或通过系统函数addslashes对内容进行过滤
php配置文件中register_globals=off;设置为关闭状态.(作用将注册全局变量关闭);如接收POST表单的值使用$_POST['user'],假设设置为ON的话$user才接收值
sql语句书写的时候尽量不要省略小引号(tab上面那个)和单引号
提高数据库命名技巧,对于一些重要的字段根据程序的特点命名,使之不易被猜中
对于常的方法加以封装,避免直接暴漏SQL语句
开启PHP安全模式safe_mode=on
打开magic_quotes_gpc来防止SQL注入,默认为关闭,开启后自动把用户提交sql查询语句进行转换把"'"转换成"\'"
控制错误信息输出,关闭错误信息提示,将错误信息写到系统日志
使用mysqlI或PDO预处理本回答被提问者和网友采纳
使用 MySQLi 时如何防止 SQL 注入
【中文标题】使用 MySQLi 时如何防止 SQL 注入【英文标题】:How to prevent SQL-injection when using MySQLi 【发布时间】:2015-05-04 15:26:01 【问题描述】:我正在构建一个简单的表单,并希望保护它免受以下 SQL 注入的影响: - 盲注 - 基于布尔值 - 盲注 - 基于 UNION 查询 - 堆叠查询 - 基于错误的注入
我以为我已经确保一切安全,但是当我运行 SQL-map 时,它仍然会利用我的数据库。
<?php
$input = $_GET['input'];
if ($input)
$db = mysqli_connect("localhost", "sec", "dubbelgeheim", "bookshop");
// Check connection
if (mysqli_connect_errno())
echo "Failed to connect to MySQL: " . mysqli_connect_error();
$escaper = real_escape_string($input);
$statement = $db->prepare("SELECT * FROM productcomment WHERE ProductId = ? LIMIT 1");
$statement->bind_param("s", $escaper);
$statement->execute();
$result = $statement->get_result();
$statement->close();
$count = $result->num_rows;
if ($count > 0)
while ($row = $result->fetch_assoc())
echo "Product:" . $row['ProductId'] . "<br>";
echo "Annotation:" . $row['Comment'] . "<br>";
echo "TestOK!<br>";
else
echo 'No record!';
$result->free();
$db->close();
?>
我是不是忘记了什么?
谁能帮忙?
提前致谢!
【问题讨论】:
我会选择 PDO 而不是 MySQLi。"it still exploits my database"
你能提供更多细节吗?我在这里看不到任何可以被利用的东西。
单独使用准备好的语句并不能保证不会注入。确保您已将 XSS 漏洞利用考虑在内。
顺便说一句; real_escape_string()
isn't a core PHP function。 $city = $mysqli->real_escape_string($city);
是面向对象的风格 php.net/manual/en/mysqli.real-escape-string.php - 所以,向我们展示这个函数的作用。
@GjertGjersund PDO 只给出 1045 错误..
【参考方案1】:
您的问题是由您显示mysqli_connect_error()
引起的。这可以用于测试,但不应在生产代码中使用。你也不需要$escaper = real_escape_string($input);
。
试试这个
/* check connection */
if (mysqli_connect_errno())
file_put_contents('MySQLiErrors.txt',date('[Y-m-d H:i:s]'). mysqli_connect_error()."\r\n", FILE_APPEND);
exit();
else
$statement = $db->prepare("SELECT * FROM productcomment WHERE ProductId = ? LIMIT 1");
$statement->bind_param("s", $input);
【讨论】:
感谢您的回复,但没有帮助。我仍然可以使用 sqlmap 进入我的数据库 你能看看我最近发布的这个主题吗? ***.com/questions/28850098/…以上是关于php如何防止sql注入的主要内容,如果未能解决你的问题,请参考以下文章