【问题标题】:Security Scan On Site现场安全扫描
【发布时间】:2009-03-16 17:54:22
【问题描述】:

我最近对我工作的一个网站进行了安全审核。这是使用 Acunetix Web Vulnerability Scanner 完成的。这带来了一堆我正在整理的结果。

出现了很多关于 XSS 的点击,但我不确定它们是否是误报。

代码如:

if(isset($_GET['variableNameX']))
    $var_to_use_in_app = mysql_escape_string(trim($_GET['variableNameX']));

以对 XSS 开放的方式回归。任何带有查询字符串的页面是否会返回可能对 XSS 开放,或者是否足够聪明,知道我正在处理这个服务器端?

感谢您的帮助。

【问题讨论】:

    标签: php security web-applications xss


    【解决方案1】:

    如果有 HTML 传递到 querystring 参数中,你会在页面上显示它吗?如果是这样,这不是误报。

    换句话说,如果你通过了,就会有这样的东西: http://www.example.com/?myVar=Test

    如果您在页面上显示 myVar 的结果而无需测试 HTML/Script,那么有人可能会将其更改为: http://www.example.com/?myVar=<b>Test</b&gt;

    或者类似的东西: http://www.example.com/?myVar=<script>+doSomethingBad()+</script&gt; (可能编码...但你明白了)

    【讨论】:

    • 在这种情况下,它实际上是作为 var 从第三方产品传递到 API 中的……但在其他情况下,它会传递到 SQL 中。转义字符串不会导致所有这些都中断吗?我测试了一个 javascript 警报,但它没有执行。
    • 对,您应该在将 HTML 写入客户端之前对其进行编码。我使用的在线扫描服务通常有一个“复制”选项,可以准确地向您展示您的网页是如何易受攻击的。
    【解决方案2】:

    $var_to_use_in_app = mysql_escape_string(trim($_GET['variableNameX']));

    这通常是错误的做法。应用程序内部使用的字符串应始终是纯文本版本。然后,您可以确定您的任何字符串操作都不会破坏它,并且您不会将错误的内容输出到页面。

    例如,如果您有提交的字符串:

    O'Reilly
    

    mysql_escape_string 会将其转义为:

    O\'Reilly
    

    当您将该字符串输出到 HTML 页面时,它看起来很傻。如果你把它输出到一个表单域,然后再次提交,你会得到 another 反斜杠,它会变成两个黑斜杠,如果再次编辑会变成四个、八个……和很快你就会得到由数百个反斜杠组成的字符串。这是在编写不佳的 CMS 和启用了 evil magic_quotes 功能的服务器中常见的问题。

    如果你想把名字的前两个字母放入数据库查询中,你可以剪掉子字符串:

    O\
    

    然后将其连接到查询中:

    SELECT * FROM users WHERE namefirst2='O\';
    

    哎呀,语法错误,该字符串现在未终止。对预转义字符串进行字符串处理的变体同样容易让您陷入安全问题。

    不要使用这种方法,而是将字符串作为简单的未转义文本字符串保存在应用程序中的所有位置,除了在最终输出阶段将它们连接成 SQL 或 HTML 中的分隔文字。对于 SQL:

    "SELECT * FROM users WHERE name='".mysql_real_escape_string($name)."';"
    

    注意“真实”函数名称 — 对于东亚字符集和使用 ANSI SQL_MODE 集的连接/数据库等某些极端情况,普通的旧 mysql_escape_string 会失败,因此通常您应该始终使用“真实”版本。

    您可以定义一个与 mysql_real_escape_string 相同但名称更短的函数(例如 m()),以使其不那么难看。或者,更好的是,看看mysqli的parameterised queries

    对于 HTML,应该使用 htmlspecialchars() 函数进行转义:

    <div id="greeting">
        Hello, Mr. <?php echo htmlspecialchars($name); ?>!
    </div>
    

    您可以定义一个执行 echo(htmlspecialchars()) 但名称更短的函数(例如 h()),以使其不那么难看。

    如果您错过了对 htmlspecialchars 的调用,那么您的扫描器绝对正确地告诉您您的网站易受 XSS 攻击。但不要觉得太糟糕,几乎所有其他 PHP 程序员都会犯同样的错误。

    mysql_[real_]escape_string 在这里根本没有帮助,因为在 HTML 中从文本中跳出的字符是 '&'、'

    <script>alert("I'm stealing your cookies! "+document.cookie);</script>
    

    只被转义到:

    <script>alert("I\'m stealing your cookies! "+document.cookie);</script>
    

    就安全性而言,这没有任何帮助。

    【讨论】:

      【解决方案3】:

      Acunetix 是一个不错的工具,但它不能替代基于手动的应用渗透测试。它没有遵循潜在漏洞的逻辑......

      它肯定在银行中使用,我已在提案(已获批准)中推荐它来进行正式的工作。如果你有一个相当复杂的应用程序,它有很多动态生成的页面并且预算/时间是一个问题,你可以使用 Acunetix 或类似的工具来引导你指向应用程序潜在热点的方向。然后,您可以通过手动方式专注于这些领域 - 无论是手动测试还是逐步执行代码。这就是您的渗透测试机构赢得荣誉的地方。

      客户根本没有资源来彻底检查大型应用程序。

      哦,请记住,有很多误报。

      【讨论】:

        【解决方案4】:

        我不知道具体的工具,但它不太可能“知道”您正在服务器端处理它,因为这需要在一般情况下解决等效问题。除此之外,该工具甚至可以访问您的 mysql 实例吗?它怎么知道?

        【讨论】:

          【解决方案5】:

          我使用过的很多工具都会返回误报。如果它正在审核实际代码,那么可能会返回一个潜在的漏洞,并且将 $_GET 或 $_POST 变量分配给正常变量的时间,即使它稍后没有被打印出来。

          为了安全起见,您应该检查所有内容,并假设没有什么是误报。

          【讨论】:

            猜你喜欢
            • 2020-05-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-01-11
            • 1970-01-01
            • 2021-01-29
            • 2020-06-22
            相关资源
            最近更新 更多