0

私はjqteを使用して、コンテンツ用にWYSIWYGを作成したcmsのユーザーに提供しています。コンテンツを公開するために htmlPurifier を使用しているので、編集者がサイトの訪問者に害を及ぼすことはありません。

ただし、配置することはできます

<button onclick="alert('this sux')">klick me</button>

テキストエリアで、次のユーザーが機能するボタンを見つけます。

<script>evilcode</script>

さえ実行されます。

誰かが私の前にこれを扱ったことがありますか?ここでエレガントな解決策のヒントを教えてもらえますか?

4

2 に答える 2

1

私はここで手足を出して、以前に送信さhtmlspecialchars()たデータをフォームにロードしたときに出力がない言います. テキストは WYSIWYG によって HTML として解釈されていますが、実際の HTML と混同しないでください。:)

慰めとして、この混乱は非常に一般的であり (それは起こり続けてい ます)、あなたが説明したものとまったく同じ問題を抱えている人が非常に多いことを知っておいてください.

ワークフローと、どこで問題が発生した可能性があるかを見てみましょう。

問題のワークフロー

<tag>WYSIWYG がロードされた WYSIWYG フィールド内のリッチテキストに誰かが書き込むと、エディタは、誰かが HTML&lt;tag&gt;をメッセージに挿入しようとしていることに気付きます。

誰かが太字のテキストをリッチテキストに書き込むと、エディターは誰かが HTML <b>bold text</b>(または同等のもの) をメッセージに挿入しようとしていることに気付きます。

一方、バックグラウンドでは、テキスト(または何でも) がtextarea&lt;tag&gt; <b>bold text</b>に格納されています。テキストを HTML コンテキスト内のテキストとして保持するために、HTML エンコーディングでエンコードされ、目に見えないように.&amp;lt;tag&amp;gt; &lt;b&gt;bold text&lt;/b&gt;

ただし、送信ボタンが押されると、テキストエリアのテキスト ( &lt;tag&gt; <b>bold text</b>) がサーバーに送信されます。フォーム データ自体はもちろん HTML エンコードされていないため (HTML に埋め込まれていないため)、キーと値のセットに過ぎません。 、そしてテキストエリアの値が必要でした。

ここで、サーバー側アプリケーションで HTML を作成して、さらに編集するためにメッセージを再度読み込む場合、フィールドのを HTML でエンコードする必要があります。これは、その値を HTML コンテキストに入れるためです。以前に行っていたのは<textarea>&lt;tag&gt; <b>bold text</b></textarea>、HTML を HTML コンテキストに入れる の作成です。基本的にすべてのブラウザで、これにより textarea がvalue <tag> <b>bold text</b>を取得します。痛い!(誰かが</textarea>生のメッセージの一部として持っていると想像してみてください!)

残念なことに、WYSIWYG エディターは、残念ながら、ユーザーが求めていたものをほぼ表示するのが得意です。ほとんどのユースケースでは、違いに気付くことさえないため、このエラーが非常に広まっています。

ただし、ページの HTML を作成するときは、実際には<textarea>&amp;lt;tag&amp;gt; &lt;b&gt;bold text&lt;/b&gt;</textarea>. これにより、テキストエリアが &lt;tag&gt; <b>bold text</b>を取得します-それはまさにあなたが望んでいたことです.

現在のソリューションと、それが壊れた理由

あなたが現在持っているソリューションは、送信されたテキストを 経由で実行しhtmlspecialchars_decode()、それが に変わり、それによって HTML Purifier がそれを排除できるようにします。WYSIWYG のコンテキストで解釈されることを心配する必要はもうありません。&lt;tag&gt;<tag>&lt;tag&gt;<tag>

ただし、残念ながら次の 2 つの問題があります。

1)タグに関するメッセージは、 HTML Purifierによって削除されなければ送信できなくなりました。テキストエリアのユースケースによっては、これは問題にならない場合があります。おそらく、人々が次のような HTML メッセージを送信できるようにしたくないでしょうIf you're making your own website, you can use &lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js" language="javascript"&gt; instead of hosting the jquery.js yourself。現在のソリューションでは、そのようなメッセージはIf you're making your own website, you can use instead of hosting the jquery.js yourselfHTML Purifier によってサニタイズされます。

2) さらに危険なことに、人々はあなたをハッキングすることができます! エディターにテキスト を書き込んで&lt;script&gt;alert(1);&lt;/script&gt;(エディターは、送信したいHTML&amp;lt;script&amp;gt;alert(1);&amp;lt;/script&amp;gt;を として認識します)、送信をクリックしてみてください。あなたのソリューションはこれを に変換し&lt;script&gt;alert(1);&lt;/script&gt;、それを に入れます<textarea>が、残念ながら振り出しに戻ります。

実際のソリューション

ソリューションを削除してhtmlspecialchars_decode()(ただし、浄化を続けてください!)、代わりにhtmlspecialchars()出力を配置します。WYSIWYG は引き続き機能し、HTML Purifier のサニテーションをバイパスすることはもうありません。

于 2016-01-23T11:32:08.793 に答える
0

jqte はタグをマスクするので、

<

になる

&lt;

HTMLpurifier では見逃されます。したがって、浄化する前に、すべての html マスキングをデコードする必要があります。あなたはそれを行うことができます

htmlspecialchars_decode($string, ENT_HTML5);

これは、htmlpurifier をインストールしている (つまり composer を使用している) 場合に、文字列または配列をスローできる完全なクラスです。

class cleanWysiwyg
{
    private $allowTags = array('b','i','u');
    private $purifier;

    public function __construct()
    {
          $config = HTMLPurifier_Config::createDefault();
          $config->set('HTML.AllowedElements', $this->allowTags );
          $this->purifier = new HTMLPurifier($config);
    }

      public function cleanup ( &$dirty )
      {

        if ( !is_array($dirty) )
          {
        /*do this to prevent some clever workarounds enabled by wysiwyg or bored coders*/
        $dirty = htmlspecialchars_decode($dirty, ENT_HTML5); 
            $dirty = $this->purifier->purify( $dirty );
            return;
          }
          /*if we have an array we call ourselfes for each element*/
        foreach ( $dirty as &$element ){
          $this->cleanup($element);
        }
      }
}

応急処置として機能しますが、それでもハッキング可能です。解決策としてマークされた回答を参照してください。この回答は、ソリューションの有用なコンテキストとして簡単にするためにここに残されています。

于 2016-01-15T20:26:57.787 に答える