5

信頼できないユーザーからの HTML を受け入れてサニタイズし、Web サイトのページに安全に含めることができるようにしたいと考えています。これは、マークアップを削除したりエスケープしたりしてはならず、 や などの危険なタグ、 などの危険な属性、<script>または背景 URL などの危険な CSS プロパティが含まれていない限り、本質的に変更されずに通過する必要があることを意味します。(どうやら一部の古い IE は CSS で JavaScript URL を実行しますか?)<iframe>onload

iframe に囲まれた別のドメインからコンテンツを提供することは、適切なオプションではありません。なぜなら、iframe の高さを事前に知る方法がないため、一部のページでは見苦しくなるからです。

HTML Purifier を調べてみたのですが、まだ HTML5 に対応していないようです。Google Cajaも調べましたが、スクリプトを使わない解決策を探しています。

これを実現するライブラリを知っている人はいますか? PHP が好まれますが、物乞いは選ぶことができません。

4

7 に答える 7

6

ブラック リストのアプローチでは、アップグレードのプレッシャーがかかります。したがって、ブラウザーが新しい標準のサポートを開始するたびに、サニタイズ ツールを同じレベルに引き上げる必要があります。このような変化は、あなたが思っているよりも頻繁に起こります。

原因のホワイトリスト (明確に定義された例外を含む strip_tags によって達成される) は、ユーザーのオプションを縮小しますが、サイトを保存します。

私自身のサイトでは、非常に信頼できるユーザー (管理者など) のページにブラック リストを適用し、他のすべてのページにホワイトリストを適用するポリシーを持っています。そのため、私はブラックリストにあまり力を入れない立場に置かれています。より成熟した役割と権限の概念により、ブラック リストとホワイト リストを細かく設定することもできます。


更新:これを探していると思います:

strip_tags はタグ レベルでホワイトリストに登録しますが、属性レベルではすべてを受け入れます。興味深いことに、HTMLpurifier は属性レベルでホワイトリスト登録を行っているようです。ありがとう、ここでいい勉強になりました。

于 2014-07-04T12:40:17.413 に答える
2

次の行に沿って何かを実行できる場合があります。

preg_replace('/<\s*iframe\s+[^>]*>.*<\s*\/\s*iframe\s+[^>]*>/i', '', $html);
preg_replace('/<\s*script\s+[^>]*>.*<\s*\/\s*script\s+[^>]*>/i', '', $html);
preg_replace('/\s+onload\s+=\s+"[^"]+"/i', '', $html);

...しかし、もう一度: RegExes がありますが、2 つの問題があります。これにより、必要以上に削除され、必要以上に残る可能性があります。

しかし、HTML Purifier はおそらく最も現代的で適切な (そしてオープン ソースの) プロジェクトであるため、それでもそれを使用し、本当に必要な場合は調整を加える必要があります。

次のいずれかをチェックアウトすることもできます。

  • kses - 事実上の標準であり、ワードプレスにも道を見出しました
  • htmLawed - さらに開発された kses
  • PHP 入力フィルター- タグと属性をフィルタリングできます

ただし、閉じられていないタグが原因で結果を含める際に、独自のページ レイアウトが影響を受けないようにする必要もあります。

于 2014-07-02T13:32:04.483 に答える
2

Ruby では、Nokogiri ( php バージョン) を使用して HTML コンテンツを解析しています。ユーザーのデータを解析し、不要なタグや属性を削除してから、テキストに変換できます。

phpQuery - 別のパーサー。

PHP にはstrip_tags関数があります。

または、すべての属性を手動で削除できます。

$dom = new DOMDocument;
$dom -> loadHTML( $html );
$xpath = new DOMXPath( $dom );
$nodes = $xpath -> query( "//*[@style]" ); // all elements with style attribute
foreach ( $nodes as $node ) {
    // remove or do what you want
    $node -> removeAttribute( "style" );
}
echo $dom -> saveHTML();
于 2014-07-07T11:31:31.517 に答える
0

html5lib-python だけを使用することにしました。これは私が思いついたものです:

#!/usr/bin/env python
import sys
from xml.dom.minidom import Node
import html5lib
from html5lib import (HTMLParser, sanitizer, serializer, treebuilders,
                     treewalkers)

parser = HTMLParser(tokenizer=sanitizer.HTMLSanitizer,
                    tree=treebuilders.getTreeBuilder("dom"))
serializer = serializer.htmlserializer.HTMLSerializer(omit_optional_tags=False)

document = parser.parse(sys.stdin.read(), encoding="utf-8")
# find the <html> node
for child in document.childNodes:
    if child.nodeType == Node.ELEMENT_NODE and child.nodeName == 'html':
        htmlNode = child 
# find the <body> node
for child in htmlNode.childNodes:
    if child.nodeType == Node.ELEMENT_NODE and child.nodeName == 'body':
        bodyNode = child
# serialize all children of the <body> node
for child in bodyNode.childNodes:
    stream = treewalkers.getTreeWalker("dom")(child)
    sys.stdout.write(serializer.render(stream, encoding="utf-8"))

入力例:

<script>alert("hax")</script>
<p onload="alert('this is a dangerous attribute')"><b>hello,</b> world</p>

出力例:

&lt;script&gt;alert("hax")&lt;/script&gt;
<p><b>hello,</b> world</p>
于 2014-07-08T21:33:06.560 に答える