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

無料レッスン

他人のデータが見える(アクセス制御の不備)

このレッスンのあとで: あるリクエストを許してよかったかどうかを、判断できる。

55分のレッスンコマンド3件OWASP Juice Shop のラボ:自分のコピーで攻撃する脆弱な Web ショップ

申請番号を1つ変えたら

会社の経費精算システムで、自分の申請を開きました。アドレスの末尾は 3041 です。ふと、3042 に変えてみました。

別の同僚の申請が表示されました。名前も、金額も、領収書も見えます。何も壊していません。ただ、そのシステムは「誰の申請か」を確かめていなかったのです。

たった1つのルール

注意

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

このレッスンのゴール

メモ

あるリクエストを許してよかったかどうかを、判断できる。

今日のキーワード

ことばいみれい
認証「あなたは誰か」を確かめることです。パスワード
認可「それをしてよいか」を確かめることです。
ロール権限をまとめた呼び名です。admin
ID1件のデータを指す番号や名前です。申請番号 3041
トークンサインイン済みの印として、ブラウザが送る署名つきの値です。
ステータスコード返事の先頭にある、結果を表す番号です。401

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

サインインと許可は別もの

サイトは2つのことを尋ねます。1つ目は 認証 で、「あなたは誰か」です。2つ目は 認可 で、「それをしてよいか」です。

弱いサイトは、1つ目だけを尋ねて、2つ目を忘れます。社員だと分かったので、頼まれたものは何でも見せてしまいます。他の人のものまで見せてしまいます。

ステータスコードは結果の番号

すべての返事は、ステータスコードで始まります。200 は「どうぞ」です。401 は「あなたが誰か分かりません」です。403 は「誰かは分かりますが、だめです」です。

次の3つの Run は、サインインせずに、ラボの店へ3つのものを頼みます。どれを渡してくれるかを見ましょう。

誰にでも見せるもの

コマンド
curl -s -o /dev/null -w "%{http_code}\n" http://juice-shop:3000/api/Products/1

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

サインイン後のもの

コマンド
curl -s -o /dev/null -w "%{http_code}\n" http://juice-shop:3000/api/Users

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

断るときの返事

コマンド
curl -s http://juice-shop:3000/rest/basket/1 | grep -o "<title>[^<]*</title>"

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

例: 3つの答えを読む

リクエスト番号分かること
/api/Products/1200商品は公開なので、誰でも読める
/api/Users401人の一覧は、誰が頼むかを知ってから出す
/rest/basket/1401かごは個人のもの。まずトークンを求める

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

アドレスの ID は書き換えられる

申請、注文、請求書には番号があります。その番号は、よくアドレスの中にあります。誰でも書き換えられます。

だからサイトは、リクエストのたびに確かめます。このアカウントがその持ち主か、読めるロールを持っているか。推測しにくい番号は、確認の代わりになりません。

例: 短いリクエストの記録

ユーザーロールリクエスト許す?
tanaka一般GET /claims/17 (自分の)許す。持ち主だから
tanaka一般GET /claims/18 (suzuki の)許さない。自分のではない
yamada管理者GET /claims/18許す。管理者は全部読める
suzuki一般GET /admin/users許さない。管理者だけ

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

よくある間違い

注意

「ボタンやリンクを隠せば守れる」と考える人がいます。それは違います。ブラウザは、リンクがなくても、どんなアドレスでも頼めます。確認は、返事を作るサーバー側のコードに置きます。リンクも隠してよいですが、それだけに頼ってはいけません。

サーバーは毎回確かめる

安全な処理は、3つのことを順に行います。誰が頼んだかを調べます。データを読み込みます。持ち主かロールかを確かめて、どちらも合わなければ断ります。

断るときは 403 を返します。確認は、1か所のサーバーのコードに置きます。そうすれば、確認を忘れるページが出ません。

持ち主か管理者かの確認

コード: python
def may_read(user, role, owner):
    if role == "admin":
        return True
    return user == owner

# 名前を変えて実行します。次に、"support" のロールにも読ませてみましょう。
print(may_read("tanaka", "member", "tanaka"))
print(may_read("tanaka", "member", "suzuki"))
print(may_read("yamada", "admin", "suzuki"))

このラボとソースについて: OWASP Juice Shop のラボ:自分のコピーで攻撃する脆弱な Web ショップ

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