質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
エスケープ処理

エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

XSS

XSS【クロスサイトスクリプティング】は、 ソフトウェアのセキュリティホールの一つで、Webサイトに脆弱性が あることからその脆弱性を利用し攻撃する手法です。 主に、入力フォームなどから悪意あるスクリプトを挿入し 該当ページを閲覧したブラウザ上でそのスクリプトを実行します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

1回答

1948閲覧

HTML code内の記述をそのまま表示したい。FlaskのXSS対策HTMLエスケープと両立させたい

Y.NINOMIYA

総合スコア32

エスケープ処理

エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

XSS

XSS【クロスサイトスクリプティング】は、 ソフトウェアのセキュリティホールの一つで、Webサイトに脆弱性が あることからその脆弱性を利用し攻撃する手法です。 主に、入力フォームなどから悪意あるスクリプトを挿入し 該当ページを閲覧したブラウザ上でそのスクリプトを実行します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2020/09/17 08:57

編集2020/09/18 07:16

前提

Flaskを利用した記事投稿プラットフォームを作っています。おおまかなシステムは出来上がりました。
記事はマークダウンで記述することができ、XSS対策として一部のHTMLを使用することができます。使用できないHTMLはPythonでエスケープします。
エスケープ処理は以下のコードで行っています。

Python

1import bleach 2bleach.clean(article.content, tags=["div","br","span","img","code","pre"],attributes={"*":["style"],"img":["src","width","height"]},styles=["color","margin"])

実現したいこと

NoteやQiita、teratailなどと同じようにソースコードの貼り付けを可能にしたい。

現状

<pre><code></code></pre>内にコード(HTML)を記述すると、bleachのホワイトリストに登録したタグはそのまま解釈してしまいます。また、<!DOCTYPE html>などは表示すらされず消えてしまいます。

ブラウザ側のJavaScriptで<pre></pre>内の特殊文字をエスケープしてそのまま表示されるようにしたのですが、ホワイトリスト以外のタグは「&」など、特殊文字コードで表示されてしまいます。

どなたか回答よろしくお願いいたします。

追記

マークダウンで記述するようにしているため、{{content | markdown}} と、フィルターをかけています。
以下のコードのようにJavaScriptで<pre>内をエスケープする処理も考えましたが、bleachで許可していないタグなどは特殊文字で表示されてしまいます。予めエスケープされているので当然といえば当然なのでしょうが....

JavaScript

1 var escapeHtml = (function (String) { 2 var escapeMap = { 3 '&': '&amp;', 4 "'": '&#x27;', 5 '`': '&#x60;', 6 '"': '&quot;', 7 '<': '&lt;', 8 '>': '&gt;' 9 }; 10 var escapeReg = '['; 11 var reg; 12 for (var p in escapeMap) { 13 if (escapeMap.hasOwnProperty(p)) { 14 escapeReg += p; 15 } 16 } 17 escapeReg += ']'; 18 reg = new RegExp(escapeReg, 'g'); 19 return function escapeHtml (str) { 20 str = (str === null || str === undefined) ? '' : '' + str; 21 return str.replace(reg, function (match) { 22 return escapeMap[match]; 23 }); 24 }; 25}(String)); 26 27var pre = document.querySelectorAll('pre'); 28for(var i = 0; i < pre.length; i++) { 29 pre[i].innerHTML = escapeHtml(pre[i].innerHTML); 30}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

やりたいことを誤解しているかもしれませんが、Flaskはrender_template()で値を渡し、マスタッシュ記法内{{}}に記載したものは自動的にエスケープしてくれます。
表示するだけなら、bleachを使わなくてもエスケープしてくれると思うのですが、この動作とやりたいことに乖離があったりしますか?

以下はエスケープされているのを確認できる例です。
app.pyを実行し、表示されたupload3.htmlcode_textにHTMLを入力した場合、エスケープされたHTMLが表示されます。(upload3.htmlのHTMLをそのままペーストし、表示した場合の例:表示.html)
同様にcode_text<script>alert(1);</script>を入力して実行してもalertは表示されません。

python

1# app.py 2from flask import Flask, request, render_template 3 4app = Flask(__name__) 5 6 7@app.route('/upload3', methods=['GET', 'POST']) 8def upload3(): 9 if request.method == 'GET': 10 return render_template('upload3.html') 11 elif request.method == 'POST': 12 code = request.form.get('code_text', None) 13 return render_template('upload3.html', code=code) 14 15 16if __name__ == '__main__': 17 app.run() 18

html

1<!-- upload3.html --> 2<!DOCTYPE html> 3<html lang="ja"> 4<head> 5 <meta charset="UTF-8"> 6 <title>upload</title> 7</head> 8<body> 9 <form method="post" action="{{ url_for('upload3') }}" enctype="multipart/form-data"> 10 <textarea name="code_text" rows="10" cols="50"></textarea><br> 11 <input type="submit" value="分析する"> 12 </form> 13 <pre>{{ code }}</pre> 14</body> 15</html>

html

1<!-- 表示.html --> 2 3 4<!DOCTYPE html> 5<html lang="ja"> 6<head> 7 <meta charset="UTF-8"> 8 <title>upload</title> 9</head> 10<body> 11 <form method="post" action="/upload3" enctype="multipart/form-data"> 12 <textarea name="code_text" rows="10" cols="50"></textarea><br> 13 <input type="submit" value="分析する"> 14 </form> 15 16 <pre>&lt;!DOCTYPE html&gt; 17&lt;html lang=&#34;ja&#34;&gt; 18&lt;head&gt; 19 &lt;meta charset=&#34;UTF-8&#34;&gt; 20 &lt;title&gt;upload&lt;/title&gt; 21&lt;/head&gt; 22&lt;body&gt; 23 &lt;form method=&#34;post&#34; action=&#34;{{ url_for(&#39;upload3&#39;) }}&#34; enctype=&#34;multipart/form-data&#34;&gt; 24 &lt;textarea name=&#34;code_text&#34; rows=&#34;10&#34; cols=&#34;50&#34;&gt;&lt;/textarea&gt;&lt;br&gt; 25 &lt;input type=&#34;submit&#34; value=&#34;分析する&#34;&gt; 26 &lt;/form&gt; 27 &lt;pre&gt;{{ code }}&lt;/pre&gt; 28&lt;/body&gt; 29&lt;/html&gt;</pre> 30 31 32</body> 33</html>

投稿2020/09/18 01:32

FiroProchainezo

総合スコア2401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y.NINOMIYA

2020/09/18 03:36

やりたいことはそのようなことです。 サンプルの動作も確認できました。 ただ、マークダウンで記事を書くため、{{ content | markdown}} などのようにフィルターを通してHTMLに整形して出力しています。そのため、bleachで許可していないタグなどはエスケープするようにしていました。現状、ホワイトリストにあるタグが解釈されてしまうのは当然という状況ではあるのですが.... 解釈されないようにJavaScript側で<pre>内をエスケープする処理なども考えたのですが、ホワイトリスト以外のタグは特殊文字コードで表示されてしまいます。
FiroProchainezo

2020/09/18 03:54

Y.NINOMIYAさんの考えは私にはわかりかねますので、全ての情報を質問に追加いただけませんか? どのような現象が起きていて、その現象が起きるコードはどういったもので、どういう入力をして、どういった出力があり、最終的こうしたいなどを追加お願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問