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

無料レッスン

安全な設計の基本原則

このレッスンのあとで: 安全な設計の基本ルールを、自分のプログラムの作りに当てはめて説明できる。

55分のレッスンコマンド3件SQL インジェクションのラボ:弱い検索を攻撃し、クエリを直して確かめる

安全な設計とは何か

セキュア設計(secure design)とは、攻撃されることを前提に、プログラムの作りを先に決めておく考え方です。あとから穴をふさぐより、はじめから穴を小さく作るほうが、安く済みます。

大学の学食の予約アプリを考えます。会計係のアカウントで、メニューも全員の予約も消せるなら、1つの乗っ取りが全部の被害になります。

このレッスンのゴール

メモ

安全な設計の基本ルールを、自分のプログラムの作りに当てはめて説明できる。

今日のキーワード

ことばいみれい
最小権限仕事に要る力だけを渡すことです。
安全側に倒す迷ったときは、断るほうに決めることです。
許可リスト許すものを書き並べた一覧です。["read", "write"]
信頼境界信頼できる所と、できない所の境目です。
攻撃面外から触れる入口の全部です。
多層防御守りを1枚でなく、重ねて置くことです。

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

たった1つのルール

注意

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

渡す力は仕事の分だけにする

ある人やプログラムには、仕事に要る力だけを渡します。これを 最小権限(least privilege)と呼びます。力が小さければ、乗っ取られても被害は小さく済みます。

会計係に冷蔵庫の鍵は要りません。予約を読むだけの画面に、予約を消す力は要りません。

例: 学食アプリの権限

担当必要な力渡してはいけない力
予約の一覧画面予約を読む予約を消す、変える
会計の画面金額を読む、記録するメニューを変える
ログを見る人ログを読むログを消す
アプリが使うデータベース口座自分の表を読み書きする表を作る、消す、他の表に触れる

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

決まりがないときは断る

決まりに書いていない場合は、断ります。これを 安全側に倒す(fail safe)と言います。許すものを並べた一覧が 許可リスト(allow list)です。

逆に、止めるものの一覧だけを作ると、一覧にない新しいものが全部通ってしまいます。

知らない役割は断る

コード: python
# 役割ごとに、許す操作の一覧を持ちます。
ALLOWED = {"guest": ["read"], "staff": ["read", "write"]}

def can_do(role, action):
    if role not in ALLOWED:
        return False  # 知らない役割は断ります。
    return action in ALLOWED[role]

# role や action を変えて、実行します。
print(can_do("staff", "write"))
print(can_do("student", "read"))
print(can_do("guest", "delete"))

境目を越えるデータは必ず検査する

信頼境界(trust boundary)は、信頼できる部分と、できない部分の境目です。境目を越えて入ってくるデータは、必ず検査します。

Web アプリでは、利用者のブラウザとサーバーの間が、いちばん大きな境界です。ブラウザから来た値は、利用者が自由に書き換えられます。

ラボの店を見てみる

ラボには、わざと弱く作った店があります。ラボを起動して、次の3つを実行しましょう。どれも見るだけです。

1つ目は、存在しないページを開きます。2つ目は、店のプログラムが、どの利用者の力で動くかを調べます。3つ目は、エラーを返している行を探します。

存在しないページ

コマンド
curl -s -w "%{http_code}\n" http://app:8000/nowhere

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

店を動かす利用者

コマンド
docker exec app id -u

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

エラーを返す行

コマンド
docker exec app grep -n "database error" /tmp/app/app.py

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

3つの答えを読む

1つ目は、not found と 404 を表示します。知らない場所には、何も教えずに断っています。これは安全側に倒す例です。

2つ目は 65532 を表示します。管理者ではない、力の小さい利用者で動いているので、最小権限の例です。3つ目は、行番号と、エラーをそのまま返す1行を表示します。この行は、安全側ではありません。

よくある間違い

注意

「社内のネットワークから来たデータは安全だ」と考える人がいます。それは違います。中の1台が乗っ取られれば、中から来たデータも攻撃になります。境界を越えて入るデータは、送り主にかかわらず検査します。

このラボとソースについて: SQL インジェクションのラボ:弱い検索を攻撃し、クエリを直して確かめる

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