清理HTML输入值

时间:2015-04-02 10:32:43

标签: javascript html security xss

您是否必须将引号(")以外的任何内容转换为(")内的:

<input type="text" value="$var">

我个人看不出如何在不使用" on*=...的情况下突破这一点。

这是对的吗?

编辑:显然有些人认为我的问题太模糊了;

<input type="text" value="<script>alert(0)</script>">未执行。因此,如果不使用",就无法摆脱使用。

这是对的吗?

5 个答案:

答案 0 :(得分:24)

您确实有两个问题(或者至少可以解释):

  1. 如果不允许引用,是否可以注入value引用的input[type="text"]属性?

  2. 如果不允许引用,可以注入元素的任意引用属性。

  3. 第二部分通过以下方式得到了简单的证明:

    <a href="javascript:alert(1234);">Foo</a>
    

    <div onmousemove="alert(123);">...
    

    第一个有点复杂。

    HTML5

    根据HTML5 spec

      

    属性值是文本和字符引用的混合,除了文本不能包含模糊符号的附加限制。

    在引用属性中进一步细化为:

      

    属性名称,后跟零个或多个空格字符,后跟一个U + 003D EQUALS SIGN字符,后跟零个或多个空格字符,后跟一个&#34;&#34;&#34; (U + 0022)字符,后跟属性值,除了上面给出的属性值的要求之外,它不能包含任何文字U + 0022 QUOTATION MARK字符(&#34;),最后是第二个单身&#34;&#34;&#34; (U + 0022)角色。

    简而言之,除了&#34;模棱两可的&符之外的任何角色。 (&[a-zA-Z0-9]+;当结果不是有效的字符引用时),引号字符在属性内有效。

    HTML 4.01

    HTML 4.01关于语法的描述性低于HTML5(HTML5最初创建的原因之一)。但是,它确实say this

      

    当脚本或样式数据是属性的值(样式或内部事件属性)时,作者应根据脚本或样式语言约定,在值内转义分隔单引号或双引号的出现。作者也应该避免出现&#34;&amp;&#34;如果&#34;&amp;&#34;并不意味着是角色参考的开始。

    注意,这是说作者应该做什么,而不是解析器应该做什么。因此,解析器在技术上可以接受或拒绝无效输入(或将其修改为有效)。

    XML 1.0

    XML 1.0 Spec将属性定义为:

      

    Attribute :: = Name Eq AttValue

    其中AttValue定义为:

      

    AttValue :: =&#39;&#34;&#39; ([^&lt;&amp;&#34;] |参考)*&#39;&#34;&#39; | &#34;&#39;&#34; ([^&lt;&amp;&#39;] |参考)*&#34;&#39;&#34;

    &类似于&#34;模糊的&符号&#34;来自HTML5,但它基本上是说&#34;任何未编码的&符号&#34;。

    请注意,它明确拒绝属性值中的<

    因此,虽然HTML5允许,但XML1.0明确否认它。

    意味着什么

    这意味着对于兼容且无错误的解析器,HTML5将忽略属性中的<个字符,而XML将会出错。

    这也意味着对于兼容且无错误的解析器,HTML 4.01将以未指定且可能奇怪的方式运行(因为规范没有详细说明行为)。

    这归结为问题的症结所在。在过去,HTML是如此宽松的规范,每个浏览器对于如何处理格式错误的HTML有不同的规则。每个人都会尝试修复&#34;它,或者&#34;解释&#34;你的意思是。这意味着虽然符合HTML5标准的浏览器无法在<input type="text" value="<script>alert(0)</script>">中执行JS,但没有什么可以说HTML 4.01兼容的浏览器不会。并且没有什么可以说XML或HTML5解析器中可能不存在导致它被执行的错误(尽管这将是一个非常重要的问题)。

    THAT 是OWASP(以及大多数安全专家)建议您对属性值中的所有非字母数字字符或&<"进行编码的原因。这样做没有任何成本,只有增加了知道浏览器解析器将如何解释该值的安全性。

    吗?没有。但是深度防守表明,由于没有这样做的成本,潜在的好处是值得的。

答案 1 :(得分:6)

当用户提交数据时,您需要确保他们提供了您期望的内容。

例如,如果您需要一个数字,make sure the submitted data is a number。你也可以cast user data into other types。提交的所有内容最初都被视为一个字符串,因此强制将已知数字数据转换为整数或浮点数使得清理变得快速且无痛。

您需要确保不应包含任何HTML内容的字段实际上不包含HTML。有不同的方法可以解决这个问题。

