家の鍵を「他人に渡す」のと同じこと?ファイルアップロードの危険な落とし穴
こんにちは!現場でセキュリティの最前線に立っていると、ふと「なぜこんな単純な仕組みで攻撃されてしまうんだろう?」と思うことがあります。その筆頭が、Webサイトの「ファイルアップロード機能」です。
皆さんが普段使っているSNSやクラウドストレージ。ユーザーが画像をアップロードする機能は便利ですが、実は「攻撃者にとっての裏口」になりやすい場所なんです。今日は、なぜこの機能が狙われるのか、そしてどうやって鉄壁の防御を築くのか、身近な例えを交えてお話ししますね。
—
1. 「名前をそのまま保存する」という危うさ
想像してみてください。あなたは自分の家の玄関に「郵便受け」を置きました。誰でも自由に封筒を入れられる仕組みです。
もし、攻撃者がその封筒に「../../リビングの金庫への鍵.txt」なんて名前を書いて送りつけてきたらどうなるでしょう?
もしシステムが、「送られてきた名前の通りに保存する」という単純な処理をしていたら……。プログラムは言われるがままに、サーバーの大事な領域に勝手にファイルを書き込んでしまいます。これが「パス・トラバーサル(ディレクトリトラバーサル)」攻撃の正体です。
攻撃者は、あなたのサーバーの「本来触らせてはいけない深い場所」に、自分の悪意あるプログラム(バックドア)をこっそり隠そうとします。これが実行されると、サーバーが乗っ取られるのは時間の問題です。
—
2. 鉄壁の守りを作る「3つの防犯ルール」
では、どうすれば安全にファイルを受け取れるのでしょうか? 対策はシンプルですが、徹底することが重要です。
ルール①:ファイル名は「ランダム化」する
ユーザーが付けたファイル名をそのまま使うのは厳禁です。代わりに、プログラムで生成したUUID(世界で唯一のランダムな文字列)をファイル名にしましょう。
- 悪い例:
my_photo.jpg→ そのまま保存 - 良い例:
550e8400-e29b-41d4-a716-446655440000.jpg→ 名前を変えて保存
これだけで、攻撃者がファイル名を使ってサーバー内の場所を指定する(トラバーサルする)ことは不可能になります。
ルール②:拡張子は「ホワイトリスト」で絞り込む
「なんでも受け入れる」のは防犯上最悪です。画像ならjpg, png, gifだけ。それ以外は即座に拒否する。これがホワイトリスト方式です。
- 「.php」や「.sh」といった実行可能なファイルが紛れ込んでいないか、厳しくチェックしましょう。
ルール③:保存先は「Web公開領域外」にする
もし可能であれば、アップロードされたファイルを保存する場所を、Webサイトのプログラムが動くディレクトリとは別の場所に逃がしてください。たとえ攻撃者が悪意あるファイルをアップロードしたとしても、それがWebブラウザから直接アクセスできない場所にあれば、実行されることはありません。
—
3. 実践!安全なファイル保存ロジック(サンプルコード)
では、具体的にどのようなコードを書くべきか、Python(Flask)を例に見てみましょう。
import os
import uuid
from flask import request
許可する拡張子のリスト(ホワイトリスト)
ALLOWED_EXTENSIONS = {‘png’, ‘jpg’, ‘jpeg’, ‘gif’}
def allowed_file(filename):
# 拡張子を確認する関数
return ‘.’ in filename and filename.rsplit(‘.’, 1)[1].lower() in ALLOWED_EXTENSIONS
def save_uploaded_file(file):
if file and allowed_file(file.filename):
# 1. 元のファイル名は捨てて、UUIDで新しい名前を生成する
extension = file.filename.rsplit(‘.’, 1)[1].lower()
new_filename = f”{uuid.uuid4()}.{extension}”
# 2. 保存先のパスを固定する(ユーザー入力には依存させない)
upload_folder = ‘/var/www/uploads/’
save_path = os.path.join(upload_folder, new_filename)
# 3. ファイルを保存
file.save(save_path)
return True
return False
このコードのポイントは、「ユーザーが送ってきた情報を一切信用せず、サーバー側で命名し直している」点です。これがセキュリティにおける「信頼の境界線」を守るということなんです。
—
最後に:セキュリティは「疑うこと」から始まる
セキュリティに携わるエンジニアにとって、一番の敵は「きっと大丈夫だろう」という慢心です。
- 「ファイル名ぐらい、変な入力は来ないだろう」
- 「拡張子チェックなんて、面倒だからいいや」
そう思った瞬間、攻撃者の足音はすぐそこに聞こえています。今回紹介した対策は、基本的なことばかりですが、これを徹底するだけで、あなたのシステムは圧倒的に強固になります。
まずは今日、あなたのプロジェクトのファイルアップロード処理を覗いてみてください。もし「ユーザーのファイル名をそのまま保存」していたら……それが改善のチャンスです。
一歩ずつ、強固で安全なシステムを一緒に作っていきましょう!応援しています。
コメント