【问题标题】:Will these security functions be enough?这些安全功能就够了吗?
【发布时间】:2011-02-15 15:45:37
【问题描述】:

我正在努力保护我的网站,这样我就不会受到 sql 注入或 xss 的攻击。

这是我的代码:

//here's the form (abbreviated)
<form>
<label for="first_name" class="styled">First Name:</label>
<input type="text" id="first_name" name="first_name" value="<?php if (!empty($first_name)) echo $first_name; ?>" /><br />

//submit button etc
</form>


if (isset($_POST['submit'])) {

 //gets rid of extra whitesapce and escapes
 $first_name = mysqli_real_escape_string($dbc, trim($_POST['first_name']));

 //check if $first_name is a string
 if(!is_string($first_name)
 { 
 echo "not string"; 
 }

 //then insert into the database. 
 .......

}

mysqli_real_escape_string:我知道这个函数会转义某些字母,例如\n \r,所以当数据输入到dbc时,它会在所有转义字母旁边都有'\'吗?

  • 这个脚本是否足以阻止大多数 sql 注入?只是转义并检查数据是否为字符串。对于整数值(比如用户输入价格),我只是:is_numeric()

  • 我应该如何使用htmlspecialchars?我应该只在回显和显示用户数据时使用它吗?还是在将数据插入数据库时​​也应该使用它?

  • 什么时候应该使用strip_tagshtmlspecialchars

所以有了所有这些功能:

if (isset($_POST['submit'])) {

 //gets rid of extra whitesapce and escapes
 $first_name = mysqli_real_escape_string($dbc, trim($_POST['first_name']));

 //check if $first_name is a string
 if(!is_string($first_name)
 { 
 echo "not string"; 
 }

 //gets rid of any <,>,&
 htmlspecialchars($first_name);

 //strips any tags with the first name
 strip_tags($first_name)

 //then insert into the database. 
 .......

}

sql注入应该使用哪些函数,xss应该使用哪些函数?

用户何时可以对我插入 xss 脚本?什么时候有表格?

【问题讨论】:

  • 我建议进行适当的表单验证,而不是仅仅清除用户提供的数据。
  • 正确的表单验证是什么意思?
  • 当我说正确的表单验证时,我主要想到一些 Web 框架中的示例,这些框架使用编程语言中构建的 html 表单的抽象,即创建一个类来表示一个表单,该表单将知道它具有哪些字段以及如何验证它们,返回清理后的数据,打印出 html 等。在您的示例中,您可以使用正则表达式('\w+')验证您的 $first_name,如果验证通过,您很确定您没有字符串中的任何不安全字符,如反斜杠等,否则会引发错误。

标签: php mysql security xss sql-injection


【解决方案1】:

对于 SQL 注入,mysql_real_escape_string 应该可以工作。 (完全可以肯定,你可以使用准备好的语句)

对于 XSS,htmlspecialchars 应该可以工作。 strip_tags 可能不安全,因为有人可以巧妙地伪装他们的 javascript。

【讨论】:

  • 所以任何用户可以输入数据的地方,我都应该使用htmlspecialchars,如果我将数据插入dbc,我应该使用mysql_real_espace_string和prepared statements?
  • 是的。 (real_escape_string 或准备好的语句)你不(可能不应该)同时使用两者。
【解决方案2】:

当您在 HTML 中嵌入用户提供的信息时,您应该使用htmlspecialchars。每当您在 SQL 中嵌入用户提供的信息时,都应该使用mysql_real_escape_string。遵循这些规则,你应该没问题。

但是请注意,更好的数据库安全解决方案是使用准备好的/参数化查询(请参阅 herehere),因为它们会为您处理转义,消除您忘记的可能性。

另外,别忘了检查magic quotes

【讨论】:

    【解决方案3】:

    检查数据是否为字符串是没有用的:字符串正是您用于注入的内容。

    real_escape_string 是一种合理的但不能保证避免 SQL 注入的方法,因为转义例程存在错误且无法正确转义事物的风险(事实上,之前已经存在错误)。正确的做法是使用parameterized queries - 这将数据与查询的结构分开,使得注入成为不可能。但是,如果您绝对不能使用参数化查询,那么 real_escape_string(打开连接时带有 set_charset)是您能做的最好的事情。

    您将希望在用户可以触摸的任何内容上使用 htmlspecialchars,并且希望在它显示在页面上的那一刻使用它。如果您希望用户格式化帖子或任何内容,那么您应该为他们提供一种格式化语言,例如 BBCode(并在运行 htmlspecialchars 之后转换 BBCode)。如果你需要存储纯 HTML,你不会想使用 htmlspecialchars,但你会想确保只有受信任的人才能在那里写。例如,如果您正在写博客,那么在博客文章本身中允许使用纯 HTML 可能没问题,因为只有博客编辑器可以在那里写东西。但是,您不会希望在 cmets 中允许它,因为每个人都可以在那里写东西,而这只会让像 cross-site scripting 这样的东西变得太容易了。

    【讨论】:

      【解决方案4】:

      如果您要打印 HTML,您应该先用HTML Purifier 清理它。将其视为strip_tags() 的高级(和可定制)版本。

      为了插入数据库,我使用prepared statements。这是万无一失的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-08
        • 1970-01-01
        • 1970-01-01
        • 2014-04-01
        • 2021-02-20
        • 2017-03-09
        相关资源
        最近更新 更多