您可以尝试使用htmlspecialchars转义HTML输入。您不应该使用htmlentities来中和HTML,因为它还会执行它认为也需要编码的重音和其他字符的编码。

您可以尝试删除任何可能的HTML。 strip_tags快速而简单,但也很草率。 HTML Purifier做了更彻底的工作,既剥离了所有HTML,又允许通过标签和属性选择性白名单。

您可以使用OWASP PHP Filters。它们使用起来非常简单有效。

您可以使用filter extension,它提供了一种全面的方法来清理用户输入。

<强>实施例

以下代码将从字符串中删除所有HTML标记:

$string = "<h1>Hello, World!</h1>";
$new_string = filter_var($string, FILTER_SANITIZE_STRING);
// $new_string is now "Hello, World!"

以下代码将确保变量的值是有效的IP地址:

$ip = "127.0.0.1";
$valid_ip = filter_var($ip, FILTER_VALIDATE_IP);
// $valid_ip is TRUE

$ip = "127.0.1.1.1.1";
$valid_ip = filter_var($ip, FILTER_VALIDATE_IP);
// $valid_ip is FALSE

清理和验证电子邮件地址:

<?php
$a = 'joe@example.org';
$b = 'bogus - at - example dot org';
$c = '(bogus@example.org)';

$sanitized_a = filter_var($a, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_a, FILTER_VALIDATE_EMAIL)) {
    echo "This (a) sanitized email address is considered valid.\n";
}

$sanitized_b = filter_var($b, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_b, FILTER_VALIDATE_EMAIL)) {
    echo "This sanitized email address is considered valid.";
} else {
    echo "This (b) sanitized email address is considered invalid.\n";
}

$sanitized_c = filter_var($c, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_c, FILTER_VALIDATE_EMAIL)) {
    echo "This (c) sanitized email address is considered valid.\n";
    echo "Before: $c\n";
    echo "After:  $sanitized_c\n";    
}
?>

参考:

  

What are the best PHP input sanitizing functions?

     

http://code.tutsplus.com/tutorials/sanitize-and-validate-data-with-php-filters--net-2595

     

https://security.stackexchange.com/q/42498/71827

     

http://php.net/manual/en/filter.examples.sanitization.php

答案 2 :(得分:3)

如果你的问题是&#34;什么类型的xss攻击是可能的&#34;然后你最好谷歌吧。我只是留下一些为什么要对你的输入进行消毒的例子

  • 如果输入是由echo '<input type="text" value="$var">'生成的,则简单'会将其分解。

  • 如果输入是PHP页面中的纯HTML,那么value=<?php deadly_php_script ?>会打破它

  • 如果这是HTML文件中的纯HTML输入 - 那么转换双引号就足够了。

虽然转换其他特殊符号(例如<>等)是一种很好的做法。输入信息将存储在服务器\转移到另一个页面\脚本中,因此您需要检查可能会破坏这些文件的内容。我们说我们有这样的设置:

的index.html:

<form method=post action=getinput.php> <input type="text" name="xss"> <input type="submit"></form>

getinput.php:

echo $_POST['xss'];

输入值;your_deadly_php_script完全打破它(在这种情况下你也可以清理服务器端)

如果这还不够 - 请提供有关您问题的更多信息,请添加更多代码示例。

答案 3 :(得分:3)

我相信这个人指的是跨站点脚本攻击。他们将此标记为php,security和xss

以例如

<input type="text" value=""><script>alert(0)</script><"">

以上代码将执行警告框代码;

<?php $var= "\"><script>alert(0)</script><\""; ?>
<input type="text" value="<?php echo $var ?>">

这也将执行警告框。 要解决这个问题,你需要逃避“,&lt;&gt;,以及更多安全.PHP有一些值得研究的功能,每个都有它们的起伏!

htmlentities() - Convert all applicable characters to HTML entities
htmlspecialchars() - Convert special characters to HTML entities
get_html_translation_table() - Returns the translation table used by  htmlspecialchars and htmlentities
urldecode() - Decodes URL-encoded string

你需要注意的是,你传递的是一个变量,并且有方法可以创建错误,从而导致错误发生。最好的办法是确保数据在发生错误时不以可执行的方式格式化。但是如果它们没有引用你是不对的,但是你现在还有一些方法可以让你发生这种情况。

答案 4 :(得分:0)

$ var = "><script>alert(0);</script>会起作用...如果你可以关闭报价,你可以关闭标签然后打开另一个......但我认为你是对的,没有关闭报价就不能注射...