我是不是从mysql注入安全?

时间:2010-08-28 15:32:22

标签: php sql-injection xss

这是否足以避免SQL注入?

mysql_real_escape_string(htmlentities (urlencode($_POST['postmessage'])));

4 个答案:

答案 0 :(得分:21)

mysql_real_escape_string()是您需要的唯一方法 在数据库中插入数据之前,不应该执行htmlentities()urlencode()。这些方法通常是在呈现您向用户提供的View时的代码。

避免SQL注入的更好方法是使用预准备语句


资源:

关于同一主题:

答案 1 :(得分:10)

我认为您混淆了两个安全问题:SQL injectioncross-site scripting (XSS)

如果在发送到SQL数据库的SQL查询中使用了不正确的清理用户输入,则网站很容易受到SQL注入攻击。例如,此代码引入了SQL注入漏洞:

mysql_query("INSERT INTO postmessages (postmessage) VALUES ('" . $_POST['postmessage'] . "')");

使用像mysql_real_escape_string这样的函数转义用户输入很容易解决这个问题:

mysql_query("INSERT INTO postmessages (postmessage) VALUES ('" . mysql_real_escape_string($_POST['postmessage']) . "')");

这就是您需要做的所有事情,但棘手的部分是记住为SQL语句中使用的每个用户输入执行此操作。

当在发送给客户端的HTML中使用用户输入时,网站容易受到跨站点脚本的攻击。例如,此代码引入了XSS漏洞:

echo "<div class='postmessage'>" . $_POST['postmessage'] . "</div>";

通过使用htmlspecialchars之类的函数转义用户输入来修复XSS漏洞:

echo "<div class='postmessage'>" . htmlspecialchars($_POST['postmessage']) . "</div>";

同样,这很容易做到,但很容易被遗忘。

通常,放置在数据库中用于稍后发送回HTML的用户输入将保存为未修改。也就是说,仅使用mysql_real_escape_string。但是,您可以转义用户输入以阻止XSS,然后转义XSS安全字符串以防止SQL注入:

mysql_query("INSERT INTO postmessages (postmessage) VALUES ('" . mysql_real_escape_string(htmlspecialchars($_POST['postmessage'])) . "')");

好处是,在将它们写入HTML之前,您不需要记住使用htmlspecialchars从数据库中转义值。缺点是某些值可能需要使用不同的函数进行转义。例如,用户名可能会使用htmlspecialchars进行转义,但“postmessage”可能允许使用BBcode,Markdown或HTML的子集。如果您转义了所有输入以阻止XSS,那么您需要使用例如htmlspecialchars_decode从数据库中取消值。

一个问题是,转义转义字符串并不总是返回原始字符串(unescape(escape($orig))不一定与$orig相同)。即使使用htmlspecialcharshtmlspecialchars_decode,使用不同的引用样式也会导致此问题。另一个例子是,如果使用strip_tags,则无法恢复信息;您将无法撤消strip_tags。因此,许多开发人员选择仅使用mysql_real_escape_string将值保存到数据库中,并htmlspecialchars(或其他)从数据库中准备要在HTML中使用的字符串。

答案 2 :(得分:1)

您还应该确保在您插入代码的地方使用“。

例如,如果你这样做

$_POST['userid'] = mysql_real_escape_string($_POST['userid']);
mysql_query('SELECT * FROM user WHERE userid = '. $_POST['userid']);

mysql_real_escape_string无济于事。因为$ _POST ['userid']没有被'。

包围

所以你应该做

$_POST['userid'] = mysql_real_escape_string($_POST['userid']);
mysql_query('SELET * FROM user WHERE userid = \''. $_POST['userid'] .'\'');

代替。

因此,在变量上使用mysql_real_escape_string并不意味着它们在任何查询中都是安全的。

另一种方法是使用Prepared语句。

答案 3 :(得分:1)

是的,但是没有使用mysql_real_escape_string()的原因。首先,输入是一种痛苦。其次,你必须记住每次都使用它。第三,它使你的代码变得丑陋。第四,你必须记住引用你的字符串。第五,以这种方式在db中插入blob更加困难。

从长远来看,学习PDO会让你的生活更美好。它比单纯使用mysql_real_escape_string()更难学,但长期的好处超过了学习曲线的不便。