在生成的数据中检查而不打印 JavaScript?

Checking for and not printing JavaScript in generated data?

提问人:Doug T. 提问时间:10/1/2008 最后编辑:hakreDoug T. 更新时间:11/14/2011 访问量:219

问:

在我的 php Web 应用程序中,假设我想加倍努力,除了去帮派克星和保持对我的输入进行消毒之外,我还想确保我没有 JavaScript 在我插入到 html 模板中的字符串中输出。

有没有一种标准方法可以确保我不会在生成的 html 内容中放入 JavaScript?

PHP JavaScript 安全性

评论


答:

0赞 dlamblin 10/1/2008 #1

不完全是标准方式;因为如果你在做呢: ,并扩展到<img src="${path}">${path}http://p0wned.com/jpg.jpg" /><script src="p0wned.com/js.js"/>

无论如何,我喜欢这个正则表达式:

#from http://www.perlmonks.org/?node_id=161281
sub untag {
  local $_ = $_[0] || $_;
# ALGORITHM:
#   find < ,
#       comment <!-- ... -->,
#       or comment <? ... ?> ,
#       or one of the start tags which require correspond
#           end tag plus all to end tag
#       or if \s or ="
#           then skip to next "
#           else [^>]
#   >
  s{
    <               # open tag
    (?:             # open group (A)
      (!--) |       #   comment (1) or
      (\?) |        #   another comment (2) or
      (?i:          #   open group (B) for /i
        ( TITLE  |  #     one of start tags
          SCRIPT |  #     for which
          APPLET |  #     must be skipped
          OBJECT |  #     all content
          STYLE     #     to correspond
        )           #     end tag (3)
      ) |           #   close group (B), or
      ([!/A-Za-z])  #   one of these chars, remember in (4)
    )               # close group (A)
    (?(4)           # if previous case is (4)
      (?:           #   open group (C)
        (?!         #     and next is not : (D)
          [\s=]     #       \s or "="
          ["`']     #       with open quotes
        )           #     close (D)
        [^>] |      #     and not close tag or
        [\s=]       #     \s or "=" with
        `[^`]*` |   #     something in quotes ` or
        [\s=]       #     \s or "=" with
        '[^']*' |   #     something in quotes ' or
        [\s=]       #     \s or "=" with
        "[^"]*"     #     something in quotes "
      )*            #   repeat (C) 0 or more times
    |               # else (if previous case is not (4))
      .*?           #   minimum of any chars
    )               # end if previous char is (4)
    (?(1)           # if comment (1)
      (?<=--)       #   wait for "--"
    )               # end if comment (1)
    (?(2)           # if another comment (2)
      (?<=\?)       #   wait for "?"
    )               # end if another comment (2)
    (?(3)           # if one of tags-containers (3)
      </            #   wait for end
      (?i:\3)       #   of this tag
      (?:\s[^>]*)?  #   skip junk to ">"
    )               # end if (3)
    >               # tag closed
   }{}gsx;          # STRIP THIS TAG
  return $_ ? $_ : "";
}
2赞 leek 10/1/2008 #2

如果你不反对外部依赖,HTML Purifier 库是大多数 XSS 攻击的一个很好的过滤器。

0赞 Kent Brewster 10/1/2008 #3

在PHP中,我会从strip_tags开始。这样:

$output = strip_tags($input);

如果我想在用户输入中允许某些标签,我会包含它们,如下所示:

$output = strip_tags($input, '<code><em><strong>');
0赞 tduehr 10/2/2008 #4

我认为不可能找到这样的 javascript 代码。

您必须通过某种类型的解释器传递数据才能尝试找到有效的 js 语句。这将是非常占用大量处理器资源,并且可能会产生许多误报,具体取决于文本的性质。

实体转义元字符可能是进一步保护应用程序免受过滤器可能遗漏的攻击的最佳方法。如果 Javascript 作为常规文本加载,则无法运行。