GMO Flatt Security株式会社の公式ブログです。
プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。
こんにちは。株式会社Flatt Securityセキュリティエンジニアの村上です。セキュリティ・キャンプ卒業後、新卒入社組としてFlatt Securityでセキュリティエンジニアをしています。
本稿では、Webアプリケーション上で実装される「ファイルアップロード機能」の実装パターンをいくつか示し、「開発者が設計をする上で気をつけるべき脆弱性」とその対策について解説していきます。
「ファイルアップロード機能」の脆弱性は特定の言語やサービスによって発生する脆弱性だけでなく、特定の拡張子のファイルでのみ発生する脆弱性など非常に多岐にわたります。そのため、本稿では全ての脆弱性を網羅する事は目的としておりません。しかし、「ファイルアップロード機能」のセキュリティについて考えるための基本となる知識と対策観点を本記事で知って、今後の開発に応用していただければ幸いです。
SNSや掲示板サイトなどでよく見るシンプルな画像ファイルのアップロード機能です。この場合、画像ファイルのみを受け入れてそれ以外のファイルは適切に拒否される必要があります。
アップロードされるファイル形式が適切に制限されていない場合、画像ファイル以外のファイルがサーバーに設置されることによりサイトの改竄やサーバーの乗っ取りといった攻撃が行われる危険性があります。
例えばApacheなどで動いているサービスに対して任意のPHPファイルを設置できる場合、PHPを経由してWebサーバーに対してシェルコマンドの実行を行うことができます。Node.jsの場合においても、サーバーサイドのJavaScriptのコードを書き換える事によってシェルコマンドの実行ができてしまうパターンがあります。
他にも、フィッシング攻撃に利用されたり攻撃者によって意図しないファイル(マルウェア等)が設置されたりと攻撃に加担させられる危険性も存在します。
このような意図していないファイルをアップロードする攻撃に対して、具体的にどういったケースで問題が発生するかを解説します。
ファイルアップロード機能を設計する場合、HTMLのinput要素のaccept属性を利用することによって画像ファイルのみ選択できるようにする場合や、JavaScriptを利用してファイルをアップロードする前にクライアント側で適切なファイルであるかをチェックするといった事を行う場合があります。
このようにクライアントサイドでファイル形式やアップロードされるファイルの安全性をチェックする場合、その制限を回避される危険性があります。例えばブラウザでアップロードするファイルの表示設定を変更することによって画像ファイル以外をアップロードしたり、リクエストを書き換えることによってクライアントサイドでのチェックを回避したりといった方法です。
ではどのように対策をすればよいかについて簡単に説明していきます。
ファイルが意図された適切な種類のものかのチェックは原則としてクライアントサイドではなくサーバーサイドで実行します。先ほども述べた通り、クライアントサイドでのチェックはさまざまな回避方法が存在しています。
たとえ、クライアントサイドでアップロード前にチェックを行った場合でも欠かさずにサーバーサイドでのチェックが必要となります。
アップロードされたファイルの拡張子が開発者の意図したものであるかの確認を行うために正規表現を利用する場合は注意が必要です。後方一致による正規表現のチェックでない場合、example.jpg.phpのような二重拡張子がついているファイルを用いることによってチェックを回避される危険性があります。
拡張子のチェックは前方一致や部分一致ではなく、後方一致によって行うことで二重拡張子などによるチェックの回避を防ぐことができます。
言語ごとに用意されている関数を利用して拡張子のチェックを行う関数を作成する場合も正しく後方一致のロジックが実装されているか気をつける必要があります。
後方一致による拡張子のチェックのフローの例:
一般的でない拡張子を利用する事により拒否リスト型の拡張子の制限を回避される危険性があります。
例えばPHPの場合.php
以外に以下のような拡張子の種類があります。このような拡張子を利用する事によって、.php
の拡張子が制限されている場合もPHPのファイルをアップロードすることができてしまいます。
利用できる拡張子の制限は拒否リストではなく許可リストによって行ってください。それにより想定外の拡張子のファイルがアップロードされる事を防げます。
細工をしたファイル名を送信する事により意図しない場所にファイルを設置される危険性があります。設定ファイルの書き換えによるサーバーの乗っ取りや、Webサイトの書き換えを行うことが出来てしまいます。
アップロードされたファイルのファイル名に対して、「/」「\」「:」などの利用するとディレクトリトラバーサルが可能な記号が含まれていない事を確認してください。
巨大なファイルをアップロードする事によってサーバーのリソースを意図的に消費したり、サーバーでの処理に負荷をかけることにより正常な操作を行えなくしたりするDoS攻撃が発生する危険性があります。
サーバーの設定にてリクエストボディサイズの制限を行う事によって巨大なファイルを処理してしまう事を防ぎます。
多くの場合は言語やフレームワークごとに設定方法が用意されているため、リクエストのサイズを計測するプログラムを自作するのではなく適切な既存のプログラムを利用してください。
画像ファイルを編集するソフトウェアの脆弱性を攻撃する方法も存在しています。
例えば、ImageMagickはその最たる例と言えるでしょう。対応するファイル形式の多さやその利便性から広く使われているImageMagickですが、毎年多くの脆弱性が報告されています。CVE Detailsによると2021年には16件、2020年には43件もの脆弱性がCVEに登録されています。そのうちの3件は任意コード実行(RCE)が可能な非常に危険なものとなっています。
それだけ多くの脆弱性が発生する理由の一つとしては、対応しているファイルフォーマットの多さがあります。一般的なJPEGやPNGだけでなくさまざまなファイルフォーマットに対応しているため、それだけ脆弱性が発生する要因が存在してしまっています。
ImageMagickのポリシーから必要なファイルフォーマットのみを許可してください。それにより、脆弱性につながる危険性のあるファイルをImageMagickが処理してしまう危険性を減らす事が可能です。
最新のバージョンのImageMagickを利用することによって既知の脆弱性を利用した攻撃を防ぐ事が可能です。バージョンによっては既存のプログラムがうまく動かなくなるという危険性もありますが、セキュリティ上の観点からは最新のバージョンを利用してください。
画像ファイルに登録されている情報を適切に削除しない場合、画像ファイルにアクセスできるユーザーに意図せずファイルに紐づく情報を取得される危険性があります。それにより、個人名や撮影場所や撮影時間といった情報が漏洩する危険性があります。
サーバーに画像ファイルがアップロードされた際に、写真を撮影した場所や時間の特定に利用できるExif情報を削除してください。
ファイル名に氏名などが使われている場合、そこから意図せず個人情報が漏洩する危険性があるため、例えばランダムな文字列などにファイル名を変更してください。
業務アプリ等でデータを移行する際にCSV形式のファイルを利用するパターンです。BtoB SaaS等でかなりポピュラーな機能だと思います。
データを移行するために作成されるCSVファイルは多くの場合ユーザーが作成するのではなく、信用できるWebアプリケーション上で作成されたものをインポートして利用されます。
CSVファイル自体は信用できるWebアプリケーションが生成したものであっても、CSVファイルを攻撃者が直接加工できる場合や、CSVファイルに集計されることを見越して元々悪意のある値がアプリケーションに渡っていた場合にはリスクが発生します。
信用できるWebアプリケーション上で生成されたCSVファイルに対して、攻撃者が悪意のある変更を行える場合を考えます。アプリケーションが生成したCSVテンプレートに対し、従業員情報をローカルでExcelなどを用いて入力し、アプリケーションに一括アップロードする機能が考えられます。
この時、信用できない値をCSVファイルをアップロードされたWebアプリケーションが受け取ってしまう事になります。これにより、XSS(Cross-Site Scripting)やSQLインジェクションをはじめとした一般的なWebアプリケーションの脆弱性が引き起こされます。
また、アプリケーションの仕様として意図していない値を入力(正の正数しか想定していない箇所にマイナスを入力される、少数を入力される、文字列を入力される等)されてしまいシステムの整合性が取れなくなる等の可能性もあります。
それらの攻撃を防ぐためにCSVファイルから受けとった値に対しても通常のWebアプリケーションで行うような、特殊記号のエスケープ処理や値のチェックのような対策を行ってください。
CSVファイルによるデータのやりとりで頻繁に発生するのがこの脆弱性です。悪意のある値を含むCSVファイルを第三者がダウンロードできる形にすることにより、ExcelでCSVファイルを開いた第三者に対してExcelの関数を実行させることが可能です。
例えばWebフォームのアンケート機能において、最終的にCSVファイルに集計されることを見越して悪意のある値を入力しておき、エクスポートされたCSVファイルがExcelで開かれた時に脆弱性が発現するようなパターンです。攻撃を受けた側としては信用できるアプリケーションからダウンロードしたファイルを開いただけで攻撃が成立してしまうわけです。
この攻撃によりCSVファイル内のデータが第三者に流出する危険性や、DDE関数を利用する事により任意のシェルコマンドの実行が引き起こされる危険性があります。
CSVファイル内の値がExcelによって関数だと認識されないように=/+/-/@/Tab(0x09)/改行コード(\n,\r)/フィールド区切り文字(;/,)
が値の先頭に来る場合にはシングルクオーテーション('
)を先頭につける事により関数ではなく単なる文字列と扱わせる処理を実装してください。
問題として、負の値(-1
等)を利用できなくなる問題があるため、必要に応じて負の値を利用する際には数字以外の文字が入らないようにするなどの処理を追加する必要があります。
免許証や健康保険証などによる本人確認を行う際に利用される本人確認書類のアップロード機能では、これまでの対策に加えて第三者による閲覧を防ぐための対策が必要になります。toCの金融系サービスやマッチングアプリでほぼ必須と言える機能です。
本人確認実施後そのまま本人確認書類をWebアプリケーション上に保存していた場合、潜在的なリスクとなります。何かしらの攻撃により攻撃者に本人確認書類が漏洩した際に、適切に不要な本人確認書類の消去が行われていた場合影響は小規模なものになります。しかし、古い本人確認書類を削除していないと、最悪の場合サービス利用者全体にまで影響が拡大する危険性があります。
不要な機密情報は適切に削除することにより攻撃が発生した際の潜在的なリスクを低下させてください。
パターンAで紹介したようなアイコン画像のアップロードであれば、その画像が他のユーザーに見えることが期待される挙動のことも多いでしょう。しかし、本人確認書類のような機微な情報が他のユーザーから閲覧可能だと大きなリスクとなります。
アップロードされたファイルに対して適切なアクセス制限を行ってください。
よくあるパターンとしては、そもそもアクセス制限が行われておらずファイルに割り振られたIDがわかれば誰でもアクセスできる場合や、Cookieの値などユーザー側が変更可能な値を元にアクセス制御が行われている場合があります。このような実装においてはアクセス制限を回避して攻撃者がアクセスを行える可能性が高いです。
対策1を行なった上でアクセス制限を回避された場合の緩和策として、ファイル名を推測困難にするというのがあります。ファイル名に対してUUIDなどを割り当てる事により第三者がファイル名を推測することが難しくなります。
本稿では、現代のWebサービスでよくみる3つのパターンに関してファイルアップロード機能の主要な脆弱性を解説しました。しかし、今回紹介することのできなかった脆弱性もまだまだたくさんあります。それは利用しているサービスやWebサービス自体の設計、扱うファイルの形式などさまざまな要因によって引き起こされてしまいます。
そのため、これをすれば全てのパターンで脆弱性を防げるという対策はありません。しかし、どのような攻撃への対策も本稿で紹介した知識が基本となるため、強固なWebサービスを作成する第一歩として本稿がお役に立てると幸いです。
Flatt Securityでは、今回ご紹介したような脆弱性を洗い出すため、セキュリティエンジニアの手動検査とツールを組み合わせたセキュリティ診断サービスを提供しています。
過去に診断を実施したが不安や課題がある、予算やスケジュールに制約がありどのように診断を進めるべきか悩んでいる等、お困り事にあわせて対応策をご提案いたしますので、まずはお気軽にお問い合わせください。
お問い合わせは下記リンクよりどうぞ。
https://flatt.tech/assessment/contact
Flatt Securityはセキュリティに関する様々な発信を行っています。最新情報を見逃さないよう、公式Twitterのフォローをぜひお願いします!
ここまでお読みいただきありがとうございました!
2022年6月16日「画像ファイルからの個人情報の漏洩」にて画像ファイルから意図しない漏洩が発生する危険性について追記しました。こちらの観点は以下のご両名よりご提案いただき追記させていただきました。ありがとうございました。
@shioshiota (Exifの削除),@kyohei_shimada (ファイル名の変更)
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。