レッスン 2-6
ファイルの受け取りとパス
拡張子を
受け取った
なぜ通るのか
見積書を
ここで、
名前が場所の命令になる所
パスの/) を..) を
悪意が
さらに Python の os.path.join は、
確かめた時と使う時のずれ
「名前に
- 確かめた
あとに、 名前の 符号 (% で 始まる 書き方など ) を 戻したり、 文字の 正規化を したりする。 確かめたのは 戻す前の 文字列で、 開くのは 戻した あとの 文字列になる - 確かめた
時は 普通の ファイルだった 場所が、 開く 時までに 別の 場所への リンク (シンボリックリンク) に替わる - 保存の
時に 拡張子を 確かめても、 配信する 時には サーバーの 設定が 別の 規則で 扱いを 決める。 確かめた 所と、 実行や 表示が 決まる 所が違う
確かめは、
脆いコードと直したコード
ラボの
名前で保存するか、ID で保存するか
import os def save(base, name, data):path = os.path.join(base, name)with open(path, "wb") as f:f.write(data)return nameimport uuidfrom pathlib import Path NAMES = {} def save(base, name, data):fid = uuid.uuid4().hexPath(base, fid).write_bytes(data)NAMES[fid] = namereturn fid直した方では、
つないで開くか、正規化してから確かめるか
import os def load(base, name):path = os.path.join(base, name)with open(path, "rb") as f:return f.read()from pathlib import Path def load(base, fid):root = Path(base).resolve()path = (root / fid).resolve()if not path.is_relative_to(root):raise PermissionError(fid)return path.read_bytes()resolve は、
ログでの見え方と検知
脆い
FileNotFoundError: [Errno 2]No such file or directory:'uploads/2026/見積.pdf'この
| 見る物 | な |
|---|---|
| 開こうとした | 置き場の |
| 置き場の | 直した |
| 区切りや | ふだんの |
記録には
直し方と、直ったことの確かめ方
自分の
- 作業用の
フォルダの 中に、 置き場の フォルダ uploads を作る - 脆い
saveに、作業用の フォルダの 中の uploads の 外を 指す絶対パスを 名前として 渡し、 uploads の 外に ファイルが できる ことを 確かめる - 保存と
取り出しを、 直した コードに 置き換える - 同じ
名前を 渡し、 uploads の 外には 何も できず、 uploads の 中に ID の 名前の ファイルが 1 つできる ことを 確かめる - uploads の
中に 外を 指すリンクを 1 つ 置き、直した loadが拒むことを 確かめる - 下の
試験を 足し、 直す前の コードに 戻すと 試験が 落ちる ことも 確かめる。 終わったら 作業用の フォルダごと消す
def test_name_cannot_pick_place(tmp_path):base = tmp_path / "uploads"base.mkdir()outside = tmp_path / "outside.txt"fid = save(base, str(outside), b"x")assert not outside.exists()assert (base / fid).read_bytes() == b"x" def test_link_cannot_leave(tmp_path):base = tmp_path / "uploads"base.mkdir()(tmp_path / "secret.txt").write_text("s")link = base / "link"link.symlink_to(tmp_path / "secret.txt")with pytest.raises(PermissionError):load(base, "link")試験は
あわせて、
関わる事例
この
CISA と
その
確認クイズ
1 問目
保存の
- ア
確かめる 文字列と、 保存に 使う 文字列が違う - イ 符号を
戻すと、 ファイルの 中身が壊れる - ウ 文字列の
確かめは 遅いので、 要求が詰まる
答えと理由を見る
答え ア
確かめたのは
2 問目
利用者が
- ア 利用者の
付けた 名前のまま、 公開フォルダに置く - イ 利用者の
付けた 名前から 区切りの 文字を 取り除いて、 公開フォルダに置く - ウ アプリが
振った ID で 公開フォルダの 外に 置き、 名前は 表示用に 別に持つ
答えと理由を見る
答え ウ
ID で
説明課題
次の
- 確かめた
時と 使う 時の ずれが 問題に なる例を 1 つ挙げ、 なぜ問題に なるのか
模範解答を見る
名前に
一次資料
どれも
- 安全な
ウェブサイトの 。作り方 1.3 パス名パラメータの 未チェック/ディレクトリ・ トラバーサル (IPA、 日本語) 固定の フォルダの 名前と つなぐだけでは 防げない こと、 絶対パスの 指定、 アクセス権限を 正しく 管理する 保険的な対策 - File Upload Cheat Sheet (OWASP、英語)。
名前を アプリが 作った 物に 替える こと、 公開フォルダの 外か別の サーバーに 置く こと、 Content-Type を 信じないこと - Secure by Design Alert Eliminating Directory Traversal Vulnerabilities in Software (CISA、英語)。
2024年5月2日の CISA と FBI の 文書、 CVE-2024-1708 と CVE-2024-20345、 KEV カタログの 55 件
次へ
次の