Skip to content

Commit 29400a3

Browse files
Merge pull request #910 from shimos/ja-translate-labs-xss
Add Japanese translation for labs/ja_xss
2 parents 9995036 + 53cf52d commit 29400a3

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

docs/labs/ja_xss.html

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
<!DOCTYPE html>
2+
<html lang="ja">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<link rel="stylesheet" href="https://best.openssf.org/assets/css/style.css">
8+
<link rel="stylesheet" href="checker.css">
9+
<script src="checker.js"></script>
10+
<script src="xss.js"></script>
11+
<link rel="license" href="https://creativecommons.org/licenses/by/4.0/">
12+
13+
<!-- See create_labs.md for how to create your own lab! -->
14+
15+
</head>
16+
<body>
17+
<!-- For GitHub Pages formatting: -->
18+
<div class="container-lg px-3 my-5 markdown-body">
19+
<h1>ラボ演習 xss</h1>
20+
<p>
21+
これはセキュアなソフトウェア開発に関するラボ演習です。
22+
ラボの詳細については、<a href="ja_introduction.html" target="_blank">概要</a>をご覧ください。
23+
24+
<p>
25+
<h2>タスク</h2>
26+
<p>
27+
<b>FlaskとテンプレートエンジンのJinja2を用いてクロスサイトスクリプティング(XSS)への対策を練習しましょう。</b>
28+
29+
<p>
30+
<h2>背景</h2>
31+
<p>
32+
この演習では、<a href="https://github.com/ossf/secure-sw-dev-fundamentals/blob/main/secure_software_development_fundamentals.md#countering-cross-site-scripting-xss">コースで述べたように(訳注: リンク先は英語版)</a>、クロスサイトスクリプティング(XSS)攻撃に対する広範な対策となる仕組みを実装します。
33+
ここでは、「XSS対策の標準的な方法は、攻撃者のものである可能性があり、特に承認されていないすべての出力をエスケープすることです。(中略) ほとんどの場合、XSSに対する最善の解決策は、HTML出力を自動的にエスケープしてくれるフレームワークやライブラリーを選択することです。」と述べました。
34+
すなわち、エスケープしないように指定しない限り、"&lt;"のような文字を"&amp;lt;"に変換するように、自動的にエスケープしてくれるシステムを用いるのがよいということです。
35+
このようにして、特殊な文字が無害な形で出力されます。
36+
<p>
37+
<i>理論的には</i>、出力を生成する際に、毎回エスケープルーチンを呼び出すこともできます。<i>現実的には</i>このアプローチは安全ではありません。
38+
いつかは開発者が誤って、出力を生成する際にエスケープルーチンを呼ぶことを忘れてしまうことがあるでしょう。
39+
エスケープを<i>デフォルトで</i>実行してくれる仕組みを用いるほうがはるかに安全です。
40+
<p>
41+
<a href="https://pypi.org/project/Flask/"
42+
>Flask</a>はPythonプログラミング言語向けのサーバーサイドのWebアプリケーションの軽量フレームワークです。
43+
Flaskを用いるプログラムでは、<a href="https://flask.palletsprojects.com/en/3.0.x/quickstart/#rendering-templates">Jinja2テンプレートエンジン</a>もよく使われています。
44+
<a href="https://jinja.palletsprojects.com/en/3.1.x/api/#autoescaping">Jinja2は、HTMLを自動的にエスケープする仕組みを持っています。</a>
45+
<p>
46+
Jinja2のバージョン3.1.xシリーズは、この「自動エスケープ」モードをデフォルトでは有効にして<i>いません</i>
47+
これは、Jinjaの将来のバージョンでは変わるかもしれませんが、いずれにしても、これは良い例といえるでしょう。
48+
つまり、ライブラリによっては、危険ではない使い方をするために特殊な設定を行わなければならないことがあるということです。
49+
これは理想的ではありませんが、そのようなライブラリであっても使うことはできます。
50+
ライブラリを安全に使うために、<i>正しく</i>設定することをしっかりと確かめる必要があるというだけです。
51+
<p>
52+
<a href="https://flask.palletsprojects.com/en/3.0.x/quickstart/#rendering-templates"
53+
>Flaskはデフォルトで自動的にHTMLをエスケープするようにJinja2を設定します。</a>.
54+
そのため、<i>Flask</i>のユーザーに関していえば、Jinjaテンプレートシステムは、デフォルトでHTMLを自動的にエスケープ<i>します</i>
55+
56+
<p>
57+
<h2>タスクの詳細</h2>
58+
<p>
59+
下記のコードを変更してXSS脆弱性の対策を行ってください。必要に応じて「ヒント」や「諦める」のボタンを押してください。
60+
このタスクは複数のパートから構成されています。各パートの指示はそれぞれの部分に分かれて書かれています。
61+
62+
<p>
63+
<h2>演習 (<span id="grade"></span>)</h2>
64+
65+
<h3>パート1</h3>
66+
<p>
67+
このパートでは、Flaskは<i>使いません</i>
68+
その代わり、PythonとJinja2テンプレートエンジンを直接使います。
69+
今回対象とするバージョンのJinja2は、<a href="https://jinja.palletsprojects.com/en/3.1.x/api/#basics">そのように設定しない限り、自動的にエスケープを行い<i>ません</i></a>
70+
Jinja2の設定を変更してHTMLを自動的にエスケープするようにしてください。これには、<tt>autoescape</tt>というフィールドに<tt>select_autoscape()</tt>を値として設定することで行います。
71+
72+
<!--
73+
You can use this an example for new labs.
74+
For multi-line inputs, instead of <input id="attempt0" type="text" ...>, use
75+
<textarea id="attempt" rows="2" cols="65">...</textarea>
76+
-->
77+
<form id="lab1"><pre><code
78+
>from jinja2 import Environment, PackageLoader, select_autoescape
79+
env = Environment(
80+
loader=PackageLoader("yourapp"),
81+
<input id="attempt0" type="text" size="60" spellcheck="false" value="">
82+
)
83+
</code></pre>
84+
<button type="button" class="hintButton">ヒント</button>
85+
<button type="button" class="resetButton">リセット</button>
86+
<button type="button" class="giveUpButton">諦める</button>
87+
</form>
88+
89+
<h3>パート2</h3>
90+
<p>
91+
このパートでは、Flaskを<i>使います</i>
92+
FlaskはJinja2をHTMLを自動的にエスケープするように設定します。
93+
下記のコード(<a href="https://flask.palletsprojects.com/en/3.0.x/quickstart/#rendering-templates"
94+
>Flask quickstart</a>を元にしています)は、Jinja2を中で呼び出すFlaskのテンプレートレンダリングシステムを用いて、結果を出力しています。
95+
</p>
96+
97+
<pre><code
98+
>from flask import render_template
99+
@app.route('/hello/')
100+
@app.route('/hello/<name>')
101+
def hello(name=None):
102+
return render_template('hello.html', person=name)</code></pre>
103+
104+
<p>
105+
上のサンプルコードは、下記に示す<tt>hello.html</tt>というテンプレートを用いています。
106+
テンプレートで<tt>{{ ... }}</tt>で囲まれている部分には、値が代入されることに注意してください。
107+
<p>
108+
残念なことに、下記のテンプレートには脆弱性があります。
109+
"| safe"というマークは、テンプレートシステムに対して、そのデータが安全でありエスケープするべきではないと指示するものです。
110+
しかし、上記のコードで示した通り、人物の名前(name)は、信頼できないユーザーから得たものです。
111+
したがって、(他のほとんどのデータと同様に)名前は安全では<i>ありません</i>
112+
このままでは、攻撃者は"&lt;"といった文字を名前に忍び込ませて、他社への攻撃の手段として使うことが可能です。
113+
この脆弱性を修正してください。
114+
115+
<!--
116+
You can use this an example for new labs.
117+
For multi-line inputs, instead of <input id="attempt0" type="text" ...>, use
118+
<textarea id="attempt" rows="2" cols="65">...</textarea>
119+
-->
120+
<form id="lab2">
121+
<pre><code
122+
>&lt;!doctype html&gt;
123+
&lt;title&gt;Hello from Flask&lt;/title&gt;
124+
{% if person %}
125+
<input id="attempt1" type="text" size="50" spellcheck="false"
126+
value=" &lt;h1&gt;Hello {{ person | safe }}!&lt;/h1&gt;">
127+
{% endif %}
128+
</code></pre>
129+
<button type="button" class="hintButton">ヒント</button>
130+
<button type="button" class="resetButton">リセット</button>
131+
<button type="button" class="giveUpButton">諦める</button>
132+
</form>
133+
134+
135+
<h3>パート3</h3>
136+
<p>
137+
このパートでも、Flaskを使い続けます。
138+
しかし、何をエスケープして何をエスケープしないかについて、より洗練されたコントロールが必要な場合があります。
139+
ほとんどのWebアプリケーションフレームワークには、HTMLの値を記録する型やクラスがあり、それによってどれをエスケープするかしないかを指定することができます。
140+
通常、Flaskでは<a href="https://flask.palletsprojects.com/en/3.0.x/templating/#controlling-autoescaping">Markup</a>クラスを用います。
141+
<p>
142+
<tt>Markup</tt>クラスのインスタンスは、<tt>Markup</tt>を呼ぶことによって作られます。
143+
最初にコンストラクタで与えられた文字列は安全であるとみなされ、エスケープ<i>されません</i>
144+
Markupクラスの値に対して通常の文字列を連結することができますが、その追加された部分はエスケープ<i>されます</i>
145+
<a href="https://tedboy.github.io/flask/generated/generated/flask.Markup.html"
146+
>例えば</a><tt>Markup("&lt;em&gt;Hello&lt;/em&gt; ") + "&lt;foo&gt;"</tt>という計算では、
147+
<tt>'&lt;em&gt;Hello&lt;/em&gt; &amp;lt;foo&amp;gt;'</tt>というUnicode文字列をもつMarkupインスタンスが作成されます。
148+
このように、最初の部分はエスケープされておらず、後の部分はエスケープ<i>されている</i>ことに注意してください。
149+
Markupインスタンスを空文字列から作成することもでき、その場合、連結した文字列は全てエスケープされます。
150+
文字列のMarkupインスタンスに対する連結はデフォルトでエスケープされるため、デフォルトが安全な(エスケープ)操作になります。
151+
コードにおいても、何が安全で何が安全でないかを明確に示されることになります。
152+
ここでは説明しませんが、Markupクラスは、何をスケープするかのコントロールを単純化するメソッドを他にも持っています。
153+
テンプレートシステムは、Markupインスタンスをさらなるエスケープなしで直接使います。これは、エスケープすべきものは既にMarkupインスタンスがエスケープしているからです。
154+
<p>
155+
下記のPythonコードは、<tt>name</tt>を含む形で<tt>Markup</tt>を使おうとしています。
156+
しかし、これは間違いで安全ではありません。
157+
問題は、<tt>name</tt>が信頼されていない値であり、<tt>Markup</tt>に対して、信頼された値の一部として直接渡すべきではないことです。
158+
下記のコードを変更して、<tt>result</tt>には、<i>エスケープされた</i><tt>name</tt>が入るように変更してください。
159+
Pythonにおいて<tt>+</tt>は文字列連結の演算であることに注意してください。
160+
161+
<!--
162+
You can use this an example for new labs.
163+
For multi-line inputs, instead of <input id="attempt0" type="text" ...>, use
164+
<textarea id="attempt" rows="2" cols="65">...</textarea>
165+
-->
166+
<form id="lab3">
167+
<pre><code
168+
><input id="attempt2" type="text" size="60" spellcheck="false"
169+
value=" result = Markup('Original name=' + name)">
170+
</code></pre>
171+
<button type="button" class="hintButton">ヒント</button>
172+
<button type="button" class="resetButton">リセット</button>
173+
<button type="button" class="giveUpButton">諦める</button>
174+
</form>
175+
176+
<p>
177+
<i>このラボは、<a href="https://www.linuxfoundation.org/">Linux Foundation</a>のDavid A. Wheelerによって開発されました。</i>
178+
<br><br>
179+
<p id="correctStamp" class="small">
180+
<textarea id="debugData" class="displayNone" rows="20" cols="65" readonly>
181+
</textarea>
182+
</form>
183+
</div><!-- End GitHub pages formatting -->
184+
</body>
185+
</html>

