WebVulnerabilities

アプリケーションのDoS攻撃について

概要

DoS(Denial of Service)攻撃とは、特定のWebアプリケーションやサーバーに過剰な負荷をかけ、正当なユーザーがサービスを利用できなくする攻撃です。DoS攻撃は、一つの攻撃者が単一のサーバーを標的に行う場合もあれば、DDoS(Distributed Denial of Service)攻撃のように複数の攻撃者や感染したコンピュータ群(ボットネット)を利用して大規模に行われる場合もあります。DoS攻撃は、システムリソースを枯渇させる、アプリケーションの脆弱性を悪用するなど、さまざまな手法で実行されます。


起こりうる攻撃の種類

  1. HTTP Flood:
    • HTTPリクエストを大量に送信してサーバーに過剰な負荷をかけ、リソースを使い果たす攻撃です。特にリソースを多く消費するページや処理を標的にします。
  2. Slowloris:
    • HTTPヘッダーやリクエストボディの送信を意図的に遅く行い、サーバーがリソースを長時間保持し続けるようにして、サーバーのリソースを枯渇させる攻撃です。
  3. リソース消費攻撃:
    • 高負荷な計算や大量のデータベースクエリを発生させるリクエストを多数送信し、サーバーのCPU、メモリ、ストレージなどのリソースを消費させる攻撃です。
  4. アプリケーションの脆弱性を狙った攻撃:
    • 特定のアプリケーションの脆弱性(例えば、無限ループやリソースの過剰消費を引き起こすバグ)を悪用して、サーバーを過負荷状態に陥らせる攻撃です。

脆弱性を持つコードの例と攻撃手法

PHP

脆弱なコード例:リソース消費攻撃

<?php
// 大量のデータを返すエンドポイント
if ($_GET['type'] === 'large_data') {
    $data = str_repeat('A', 10000000); // 10MBのデータを生成
    echo $data;
}
?>

攻撃手法:

Python(Flask)

脆弱なコード例:無限ループによるDoS攻撃

from flask import Flask, request

app = Flask(__name__)

@app.route('/loop')
def loop():
    n = int(request.args.get('n', '1000000'))
    for i in range(n):
        pass
    return "Done"

if __name__ == '__main__':
    app.run()

攻撃手法:

Node.js(Express)

脆弱なコード例:JSONパースによるDoS攻撃

const express = require('express');
const app = express();

app.use(express.json());

app.post('/data', (req, res) => {
    res.send('Data received');
});

app.listen(3000);

攻撃手法:

Java(Spring Boot)

脆弱なコード例:無限リダイレクトによるDoS攻撃

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RedirectController {

    @GetMapping("/redirect")
    public String redirect() {
        return "redirect:/redirect";  // 自分自身にリダイレクト
    }
}

攻撃手法:


防止策

  1. レートリミットの導入:
    • 特定のIPアドレスやユーザーからのリクエスト数を制限し、短期間に過剰なリクエストが送信されることを防ぎます。

    PHPの例:

    $ip = $_SERVER['REMOTE_ADDR'];
    if (rate_limit_exceeded($ip)) {
        http_response_code(429);
        exit('Too Many Requests');
    }
    

    Node.jsの例(Express):

    const rateLimit = require('express-rate-limit');
    const limiter = rateLimit({
        windowMs: 15 * 60 * 1000, // 15分
        max: 100 // 最大100リクエスト
    });
    app.use(limiter);
    
  2. リクエストサイズの制限:
    • リクエストボディやファイルアップロードのサイズを制限し、過剰に大きなデータが送信されることを防ぎます。

    Python(Flask)の例:

    app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 最大16MB
    

    Node.jsの例:

    app.use(express.json({ limit: '1mb' }));
    
  3. リクエストのバリデーション:
    • リクエストパラメータのバリデーションを行い、不正または不必要に大きな値が処理されないようにします。

    Java(Spring Boot)の例:

    @GetMapping("/loop")
    public String loop(@RequestParam int n) {
        if (n > 10000) {
            return "Value too large";
        }
        // ループ処理
    }
    
  4. WAF(Web Application Firewall)の導入:
    • WAFを使用して、特定の攻撃パターンを検知・ブロックすることができます。
  5. リソースの分離とスケールアウト:
    • 特に重要なサービスや機能は、他のサービスからリソースを分離し、必要に応じてスケールアウトできるように設定します。
  6. サーバーの適切な設定:
    • サーバーの設定で接続のタイムアウトや最大同時接続数を適切に設定し、過負荷状態を防ぎます。

まとめ: アプリケーションに対するDoS攻撃は、サーバーのリソースを過剰に消費させることで、サービスを停止させる危険な攻撃です。レートリミットの導入、リクエストサイズの制限、リクエストのバリデーション、WAFの導入などの防止策を講じることで、このような攻撃に対する耐性を強化し、アプリケーションの可用性を維持することが重要です。