クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

入力した文字を実行させない(XSS)

このレッスンのあとで: 打ち込まれた文字を、ページの中で実行させないようにできる。

55分のレッスンコマンド3件DVWA のラボ:Damn Vulnerable Web Application で SQL インジェクションと XSS を練習する

問い合わせ画面で動くプログラム

ある会社の問い合わせフォームに、お客さんの文面が届きます。サポート担当は、管理画面でその一覧を開いて読みます。

ある日、文章ではなく、小さなプログラムが書き込まれました。担当者が一覧を開くと、ブラウザが静かにそれを動かしました。会社は、その文面を一行も書いていません。

たった1つのルール

注意

攻撃してよいのは、自分専用のラボのコピーだけです。このラボは、わざと弱く作ったサイトで、インターネットにはつながっていません。許可のない他人のシステムを攻撃すると、不正アクセス禁止法に触れる犯罪になります。

このレッスンのゴール

メモ

打ち込まれた文字を、ページの中で実行させないようにできる。

今日のキーワード

ことばいみれい
クロスサイトスクリプティング打ち込まれたスクリプトを、ページが動かしてしまう弱点です。XSS
スクリプトブラウザがページの中で動かす、小さなプログラムです。
エスケープ特別な文字を、安全な文字に置き換えることです。< を &lt; にする
反射型リクエストで送った文字が、そのまま返事に出ることです。
格納型サイトが保存し、あとから開く全員に出ることです。
Cookieブラウザが持ち、サイトへ送り返す小さな値です。

学生が入力するセルは、このプレビューでは空白です。

打った文字がページの一部になる

ブラウザは、ページをタグの入った文字として読みます。<b> は太字にします。<script> はプログラムを動かします。

サイトが利用者の文字をそのままページに入れると、ブラウザは、サイトのタグか利用者の文字かを見分けられません。打ち込まれたスクリプトが、サイト自身のものとして動きます。

例: 反射型と格納型

反射型格納型
文字の行き先リクエストから、そのまま返事へサイトの記録に保存され、あとのページへ
被害を受ける人細工したリンクを開いた人そのページをあとで開く全員
例「〇〇を検索しました」と出す検索ページ掲示板や商品のレビュー
格納型が重い理由リンクを送らなくても、多くの人に届く

学生が入力するセルは、このプレビューでは空白です。

ラボのサイトを見てみる

ラボでは、これから試すサイトが動いています。起動して、次の3つを実行しましょう。見るのはサインインページだけです。サインインも、スクリプトの入力もしません。

Cookie が大切です。ページの中で動くスクリプトは、その Cookie を読めます。ただし、Cookie に HttpOnly の印があれば読めません。

サイトは動いているか

コマンド
curl -s -o /dev/null -w "%{http_code}\n" http://dvwa/login.php

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

サイトが出す Cookie

コマンド
curl -s -I http://dvwa/login.php | grep -i "^set-cookie"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

HttpOnly はいくつあるか

コマンド
curl -s -I http://dvwa/login.php | grep -ic httponly

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

3つの答えを読む

1つ目は 200 を表示します。2つ目は2行で、security という Cookie と、セッションを表す PHPSESSID です。3つ目は 0 を表示します。

HttpOnly の付いた Cookie はありません。このサイトで動いたスクリプトは、セッションの Cookie を読めます。XSS からセッションの乗っ取りになることが多いのは、そのためです。

エスケープは文字を文字にする

直し方は、利用者の文字がページに入るときに エスケープ することです。< を &lt; に、> を &gt; に置き換えます。ブラウザは同じ文字として表示しますが、タグとしては読みません。

& は、最初に置き換えます。最後にすると、&lt; の中の & まで &amp; になって、表示が崩れます。

エスケープする関数

コード: python
def escape(text):
    text = text.replace("&", "&amp;")
    text = text.replace("<", "&lt;")
    text = text.replace(">", "&gt;")
    return text

# note を変えて実行します。次に、& の行を最後に移して、もう一度実行します。
note = "おいしいパン <b>と</b> ケーキ & お茶"
print("<p>" + escape(note) + "</p>")

よくある間違い

注意

「保存するときに script という語を止めれば十分だ」と考える人がいます。それは違います。img のようなタグもスクリプトを運びますし、書き方を変えればすり抜けます。ページに書き出すその場所で、すべての値をエスケープします。

出力でエスケープし、層を重ねる

エスケープは、保存するときではなく、ページに書き出すときに行います。同じ文字が、あとでページにもメールにもファイルにも使われるからです。それぞれに合った方法があります。

後ろにも守りを重ねます。セッションの Cookie に HttpOnly を付けます。動かせるスクリプトを絞る Content-Security-Policy ヘッダーを送ります。1か所を見落としても、被害が小さくなります。

このラボとソースについて: DVWA のラボ:Damn Vulnerable Web Application で SQL インジェクションと XSS を練習する

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。