安全な設計とは何か
セキュア設計(secure design)とは、攻撃されることを前提に、プログラムの作りを先に決めておく考え方です。あとから穴をふさぐより、はじめから穴を小さく作るほうが、安く済みます。
大学の学食の予約アプリを考えます。会計係のアカウントで、メニューも全員の予約も消せるなら、1つの乗っ取りが全部の被害になります。
このレッスンのゴール
メモ
安全な設計の基本ルールを、自分のプログラムの作りに当てはめて説明できる。
今日のキーワード
| ことば | いみ | れい |
|---|---|---|
| 最小権限 | 仕事に要る力だけを渡すことです。 | |
| 安全側に倒す | 迷ったときは、断るほうに決めることです。 | |
| 許可リスト | 許すものを書き並べた一覧です。 | ["read", "write"] |
| 信頼境界 | 信頼できる所と、できない所の境目です。 | |
| 攻撃面 | 外から触れる入口の全部です。 | |
| 多層防御 | 守りを1枚でなく、重ねて置くことです。 |
学生が入力するセルは、このプレビューでは空白です。
たった1つのルール
注意
試してよいのは、自分専用のラボのコピーだけです。このラボは、わざと弱く作った店で、インターネットにはつながっていません。許可のない他人のシステムに同じことをするのは、不正アクセス禁止法に触れる犯罪です。
渡す力は仕事の分だけにする
ある人やプログラムには、仕事に要る力だけを渡します。これを 最小権限(least privilege)と呼びます。力が小さければ、乗っ取られても被害は小さく済みます。
会計係に冷蔵庫の鍵は要りません。予約を読むだけの画面に、予約を消す力は要りません。
例: 学食アプリの権限
| 担当 | 必要な力 | 渡してはいけない力 |
|---|---|---|
| 予約の一覧画面 | 予約を読む | 予約を消す、変える |
| 会計の画面 | 金額を読む、記録する | メニューを変える |
| ログを見る人 | ログを読む | ログを消す |
| アプリが使うデータベース口座 | 自分の表を読み書きする | 表を作る、消す、他の表に触れる |
学生が入力するセルは、このプレビューでは空白です。
決まりがないときは断る
決まりに書いていない場合は、断ります。これを 安全側に倒す(fail safe)と言います。許すものを並べた一覧が 許可リスト(allow list)です。
逆に、止めるものの一覧だけを作ると、一覧にない新しいものが全部通ってしまいます。
知らない役割は断る
# 役割ごとに、許す操作の一覧を持ちます。
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台が乗っ取られれば、中から来たデータも攻撃になります。境界を越えて入るデータは、送り主にかかわらず検査します。