【问题标题】:How to prevent against XSS and SQL injection [duplicate]如何防止 XSS 和 SQL 注入
【发布时间】:2013-05-20 21:46:59
【问题描述】:

我想从用户那里检查我的数据是否存在 XSS 和 SQL 注入,这就是我尝试的方式

if (isset($_GET['membernumber'])) 
{
    $mem = htmlentities($_GET['membernumber']);
    $memberparamter = cleanData($mem);

}

但是哪种方法是最好/正确的检查方法?

方法一

function cleanData($data)
    {
        $data=mysql_real_escape_string($data);
        $data=trim($data);
        $data=stripcslashes($data);
        $data=htmlspecialchars($data);
        $data=strip_tags($data);
        return $data;
    }

方法二

function cleanData($data)
    {
        $data=mysql_real_escape_string($data);
        $data=trim($data);
        $data=strip_tags($data);
        return $data;
    }

方法3

htmlspecialchars(stripcslashes(trim($data)))

【问题讨论】:

  • 使用准备好的语句,它会处理所有这些问题
  • 成员编号应该是整数吗?为什么不直接使用intval($_GET['membernumber'])
  • 是的,它应该是一个 int

标签: php xss sql-injection


【解决方案1】:

如果您想防止 SQL 注入攻击,请使用准备好的语句。当你做类似的事情时

SELECT * FROM TABLE WHERE id = $_GET['x']

这个查询的问题是变量被认为是 SQL 语句的一部分。这意味着 DBMS 将解析/编译和执行变量以及查询的其余部分。如此有效,我可以提供类似

$x = "1); DROP TABLE users;"

并且由于它是语句的一部分,服务器将执行该命令。

当你引入prepared statements时,变量范围将被限制在一个参数的范围内,即使没有转义,也不会对查询的其余部分产生影响。这是因为 SQL 语句由数据库解析/优化/编译等,您所要做的就是绑定参数。 sql语句是一个模板

SELECT * FROM TABLE WHERE id = ?

使用准备好的语句的另一个好处是速度。由于模板已经解析/编译等,数据库不需要重复该过程,因此可以重复使用,您所要做的就是替换参数。

在 PHP 中,PDO 和 mysqli_* 函数都支持预处理语句。

mysqli 见http://php.net/manual/en/mysqli.prepare.php 对于 PDO,请参阅 http://php.net/manual/en/pdo.prepare.php

对于 XSS 攻击,您可以采取一些方法。第一个是在打印到页面时简单地转义任何用户输入。如此危险的字符,例如:

 <>"" // and so on

将替换为等效的 html 实体。所以&amp;lt;script&amp;gt;的情况下会转换成&amp;lt;script&amp;gt;

您还可以设置白名单方法,即只允许 X 标记用于用户输入。这对于面向内容的站点特别有用,在这些站点中,用户可能需要访问某些 html 标签,例如 div、p 标签等,但不需要访问脚本标签。任何不在白名单内的标签都将被过滤掉。这很难完全涵盖,因为有很多做事的方式,但它可以提供额外的安全性。请参阅http://php.net/manual/en/function.filter-var.php 了解更多信息。

第三种方法是用自定义标签替换 html 标签(就像 SO 一样)。所以一个单词前面的星可能代表&lt;strong&gt; html标签等等。

请注意,如果您确实采用了后两者,您仍然应该转义数据。即使过滤了所有用户输入数据,也应将其视为潜在危险,因为正如他们所说,剥猫皮的方法总是不止一种。

【讨论】:

  • Thanx :) 那么如果你必须防止 xss 和 sql inj,你会怎么做。像数字类型这样的用户输入。你能举个例子吗?
【解决方案2】:

它们都不够有效。

您应该像以前一样寻找消毒方法并使用准备好的语句。

【讨论】:

    【解决方案3】:

    如前所述,预准备语句是防止 SQL 注入的最佳方法之一。即,您不应将参数添加为最终查询字符串的一部分。您应该使用参数占位符,并通过键/值数组添加参数。

    如果您使用 PDO,请查看此页面,其中更详细地描述了准备好的语句:

    http://php.net/manual/en/pdo.prepared-statements.php

    可以在这里找到关于 PHP 输入过滤器的非常详尽的解释(以及一篇关于清理的好文章):

    http://coding.smashingmagazine.com/2011/01/11/keeping-web-users-safe-by-sanitizing-input-data/

    在此处查看 PHP 自己的过滤器/清理功能:

    http://www.php.net/manual/en/filter.filters.php

    您可能对 filter_var 和 filter_input 函数感兴趣:

    另外,这个问题有一些很好的提示: What's the best method for sanitizing user input with PHP?

    这个问题也有很好的提示: What are the best PHP input sanitizing functions?

    【讨论】:

      【解决方案4】:

      XSS $data=htmlspecialchars($data); sql注入 $data=stripcslashes($data);

      如果数据将存储到数据库中然后显示在网页上,你应该两者兼而有之。

      【讨论】:

      • 不,不是stripcslashes,而是使用准备好的语句。
      猜你喜欢
      • 2019-06-03
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-24
      • 2013-04-30
      • 1970-01-01
      相关资源
      最近更新 更多