- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
今天早些时候有人问了一个关于 input validation strategies in web apps 的问题。 .
在撰写本文时,最佳答案建议在 PHP
中仅使用 htmlspecialchars
和 mysql_real_escape_string
。
我的问题是:这样就够了吗?还有更多我们应该知道的吗?这些功能在哪里分解?
最佳答案
当涉及到数据库查询时,请始终尝试使用准备好的参数化查询。 mysqli
和 PDO
库支持这一点。这比使用 mysql_real_escape_string
等转义函数要安全得多。
是的,mysql_real_escape_string
实际上只是一个字符串转义函数。它不是 Elixir 。它将做的只是转义危险字符,以便它们可以安全地用于单个查询字符串。但是,如果您不事先对输入进行清理,那么您将容易受到某些攻击向量的攻击。</p>
想象一下下面的 SQL:
$result = "SELECT fields FROM table WHERE id = ".mysql_real_escape_string($_POST['id']);
您应该能够看到这很容易被利用。
想象一下 id
参数包含常见的攻击向量:
1 OR 1=1
那里没有要编码的危险字符,因此它将直接通过转义过滤器。离开我们:
SELECT fields FROM table WHERE id= 1 OR 1=1
这是一个可爱的 SQL 注入(inject)向量,允许攻击者返回所有行。或者
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
这允许攻击者在这个完全虚构的示例中返回第一个管理员的详细信息。
虽然这些功能很有用,但必须小心使用。您需要确保所有 Web 输入都经过一定程度的验证。在这种情况下,我们看到我们可以被利用,因为我们没有检查我们用作数字的变量是否实际上是数字。在 PHP 中,您应该广泛使用一组函数来检查输入是否为整数、 float 、字母数字等。但是当涉及到 SQL 时,请注意大多数准备好的语句的值。如果上面的代码是一个准备好的语句,那么上面的代码就会是安全的,因为数据库函数会知道 1 OR 1=1
不是有效的文字。
至于 htmlspecialchars()
。这本身就是一个雷区。
PHP 中存在一个真正的问题,它有一系列不同的与 html 相关的转义函数,并且没有明确的指导说明哪些函数具体做什么。
首先,如果你在一个 HTML 标记中,你就遇到了真正的麻烦。看看
echo '<img src= "' . htmlspecialchars($_GET['imagesrc']) . '" />';
我们已经在一个 HTML 标记中,所以我们不需要 < 或 > 来做任何危险的事情。我们的攻击向量可能只是 javascript:alert(document.cookie)
现在生成的 HTML 看起来像
<img src= "javascript:alert(document.cookie)" />
攻击直接通过。
情况变得更糟。为什么?因为 htmlspecialchars
(以这种方式调用时)只编码双引号而不是单引号。所以如果我们有
echo "<img src= '" . htmlspecialchars($_GET['imagesrc']) . ". />";
我们的邪恶攻击者现在可以注入(inject)全新的参数
pic.png' onclick='location.href=xxx' onmouseover='...
给我们
<img src='pic.png' onclick='location.href=xxx' onmouseover='...' />
在这些情况下,没有 Elixir ,您只需要自己清理输入即可。如果您尝试过滤掉不良字符,您肯定会失败。采取白名单方法,只让好的字符通过。看XSS cheat sheet举例说明向量的多样性
即使您在 HTML 标记之外使用 htmlspecialchars($string)
,您仍然容易受到多字节字符集攻击向量的攻击。</p>
最有效的方法是使用 mb_convert_encoding 和 htmlentities 的组合,如下所示。
$str = mb_convert_encoding($str, 'UTF-8', 'UTF-8');
$str = htmlentities($str, ENT_QUOTES, 'UTF-8');
即使这样,IE6 也容易受到攻击,因为它处理 UTF 的方式。但是,您可以回退到更有限的编码,例如 ISO-8859-1,直到 IE6 的使用率下降。
有关多字节问题的更深入研究,请参阅 https://stackoverflow.com/a/12118602/1820
关于php - htmlspecialchars 和 mysql_real_escape_string 是否可以防止我的 PHP 代码被注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/110575/
原帖: 我的脚本不工作(它不记录数据)。它在我添加 mysql_real_escape_string 之前工作,所以我想知道我是否没有正确实现它: $array = json_decode($down
如果我在将变量放入 mysql 表之前使用了 mysql_real_escape_string,我是否需要对从表中取出的任何变量再次使用它? 最佳答案 如果要将变量放回数据库,则需要再次使用它。否则,
我正在开发一个使用 mysql.h 库的 C 程序。这是代码: int newproduct(){ char *name;//nombre del prducto char *de
如果我输入 ' 在我的搜索栏中,我收到一个 mysql 错误,因为“刺痛”没有被转义——它认为。 但是我之所以无法转义,是因为我认为它目前不是一个字符串。 搜索框使用 ajax 动态生成搜索结果,就像
我收到 警告:mysql_real_escape_string() [function.mysql-real-escape-string]:用户 'username'@'localhost' 的访问被
我有一个 PHP 脚本,它在从用户填写的表单中获取数据后将一条记录插入到数据库中。我在我的本地机器(WAMP 服务器)上开发并在我的 PHP 脚本中包含以下代码: $name = mysql_real
示例代码: $email = "" . $_POST['email']; $con = mysql_connect("localhost","user","pass") or die('Could
什么时候使用 mysql_real_escape_string 是正确的时间? 当我使用 isset(mysql_escape_string($_GET['param'])) 时是否应该使用它, 当我
我的每个 php 页面的顶部都有以下代码: foreach ($_POST as $key => $value) { if (!is_array($value)) {
我使用 imap_mail (php) 从我的邮件服务器收集电子邮件,在使用 mysql_real_escape_string 后分解结果并将其保存到数据库。 如果我从数据库检索后将其显示在文本区域中
我正在创建一个magento模块,并且在 Controller 中我试图生成一个查询。例如:"INSERT INTO ". $resource->getTableName('mymod/mymodta
我的查询是这样的, ... ON (`Test`.`id` = `Form`.`close_`%)... 它抛出错误,提示Syntax error or access violation: 1064。
这个问题已经有答案了: How to change mysql to mysqli? (12 个回答) 已关闭 2 年前。 由于 mysql_real_escape_string 现已弃用,我必须更改
我们知道,在php脚本中的mysql上执行之前,所有用户输入都必须通过mysql_real_escape_string()函数进行转义。并且知道此函数在用户输入中的任何 ' 或 " 字符之前插入\。假
我粘贴谷歌地图代码 View Larger Map 在文本区域中并使用mysql_real_escape_string(trim($_POST'map'])) 但是从 mysql 表中获取数据时
我正在尝试清理进入数据库的字符串。但使用下面的代码,我没有得到数据库的更新。 第一页以输入形式发布此内容: $note="Here is some example text"; 接收页面: $note
好的。所以我做了一个表格。如果我在从表单中检索到的变量 $usrname (是的,拼写正确)上输入 mysql_real_escape_string ,它会返回我的另一个变量 $verify 为 fa
我不明白为什么 mysql_real_escape_string 需要转义换行符和回车符: \n 和 \r 使用 \n 和 \r 的 SQL 中可能存在哪些安全漏洞? UPDATE tbl SET f
我正在将我的应用程序从 Mysql 扩展移至 PHP PDO。我面临一个奇怪的问题。在我的开发环境中,我的数据库服务器 [MySQL] 和 Web 服务器都位于单个系统中,而在测试环境中,Web 和数
因此,即使使用 mysql_real_escape_string 清理数据,您也可以使用 %27 进行 SQL 注入(inject) %27) SQL INJECTION HERE %2F* 怎么办?
我是一名优秀的程序员,十分优秀!