docs/labs/xss.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,23 @@ info =
77
{
88
present: "(Autoescape|AUTOESCAPE)",
99
text: "The name `autoescape` must be in all lowercase.",
10+
text_ja: "`autoescape`という名前は全て小文字でなければなりません。",
1011
examples: [
1112
[ "Autoescape" ],
1213
],
1314
},
1415
{
1516
present: "([Aa]uto_[Ee]scape|AUTO_ESCAPE)",
1617
text: "Use `autoescape` in all lowercase with no underscores.",
18+
text_ja: "`autoescape`は、アンダースコアなしで全て小文字で書いてください。",
1719
examples: [
1820
[ "auto_escape" ],
1921
],
2022
},
2123
{
2224
absent: "autoescape",
2325
text: "Add an `autoescape=` parameter.",
26+
text_ja: "`autoescape=`というパラメータを追加してください。",
2427
examples: [
2528
[ "" ],
2629
],
@@ -29,6 +32,7 @@ info =
2932
present: 'autoescape',
3033
absent: String.raw`autoescape\x20*=`,
3134
text: "The name `autoescape` needs to be followed by `=`.",
35+
text_ja: "`=`が`autoescape`の後に必要です。",
3236
examples: [
3337
[ "autoescape" ],
3438
],
@@ -37,6 +41,7 @@ info =
3741
present: String.raw`\| safe`,
3842
index: 1,
3943
text: "The text `| safe` indicates that this text is trusted and should not be escaped further. However, in context this data could be provided from an attacker and is NOT safe. Remove the marking.",
44+
text_ja: "`| safe`は、このテキストが信頼できエスケープするべきではないことを表します。しかし、ここではこのデータは攻撃者によって与えられる可能性があり安全ではありません。このマークを消してください。",
4045
examples: [
4146
[ null, " <h1>Hello {{ person | safe }}!</h1>" ],
4247
],
@@ -45,6 +50,7 @@ info =
4550
present: String.raw`\|`,
4651
index: 1,
4752
text: "The `|` is used to separate the computed value from the safe marking, but we will not use that marking. Remove the vertical bar.",
53+
text_ja: "`|`は、計算される値とsafeのマークを区切るために使われていましたが、ここでは必要ありません。縦棒(|)を消してください。",
4854
examples: [
4955
[ null, " <h1>Hello {{ person | }}!</h1>" ],
5056
],
@@ -53,6 +59,7 @@ info =
5359
present: String.raw`Markup \(.*\+.*\)`,
5460
index: 2,
5561
text: "Having a concatenation (+) *inside* the call to Markup is a vulnerability. The call to Markup presumes we are passing text that is *not* supposed be escaped. If it is supposed to be escaped, it should be concatenated outside the initial construction of the Markup object.",
62+
text_ja: "Markupの呼び出しの*中に*連結(+)があることが脆弱性です。Markupの呼び出しは、渡したテキストがエスケープされる*べきでない*とみなします。エスケープされるべきものであれば、Markupオブジェクトの初期コントラクタの外で連結しなければなりません。",
5663
examples: [
5764
[ null, null, " result = Markup('Original name=' + name)" ],
5865
],
@@ -61,6 +68,7 @@ info =
6168
absent: String.raw`\+`,
6269
index: 2,
6370
text: "Our expected answer includes concatentation using `+`. We expect something like `Markup('Original name='` followed by `+` followed by the variable containing the data that needs to be escaped.",
71+
text_ja: "想定解は`+`を用いた連結です。`Markup('Original name=')`に続けて`+`、さらにエスケープされるべきデータが入っている変数が続く、というものを想定しています。",
6472
examples: [
6573
[ null, null, ' result = Markup(f"Original name={name}' ],
6674
],

0 commit comments

Comments
 (0)