本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。
Web開発者が気を付けたいDoS攻撃手法
初めまして 2025年4月に新卒でMBSDに入社しました、PS部の坂島です。
弊社の技術者ブログは入社前から愛読しており、入社したら自分も執筆したいと思っていました。そんな中、ブログ執筆の機会をいただけたため、学生時代から「イメージしやすくとっつきやすそうで、実は掘り下げると奥深い」という点に強く興味を惹かれていたDoS攻撃をテーマに執筆することにしました。
早速ですが、DoS攻撃というと、まずDDoS攻撃のような大量のトラフィックによる帯域枯渇やリソース逼迫を思い浮かべる方は少なくないのではないでしょうか。
しかし実際には、Webアプリケーションといったアプリケーション層に存在する設計や実装の脆弱性を突いてサービスに極端な負荷をかける攻撃があります。
こういった攻撃に対する一時的な対策として、インフラ・運用チームが実装するCDN・WAF・オートスケールが機能する場合もあります。しかしもう一方でアプリ側に脆弱性が残ったままでは攻撃を完全に回避することはできません。
そのためこういったタイプのDoS攻撃への対策は、運用よりも前の、設計およびコーディング等、開発プロセスの早い段階で対策をしておくことが必要です。
そこで本記事では、Web開発者および設計者の方を対象として、Webアプリケーションに存在するいくつかの代表的な脆弱性を悪用するDoS攻撃の仕組みと対策を取り上げます。
注意事項
この記事の目的は、各攻撃の概要を通じて攻撃が成功する仕組みを知っていただき、対策の項目とあわせて、自身のアプリケーションにどのような対策が必要かを検討する際の参考にしていただくことです。攻撃の仕組みを解説しておりますが、実際に許諾を得ていないサーバーに対して攻撃を行うことは不正アクセス禁止法などの法律に抵触する可能性があるため、絶対に行わないでください。
なお、特定の言語やフレームワークに依存しない原則・考え方を中心に解説いたします。個別製品における具体的な設定、構成については、必ず各製品の公式マニュアルなどに記載されている信頼できる情報に基づいて判断してください。
また、本記事では「DoS攻撃」を、サービスの正常な提供を妨げる状態を意図的に引き起こす攻撃の総称として用います。
補足として、一般的なWeb診断ではDoSの観点での診断は行われません。これは、診断対象のサイトに実際の負荷をかけることで、サービスに悪影響を与えるリスクがあるためです。弊社のWeb診断でも診断対象に直接負荷をかけるテストは実施しておりませんが、理論上DoSにつながりうる挙動を調査し、その可能性がある場合は報告しています。
ReDoS(Regular Expression Denial of Service)
概要
ReDoSとは、問題のある正規表現パターンを用いているWebアプリケーションに対し、細工した入力を与えることで、大きな負荷をかける攻撃です。
正規表現エンジンによっては、途中まで一致しても最後まで成立しない正規表現パターンがあった時、直前の分岐点や繰り返し回数の選び方まで戻って別の候補を試し直す動作が発生します。これをバックトラッキングと呼びます。
また、曖昧な正規表現を書いてしまうと、その分考えられる組み合わせが膨大になり、バックトラッキングの発生回数も増えてしまいます。
OWASPでは、以下のような正規表現パターンの条件と例は「操作された入力でスタックするEvil Regex(直訳:邪悪な正規表現)」として紹介しています。
条件
- 反復によるグルーピング
- 繰り返しのグループ内:
- 繰り返し
- 重複した分岐
例
(a+)+$([a-zA-Z]+)*$(a|aa)+$(a|a?)+$
また、この「Evil Regex」の条件が満たされない正規表現でも以下のような曖昧な正規表現は、ReDoSを発生させることが可能です。
a*a*$
対策
以下の1,2の両方、可能であれば3もあわせて実施することで有効な対策となります。
- バックトラッキングが起こり得る曖昧な正規表現を避ける
- ユーザがサーバ側で評価される正規表現を定義できる設計にしない
- 高度な正規表現の機能が必要ない場合、バックトラッキングによるマッチングが行われない正規表現ライブラリを用いる
以下2つのツールは、ReDoSに脆弱な正規表現となっていないかどうかの確認に有用です。
※どちらもオンラインサービスであるため、入力する正規表現に注意してください
- regex101: build, test, and debug regex: https://regex101.com/
- Playground | recheck: https://makenowjust-labs.github.io/recheck/playground/
参考
- OWASP: Regular expression DoS (ReDoS): https://owasp.org/www-community/attacks/RegularexpressionDenialofService-ReDoS
- 正規表現が ReDoS 脆弱になる 3 つの経験則 | 立命館コンピュータクラブ: http://www.rcc.ritsumei.ac.jp/2021/1220_12435/
- regex101: build, test, and debug regex: https://regex101.com/
- Playground | recheck: https://makenowjust-labs.github.io/recheck/playground/
- 2019年7月2日に発生したCloudflareの停止に関する詳細: https://blog.cloudflare.com/ja-jp/details-of-the-cloudflare-outage-on-july-2-2019/
不正データ登録による永続的なDoS状態
概要
不正データ登録による永続的なDoS状態とは、入力検証の不備を突かれて想定外の形式のデータがDBや設定ファイルなどへ保存され その後該当データの読み出し処理が継続的に失敗することでサービス停止状態に陥る問題です。
特定のロジックに限定できるものではありませんが、以下のようなケースがあります。
- 数値リテラルが想定された処理で、記号などの文字列が混入して、読み出し時に型変換エラーで処理が止まってDoSに至る
対策
- 入力値検証を厳格に行い、逸脱するものはエラーとし、登録しない
参考
- Input Validation - OWASP Cheat Sheet Series: https://cheatsheetseries.owasp.org/cheatsheets/InputValidationCheat_Sheet.html
Web Cache PoisoningによるDoS攻撃
概要
まず、Web Cache Poisoningとは攻撃者がキャッシュに載るレスポンスを意図した内容に汚染し、その後の利用者にもその内容を返させる攻撃です。攻撃者のXSSスクリプトを被害者に配信させる際に悪用されることもある脆弱性ですが、DoS攻撃にも利用されます。攻撃者が長大なヘッダ値を指定するなど、リクエストを細工してオリジンサーバにエラーを返させ、そのエラー応答をキャッシュさせます。そうすると、以降の一般ユーザが同じリソースへアクセスした際にエラーが返り続け、結果としてサービスを利用できなくなります。
対策
Web Cache Poisoningの本質的対策は、「動的コンテンツをキャッシュさせない」ことです。今回紹介したもの以外にもキャッシュを起因とする脆弱性がありますが、動的コンテンツをキャッシュをさせないことが対策の原則となります。
また、CDNなど複数の構成要素が絡み、環境によって適切な対策が異なることにも注意が必要です。
参考
- CPDoS: Cache Poisoned Denial of Service: https://cpdos.org/
- Web Cache Poisoning | WebApp Testing: https://wg1.isog-j.org/newtechtestdoc/docs/webcachepoisoning/
- Practical Web Cache Poisoning | PortSwigger Research: https://portswigger.net/research/practical-web-cache-poisoning
画像処理を悪用したDoS攻撃
概要
画像処理を悪用したDoS攻撃とは、細工した画像ファイルをサーバに処理させることで、メモリやCPUなどの計算資源を過剰に消費させ、サービスの継続を妨げる攻撃です。
代表例として知られているのがPixel Floodです。これは、画像のファイルサイズ自体は小さなまま、寸法のメタデータのみ極端に大きくなるように操作してアップロードすることで、サーバ側の画像編集アプリケーション、ミドルウェアで読み込んだ際大量のメモリやCPUを消費させる攻撃です。
画像処理を悪用したDoS攻撃はPixel Floodに限らず、たとえば、PNG compression DoS攻撃という高圧縮のPNGを展開する際の負荷を用いたDoSや、GIF floodingと呼ばれる、巨大な寸法や大量のフレームを持つアニメーションGIFによって、デコードや変換処理の負荷を増大させる攻撃があります。こうした問題は、実際の画像処理ライブラリや周辺ソフトウェアでもたびたび課題となってきました。特にImageMagickのような汎用画像処理ツールは対応形式が多く、入力によって処理コストが大きく変動するため、設定や利用方法によってはDoS攻撃の起点になり得ます。
このImageMagickのセキュリティについては弊社の寺田が下記のブログで詳しく解説しておりますので是非ご覧ください。
- ImageMagickを使うWebアプリのセキュリティ - 2. DoS | 技術者ブログ | 三井物産セキュアディレクション株式会社: https://www.mbsd.jp/research/20180907/imagemagick2/
対策
- 不正なメタデータを持つ画像を処理しない
- 画像処理に割り当てるリソース(メモリ、CPU、実行時間)を制限できる仕組みを使う
参考
- ImageMagickを使うWebアプリのセキュリティ - 2. DoS | 技術者ブログ | 三井物産セキュアディレクション株式会社: https://www.mbsd.jp/research/20180907/imagemagick2/
- HackerOne | Report #390 - Pixel flood attack | HackerOne: https://hackerone.com/reports/390
- HackerOne | Report #454 - PNG compression DoS | HackerOne: https://hackerone.com/reports/454
- HackerOne | Report #400 - GIF flooding | HackerOne: https://hackerone.com/reports/400
GraphQLにおけるDoS
概要
GraphQLにおけるDoS攻撃とは、負荷の高いクエリをGraphQLエンドポイントに送信することによってサーバーに負荷をかけるDoS攻撃です。
GraphQLは、クライアントが必要なデータを柔軟に取得できるため、自由度が高いというメリットがありますが、その分サーバ側では、リクエストされたクエリの複雑さや指定されたオブジェクトの量を適切に確認しないとDoSにつながることがあります。
GraphQLにおけるDoS攻撃の例としては、たとえば次のようなものがあります。
- 循環参照を使用したDoS
- batch mutationを悪用した攻撃(負荷の高い処理を多数行うクエリをまとめて1つのリクエストで送信することで大きな負荷をかける)
- データの取得件数が膨大になるように細工し、サーバーに大きな負荷をかける
例えばこの中の、循環参照を使用したDoSは以下のような攻撃です。 オブジェクト同士が相互参照するスキーマが存在するGraphQL APIに対して、次のようにネストが深いクエリを実行させることでサーバに負荷をかけます。
query{
A{
B{
A{
B{
A{
name
}
}
}
}
}
}
リゾルバの実装にもよりますが、AもBも配列である場合、探索が枝分かれし、それぞれがさらに探索を繰り返すことによってサーバーに大きな負荷がかかります。
対策
- クエリの深さ制限
- レスポンスするオブジェクト数制限
- タイムアウト、レート制限
参考
- GraphQLによるDoS攻撃 | GraphQL診断ガイドライン: https://wg1.isog-j.org/graphQLGuideLine/docs/specific/dos/
- GraphQL - OWASP Cheat Sheet Series: https://cheatsheetseries.owasp.org/cheatsheets/GraphQLCheatSheet.html
SQLのLike句によるDoS
概要
Like InjectionによるDoS攻撃とは、検索機能などでワイルドカードが使えることを悪用してサーバーに負荷をかけるDoS攻撃です。
検索機能の実装時に、ユーザ入力をそのままLIKE検索に使う設計でこのDoS攻撃が成立することがあります。
例えば、%や_といったワイルドカードを悪用され、以下のようなクエリを構築されてしまい、DBに負荷をかけることができる場合があります。
select * from users where email like '%_%_%_%_%_%_%_%_3e3c3844e10000@example.com';
このように%や_といった記号がlike句にそのまま渡されると、パース及びコンパイルの段階で非常に長い時間がかかってしまいます。
対策
- ユーザの入力からワイルドカードとして用いられる「%」「_」「[」「]」「^」といった値をエスケープする
参考
- LIKE injection - The GitHub Blog: https://github.blog/engineering/user-experience/like-injection/
Billion laughs攻撃
概要
Billion laughs攻撃は、XMLの実体参照を悪用して大きな負荷をかけるDoS攻撃です。
XMLでは、DTDと呼ばれる部分で、そのXML文書で使用される要素(文字列含む)を定義できます。これを悪用し、次のように「DTDにて何らかの文字列を定義し、その文字列を結合させることによって別の文字列を定義、さらにその文字列を...」といった具合に文字列を繰り返し定義することによってパーサに負荷をかけることができます。
<!DOCTYPE data [
<!ENTITY data "test data">
<!ENTITY data2 "&data;&data;&data;&data;&data;&data;&data;&data;&data;&data;">
<!ENTITY data3 "&data2;&data2;&data2;&data2;&data2;&data2;&data2;&data2;&data2;&data2;">
]>
<data>&data3;</data>
古典的ですが、「古いXMLパーサを使い続けている」「パーサが安全な設定になっていない」といった条件が満たされる場合では今でも問題になります。
なお、XMLのパーサを悪用したほかの攻撃としてXXEがあります。こちらについて弊社の諌山が過去に執筆した記事がありますので、詳しく知りたい方はぜひご覧ください。
- XXE攻撃 基本編 | 技術者ブログ | 三井物産セキュアディレクション株式会社: https://www.mbsd.jp/research/20171130/xxe1/
- XXE 応用編 | 技術者ブログ | 三井物産セキュアディレクション株式会社: https://www.mbsd.jp/research/20171213/xxe2/
対策
- DTDを無効化する、もしくはエンティティの展開に制限を設ける
- 古いXMLパーサを用いない
- XMLを受け取らない設計にする
参考
- Billion laughs attack: https://en.wikipedia.org/wiki/Billionlaughsattack
- XXE攻撃 基本編 | 技術者ブログ | 三井物産セキュアディレクション株式会社: https://www.mbsd.jp/research/20171130/xxe1/
- XXE 応用編 | 技術者ブログ | 三井物産セキュアディレクション株式会社: https://www.mbsd.jp/research/20171213/xxe2/
その他
ここまで挙げたのはDoS状態にすることを主目的とした攻撃手法ですが、攻撃者がデータを書き換えられる脆弱性やOSコマンドインジェクション、SQLインジェクション、XSS等を足がかりに、プロセス停止・不正データ生成・ページ改ざん等によってサービスをDoS状態へ持ち込むこともできてしまいます。そのため、いうまでもなく日ごろからこういった一般的な脆弱性への対策も欠かせません。
まとめ
DoS攻撃は、DDoS攻撃などの大量のトラフィックによって帯域枯渇を発生させるイメージが先行してしまうのではないかと思います。しかし今回記事内で紹介したように、アプリケーションの設計・実装に起因して成立するものもあります。
こうした問題は、インフラや運用による対処だけでなく、Web開発者及び設計者が、開発プロセスの早い段階から意識しておくことが重要です。
この記事が、攻撃を受けるリスクのある機能の設計及び実装時に、適切な対策を行う一助となれば幸いです。
おすすめ記事