Markdownライブラリを安全に使用するにはどうすればよいですか?出力をWebページに安全に含めることができるようにするには、何をする必要がありますか?
信頼できないユーザーが(Markdown形式で)コンテンツを入力できるようにします。 Markdownプロセッサを使用してHTMLを生成します。そのHTMLを自分のWebページに含めたいのですが。これが安全で、自発的なXSSの脆弱性ではないことを確認するために何をする必要がありますか?どのような引数を渡す必要がありますか?前処理または後処理は必要ですか?必要に応じて、python-markdownライブラリを使用しています。
推奨される使用法。短い答えは、markdown(untrusted, safe_mode=remove, enable_attributes=False)
を使用することです。
古いバージョンにはセキュリティ上の問題があるため、Markdownライブラリの最新バージョンを使用していることを確認してください。
HTML PurifierなどのHTMLサニタイザーを介して出力を実行することもできます。
根拠。_enable_attributes
_を無効にすることをお勧めします。 Pythonマークダウンライブラリの最新の開発バージョンは、デフォルトで 無効にする_enable_attributes
_を設定すると_safe_mode
_ になりますが、以前のバージョンはそうしませんでした。したがって、_safe_mode
_を設定するだけで Markdownライブラリのほとんどのバージョンでは十分ではありません 。 _safe_mode
_を設定しただけの場合、結果は安全ではありません。
_import markdown
>>> markdown.markdown("{@onclick=alert('hi')}some paragraph", safe_mode=True)
u'<p onclick="alert(\'hi\')">some paragraph</p>'
_
現時点では、修正はgitにのみ存在します。この記事の執筆時点では、_enable_attributes=False
_を明示的に設定しない限り、Python Markdown(2.1.1)の最新リリースバージョンは引き続き脆弱です。したがって、現在Python Markdownを使用している多くのシステムが脆弱である可能性があります。
ドキュメンテーションは、これらの落とし穴についてMarkdownのユーザーに警告するのに適しています。 「_enable_attributes=False
_の使用時に_safe_mode
_を設定することもできます。ドキュメントの新しいバージョンでは、_enable_attributes
_を設定すると、「信頼できないユーザーがJavaScriptをドキュメントに挿入する可能性がある」とのことです。 _enable_attributes
_を設定すると、ユーザーがドキュメントにJavascriptを挿入できるようになるため、Markdownが信頼できないソースからのものである可能性がある場合は、非常に安全ではありません。
疑いがあります。とはいえ、上記で推奨されているように使用しても、結果が安全であるかどうかは100%確実ではありません。開発者は次のようなコメントをしました:
「セーフモード」は、下位互換性のために引き続き使用する名前の選択としては不十分でした(古いコードは新しいバージョンでも動作します)。それが本当に何であるかは、ノーマークアップモードです。言い換えれば、これは未加工のhtmlを許可しない方法であり、実際の安全性を保証するものではありません。
これらの種類のコメントは少し怖いです。
Python Markdownライブラリの以前のバージョンでは、HTMLのサニタイズが少し壊れやすいように見えるため、渡されたフラグに関係なく、Markdownライブラリの以前のバージョンを信頼できるかどうかはわかりません。以下を検討してください。
_>>> markdown.markdown("[Example](javascript://alert%28%22xss%22%29)", safe_mode=True)
u'<p><a href="javascript://alert%28%22xss%22%29">Example</a></p>'
_
Markdownの処理を通じて_javascript:
_スタイルのURLを許可することは、設計上、かなり疑わしい決定のように思えます。これは、XSSのホップ、スキップ、ジャンプの範囲内にあるように感じます。不足しているのは、C++スタイルのコメント(_//
_)から抜け出す方法であり、ゲームオーバーです。例えば:
_>>> markdown.markdown("[Example](javascript://\nalert%28%22xss%22%29)", safe_mode=True)
u'<p><a href="javascript:// alert%28%22xss%22%29">Example</a></p>'
_
どのJavaScriptもそのJavascriptを実行しないことをどの程度確信できますか?わからないけど、あたたかくてぼんやりした気持ちにならない。それが安全であれば、それはただの不運です。
さいわい、Markdownの最新リリースバージョンでは、_enable_attributes=False
_を設定すると、スクリプトのフィルタリングが厳しくなります。ただし、必ず_enable_attributes=False
_を設定してください。そうしないと、Markdownが以前のバージョンで見つかった脆弱なHTMLのサニタイズにフォールバックします。そのスキームのセキュリティには自信がありません。
すべきでないこと。以下は安全ではありません:markdown(escape(untrusted))
。
[clickme](javascript:alert%28%22xss%22%29)
」によって無効にすることができます。一般的に、Markdownへの入力のエスケープは 正しいアプローチではない ;です。適切な方法は、適切な方法でMarkdownを呼び出すことです(さらに保護が必要な場合は、出力にHTMLフィルターを適用することもできます)。Djangoを使用する場合。Djangoを使用する場合、Markdownを使用する安全な方法は次のとおりです。
_{{ untrusted | markdown:"safe" }}
_
Django 1.4 以降、これは安全です。 _"safe"
_引数を渡すと、Djangoは、_safe_mode
_を設定して_enable_attributes
_を無効にする特別なサポートを追加しました。ただし、必ずDjango 1.4以降に更新してください。以前のバージョンでは、 この使用法は安全ではありませんでした 。
Markdownだけでは、任意のHTML/Javascript入力を許可し、単に処理せずに渡すため、出力をサンタイズするのに十分ではありません。
例えば。これは有効なマークダウンです:
_## heading
text
_
しかしこれも:
_## heading
text <script>alert('hello');</script>
_
Markdownの構文でカバーされていないマークアップについては、単にHTML自体を使用します。 MarkdownからHTMLに切り替えることを示すために、前置きや区切りを付ける必要はありません。タグを使用するだけです。
私はpython-markdownを使用して簡単なテストを行ったところ、このように動作するようです。
とは言っても、マークダウン構文で使用される文字セットが限られているため、ユーザーが提供できる文字セットをフィルタリングする方が簡単です(== --- ==)前にマークダウンする(例えばa-zA-Z* #+:/&?=-_()>
のようなもの)が、それを解析/エンコードするコードを混乱させるのに十分であるかもしれない...したがって、マークダウンを使用します。
さらなる研究の結果、私は SOでこの答えを見つけました これはかなり賢明なようです。
次にさらに検索して、_safe_mode
_スイッチ( ここに記載 および ここ )を発見しました。
簡単なテストはかなりうまくいくようですが、さらに調査する価値があるかもしれません...
_>>> import markdown
>>> markdown.markdown("<script>alert('hello');</script> hello <strong>world</strong>")
u"<script>alert('hello');</script>\n\n<p>hello <strong>world</strong></p>"
>>> markdown.markdown("<script>alert('hello');</script> hello <strong>world</strong>", safe_mode=True)
u'<p>[HTML_REMOVED]</p>\n<p>hello [HTML_REMOVED]world[HTML_REMOVED]</p>'
_
Safe_modeの完全なオプションセット ドキュメントページで利用可能 -安全のために_enable_attributes
_をFalse
に設定することについても言及しています。