When it comes to database queries, always try and use prepared parameterised queries. The mysqli and PDO libraries support this. This is infinitely safer than using escaping functions such as mysql_real_escape_string.
$result = "SELECT fields FROM table WHERE id = ".mysql_real_escape_string($_POST['id']);
你应该能够看到这是脆弱的利用。
Imagine the id parameter contained the common attack vector:
1 OR 1=1
这里没有危险的字符需要编码,所以它会直接通过转义过滤器:
SELECT fields FROM table WHERE id= 1 OR 1=1
这是一个可爱的 SQL 注入向量,允许攻击者返回所有行。
或者
1 or is_admin=1 order by id limit 1
产生了
SELECT fields FROM table WHERE id=1 or is_admin=1 order by id limit 1
Which allows the attacker to return the first administrator's details in this completely fictional example.
虽然这些功能是有用的,但必须谨慎使用。你需要确保所有的 web 输入在一定程度上都是有效的。在这个例子中,我们看到我们可以被利用,因为我们没有检查我们用作数字的变量是否实际上是数字。在 PHP 中,应该广泛使用一组函数来检查输入是否为整数、浮点数、字母数字等。但是当涉及到 SQL 时,最需要注意的是准备语句的价值。如果上面的代码是一个准备好的语句,那么它是安全的,因为数据库函数会知道 1 OR 1=1不是一个有效的文本。
至于 htmlspecialchars(),那是个雷区。
PHP 中存在一个真正的问题,它有一整套与 html 相关的转义函数,而且没有关于哪些函数执行哪些操作的明确指导。
In these cases, there is no magic bullet, you just have to santise the input yourself. If you try and filter out bad characters you will surely fail. Take a whitelist approach and only let through the chars which are good. Look at the XSS cheat sheet for examples on how diverse vectors can be
即使在 HTML 标记之外使用 htmlspecialchars($string),仍然容易受到多字节字符集攻击向量的影响。
最有效的方法是按照下面的方式使用 mb _ trans _ coding 和 htmlentis 的组合。
请改用参数化查询(如上所述)。您可以通过例如 PDO 或通过像 PEAR DB 这样的包装器来使用它们
Make sure that magic_quotes_gpc and magic_quotes_runtime are off at all times, and never get accidentally turned on, not even briefly. These are an early and deeply misguided attempt by PHP's developers to prevent security problems (which destroys data)
没有什么灵丹妙药可以阻止 HTML 注入(比如跨网站脚本) ,但是如果你使用一个库或者模板系统来输出 HTML,你可以更容易地做到这一点。阅读相关文档,了解如何恰当地转义事物。
当涉及到数据库查询时,
总是尝试和使用准备好的
参数化查询
PDO 库支持这一点
比逃跑安全多了
功能,例如
Mysql _ real _ escape _ string.
是的,mysql _ real _ escape _ string 是
实际上只是一个字符串转义
function. It is not a magic bullet.
All it will do is escape dangerous
characters in order that they can be
在单个查询字符串中使用是安全的。
However, if you do not sanitise your
inputs beforehand, then you will be
容易受到某些攻击载体的攻击。
设想下面的 SQL:
$result = “ SELECT 字段 FROM table
WHERE id =
”. mysql _ real _ escape _ string ($_ POST [‘ id’]) ;
你应该能看出来
很容易被利用,想象一下
参数包含了常见的攻击
矢量:
1 OR 1=1
里面没有危险的字符
编码,所以它会直接通过
through the escaping filter. Leaving
我们: