4

ユーザープロファイル用に多くのユーザーが送信した html を許可したいのですが、現在、不要なものを除外しようとしていますが、ホワイトリストアプローチを変更して使用したいと考えています。

これが私の現在の非ホワイトリストアプローチです

function FilterHTML($string) {
    if (get_magic_quotes_gpc()) {
        $string = stripslashes($string);
    }
    $string = html_entity_decode($string, ENT_QUOTES, "ISO-8859-1");
    // convert decimal
    $string = preg_replace('/&#(\d+)/me', "chr(\\1)", $string); // decimal notation
    // convert hex
    $string = preg_replace('/&#x([a-f0-9]+)/mei', "chr(0x\\1)", $string); // hex notation
    //$string = html_entity_decode($string, ENT_COMPAT, "UTF-8");
    $string = preg_replace('#(&\#*\w+)[\x00-\x20]+;#U', "$1;", $string);
    $string = preg_replace('#(<[^>]+[\s\r\n\"\'])(on|xmlns)[^>]*>#iU', "$1>", $string);
    //$string = preg_replace('#(&\#x*)([0-9A-F]+);*#iu', "$1$2;", $string); //bad line
    $string = preg_replace('#/*\*()[^>]*\*/#i', "", $string); // REMOVE /**/
    $string = preg_replace('#([a-z]*)[\x00-\x20]*([\`\'\"]*)[\\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iU', '...', $string); //JAVASCRIPT
    $string = preg_replace('#([a-z]*)([\'\"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iU', '...', $string); //VBSCRIPT
    $string = preg_replace('#([a-z]*)[\x00-\x20]*([\\\]*)[\\x00-\x20]*@([\\\]*)[\x00-\x20]*i([\\\]*)[\x00-\x20]*m([\\\]*)[\x00-\x20]*p([\\\]*)[\x00-\x20]*o([\\\]*)[\x00-\x20]*r([\\\]*)[\x00-\x20]*t#iU', '...', $string); //@IMPORT
    $string = preg_replace('#([a-z]*)[\x00-\x20]*e[\x00-\x20]*x[\x00-\x20]*p[\x00-\x20]*r[\x00-\x20]*e[\x00-\x20]*s[\x00-\x20]*s[\x00-\x20]*i[\x00-\x20]*o[\x00-\x20]*n#iU', '...', $string); //EXPRESSION
    $string = preg_replace('#</*\w+:\w[^>]*>#i', "", $string);
    $string = preg_replace('#</?t(able|r|d)(\s[^>]*)?>#i', '', $string); // strip out tables
    $string = preg_replace('/(potspace|pot space|rateuser|marquee)/i', '...', $string); // filter some words
    //$string = str_replace('left:0px; top: 0px;','',$string);
    do {
        $oldstring = $string;
        //bgsound|
        $string = preg_replace('#</*(applet|meta|xml|blink|link|script|iframe|frame|frameset|ilayer|layer|title|base|body|xml|AllowScriptAccess|big)[^>]*>#i', "...", $string);
    } while ($oldstring != $string);
    return addslashes($string);
}

上記はかなりうまく機能します.2年間使用しても問題はありませんでしたが、ホワイトリストのアプローチでは、stackoverflows C#メソッドに似たものはPHPにありますか? http://refactormycode.com/codes/333-sanitize-html

4

7 に答える 7

14

HTML Purifierは、PHP で書かれた標準準拠の HTML フィルター ライブラリです。HTML Purifier は、完全に監査された、安全でありながら寛大なホワイトリストを使用してすべての悪意のあるコード (XSS として知られている) を削除するだけでなく、ドキュメントが標準に準拠していることを確認します。

于 2009-09-04T01:52:22.693 に答える
8

DOMDocumentを使用して正しく分析し、許可されていないタグを removeChild() で削除してから結果を取得する方が安全かもしれません。特に物事が複雑になり始めた場合、正規表現で物事をフィルタリングすることは常に安全であるとは限りません。ハッカーはフィルターをごまかす方法を見つけることができますが、フォーラムやソーシャル ネットワークはそれをよく知っています。

たとえば、ブラウザーは < の後のスペースを無視します。あなたの正規表現フィルター <スクリプト、しかし < スクリプトを使用すると...大きな失敗!

于 2009-09-04T01:47:16.343 に答える
3

HTML Purifierは、最高の HTML パーサー/クリーナーです。

于 2009-09-04T01:49:55.220 に答える
0

以下のこの関数「getCleanHTML」を試して、ホワイトリストにタグ名を持つ要素を除いて、要素からテキスト コンテンツを抽出します。このコードはクリーンで理解しやすく、デバッグも簡単です。

<?php

$TagWhiteList = array(
    'b', 'i', 'u', 'strong', 'em', 'a', 'img'
);

function getHTMLCode($Node) {
    $Document = new DOMDocument();    
    $Document->appendChild($Document->importNode($Node, true));
    return $Document->saveHTML();
}
function getCleanHTML($Node, $Text = "") {
    global $TagWhiteList;

    $TextName = $Node->tagName;
    if ($TextName == null)
        return $Text.$Node->textContent;

    if (in_array($TextName, $TagWhiteList)) 
        return $Text.getHTMLCode($Node);

    $Node = $Node->firstChild;
    if ($Node != null)
        $Text = getCleanHTML($Node, $Text);

    while($Node->nextSibling != null) {
        $Text = getCleanHTML($Node->nextSibling, $Text);
        $Node = $Node->nextSibling;
    }
    return $Text;
}

$Doc = new DOMDocument();
$Doc->loadHTMLFile("Test.html");
echo getCleanHTML($Doc->documentElement)."\n";

?>

お役に立てれば。

于 2009-09-04T03:38:32.113 に答える
0

strip_tags () 関数を使用できます

関数は次のように定義されているため、

string strip_tags  ( string $str  [, string $allowable_tags  ] )

あなたはこれを行うことができます:

$html = $_POST['content'];
$html = strip_tags($html, '<b><a><i><u><span>');

ただし、strip_tags を使用すると、属性を除外できないことに注意してください。例えば

<a href="javascript:alert('haha caught cha!');">link</a>
于 2009-09-04T03:25:36.933 に答える
-1

実際に達成するのは非常に簡単な目的です。ホワイトリストに登録されたタグのリストから一部のタグではないものを確認し、ソースから削除するだけです。1 つの正規表現で非常に簡単に実行できます。

function sanitize($html) {
  $whitelist = array(
    'b', 'i', 'u', 'strong', 'em', 'a'
  );

  return preg_replace("/<(^".implode("|", $whitelist).")(.*)>(.*)<\/(^".implode("|", $whitelist).")>/", "", $html);
}

私はこれをテストしていません。おそらくどこかにエラーがありますが、それがどのように機能するかの要点はわかります。また、Textile や Markdown などの書式設定言語を使用することも検討してください。

ジェイミー

于 2009-09-04T01:48:36.033 に答える