Webアプリケーションセキュリティ入門 - Cyber Security Roadmap
はじめに
Webアプリケーションは仕事ではもちろん生活にも欠かせない存在です。
Gmailでメールを確認したり、Amazonで買い物をしたりと、さまざまなサービスをブラウザを使って利用できるのでとても便利です。
しかし、その便利さの裏にはセキュリティリスクも潜んでいます。この記事では、Webアプリの仕組みや弱点について理解し、どんなリスクがあり、どのようなことを学ぶべきか整理していきます。
Webアプリケーションの仕組み
Webアプリケーションは、リモートサーバー(インターネットを通じてアクセスできるサーバー)上で動作し、ブラウザを通して利用することができます。たとえば、ショッピングサイトで商品を探したり購入したりする際、サーバーがデータを処理し、その結果をユーザーに返しています。
オンラインショッピングサイトを例に見た脆弱性と問題
Amazonのようなオンラインショッピングサイトを例にとってみます。こうしたWebアプリには、さまざまな情報が保存されていることが想像できます。
- 商品データ:商品名、価格、画像、説明など
- ユーザーデータ:名前、住所、電話番号など
- 購入データ:購入履歴や支払い情報など
このようにして多くの情報を扱うアプリケーションにおいて、攻撃者がアプリの脆弱性を突くと、以下のような問題が発生する可能性があります。
- 商品情報が改ざんされ、ブランドイメージに悪影響が出る
- ユーザー情報が悪用される
- クレジットカード情報が不正利用され、金銭的な被害が発生する
こういったリスクは、運営者やユーザーにとって大きな問題を引き起こしかねません。
アプリケーションが扱う情報によって、セキュリティリスクは高くなることがわかります。
Webアプリケーションに潜む5つのセキュリティリスク
1. ログインに関するリスク
例えば、不正ログインが発生すると、以下のようなリスクが生じる可能性があります。
- 情報の漏洩と悪用:アカウントに保存されている個人情報が盗まれ、不正利用される
- 金銭的な被害:オンラインショッピングでの不正購入や、銀行口座や仮想通貨ウォレットからの資金流出が発生する
- 信頼性の低下:SNSやメールアカウントを悪用され、有害な投稿や詐欺メールの送信により、個人や組織の信用が損なわれる
- 二次被害の連鎖:同一の認証情報を複数のサイトで使用している場合、不正ログインをきっかけに他のアカウントも乗っ取られる
- 信用の喪失:被害が公になると、個人や企業が社会的信用を失う可能性があります。特に、公人や企業の公式アカウントでは大きなダメージとなる
不正ログイン攻撃の種類
不正ログインに対策するには、どんな手法で攻撃してくるのかを知ることも大事です。
以下は有名な不正ログイン攻撃になります。
攻撃手法名 | 説明 |
---|---|
ブルートフォース攻撃 | すべての可能な文字列を順番に試し、不正ログインを試みる手法。 |
辞書攻撃 | 一般的に使用されるパスワードリストを基に試行を行う手法。 |
ジョーアカウント探索 | ユーザー名の存在有無を確認する攻撃。エラーメッセージや応答時間の違いを利用。 |
リバースブルートフォース攻撃 | 固定のパスワード(例: "password123")を複数のアカウントに対して試行する手法。 |
パスワードスプレー攻撃 | よく使われるパスワードを少数選び、多数のアカウントで試行する攻撃。アカウントロックを回避しながら攻撃が行われる。 |
パスワードリスト攻撃 | 流出した認証情報(ユーザー名とパスワードのペア)を利用して不正ログインを試みる手法。 |
不正ログイン攻撃への対策
例として以下は基本的な対策です。
上記で紹介したように不正ログイン攻撃にはさまざまな手法がありますが、いずれも大量の試行や既存の認証情報を用いて認証突破を目指すものです。
そのため、突破されないための仕組みを作ることが重要になります。
要件 | 仕様・実装詳細 |
---|---|
アカウントロック機能 | ・認証失敗5回でロック ・管理者解除 or 15分後自動解除 |
エラーメッセージの統一 | ・例:「ユーザー名またはパスワードが間違っています。」 ・存在可否の推測防止 |
応答時間の標準化 | ・成功/失敗に関わらず処理時間を2秒固定 ・ランダム遅延も検討 |
CAPTCHAの導入 | ・認証失敗一定回数後にCAPTCHA表示 |
二要素認証(2FA) | ・SMS/認証アプリでワンタイムコード入力 |
ログ監視の強化 | ・異常試行でIPブロック、通知送信 |
IPアドレスの制限 | ・特定地域外のブロックや一定回数でIPブロック |
弱いパスワードへの対策
先程の不正ログイン攻撃への対策は、システムを構築するエンジニアができる部分です。
対してどうしてもユーザー依存になる部分として、弱いパスワードへの対策が必要になることがあります。
例えば、一般的に弱いパスワードとして知られているpassword123
を使っていると、辞書攻撃などせずともログインが突破される可能性さえあります。
そのため、ユーザーが弱いパスワードを設定しない、されないための仕組みを作ることが重要になります。
要件 | 仕様・実装詳細 |
---|---|
強力なパスワードポリシー | ・12文字以上 ・英大文字/小文字/数字/記号含む ・単純パターン禁止 |
弱いパスワード使用禁止 | ・既知の弱いパスワードリストと照合し禁止 |
パスワード使い回し防止 | ・過去に使用したパスワードは再利用不可 |
パスワード生成の推奨 | ・ランダム生成ツール提供(16文字以上推奨) |
パスワード変更通知 | ・変更時にメール通知で不正検知 |
2.SQLインジェクション攻撃
SQLインジェクションは、アプリケーションが入力を適切に処理しない場合に発生する攻撃手法で、攻撃者がデータベースに不正なSQL命令を送り込むことで、データを盗んだり改ざんしたりします。
検索フォームやログイン画面など、データベースと通信する入力欄を悪用することで、通常はアクセスできない機密情報(例えばユーザー情報や管理者パスワード)を取得する可能性があります。
要件 | 仕様・実装詳細 |
---|---|
入力値の適切なバリデーション | ・正規表現で数値や文字列の形式を検証 ・例: /^[0-9]+$/ , /^[a-zA-Z0-9]+$/ ・不正入力時はエラー表示・処理中断 |
プリペアドステートメントの使用 | ・SQLとデータを分離 ・例(PHP): $stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password"); $stmt->bindParam(':username', $username);
|
特殊文字のエスケープ | ・特殊文字(例: ' , " )を適切にエスケープ・例(PHP): $safe_input = mysqli_real_escape_string($connection, $user_input);
|
最小限の権限でDBアクセス | ・DBユーザーには必要最小限の権限のみ付与 ・例: SELECT, INSERT のみ許可 ・DROPやALTERは付与しない |
エラーメッセージの抑制 | ・詳細なエラーは表示せず、一般的なメッセージのみ返す ・例: 「エラーが発生しました。システム管理者にお問い合わせください。」 |
3.クロスサイトスクリプティング(XSS)
クロスサイトスクリプティング(XSS)は、Webページに悪意のあるスクリプトを埋め込むことで、他のユーザーの情報を盗んだり、意図しない操作を実行させる攻撃です。
典型的な例として、コメント欄やフォーム入力に悪意のあるJavaScriptを挿入し、他のユーザーがそのページを閲覧した際にクッキー情報を盗む、または偽の画面を表示して情報を入力させるといった攻撃が挙げられます。
要件 | 仕様・実装詳細 |
---|---|
ユーザー入力のサニタイズとエスケープ | ・出力時に特殊文字をエスケープ ・例: < → < , > → > , " → " , ' → ' , / → / ・OWASP ESAPI、DOMPurify などの信頼できるライブラリを使用 |
Content Security Policy (CSP) の導入 | ・レスポンスヘッダーに CSP を設定 ・例: Content-Security-Policy: script-src 'self'; object-src 'none'; ・外部スクリプトは信頼済みドメインのみ許可 |
入力値のバリデーション | ・正規表現などで入力フォーマットを検証 ・例(メールアドレス検証): /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/
|
HTTP-only属性の使用 | ・クッキーに HttpOnly 属性を付与し、JSからのアクセスを禁止・例: Set-Cookie: session_id=abcdef; HttpOnly; Secure;
|
JavaScriptの安全な使用 | ・innerHTML ではなく textContent や setAttribute() を使用・例: element.textContent = userInput;
|
4.暗号化の不備
暗号化の不備は、支払い情報や個人データなどの機密情報が第三者に盗まれる原因となります。データが暗号化されずに送信されている場合、通信経路上で攻撃者に盗聴されるリスクが高まります。
この問題は、特に平文通信(HTTP)や弱い暗号化技術を使用している場合に顕著です。適切な暗号化技術を使用し、安全な通信プロトコル(例: HTTPS)を採用することで、このリスクを軽減できます。
要件 | 仕様・実装詳細 |
---|---|
HTTPSの全面導入 | ・Web全体でHTTPSを使用 ・HTTPリクエストはHTTPSへリダイレクト ・例(Apache): <VirtualHost *:80> Redirect permanent / https://example.com/
|
強力な暗号化アルゴリズムの採用 | ・データ暗号化:AES-256 ・公開鍵暗号化:RSA-2048以上 ・DES、RC4などの弱いアルゴリズムは使用禁止 |
TLSの使用 | ・最新バージョン(TLS 1.3推奨)を使用 ・TLS 1.0/1.1は無効化 ・例(Nginx): ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on;
|
証明書の正当性の確保 | ・信頼できるCAからSSL/TLS証明書を取得 ・Let's Encryptも利用可能 ・証明書は定期的に更新 |
データの暗号化保存 | ・個人情報や支払い情報はAESで暗号化 ・例(Python): cipher = AES.new(key, AES.MODE_CFB, iv) encrypted_data = cipher.encrypt(data)
|
5.アクセス制御の不備
アクセス制御は、各ユーザーが利用できる機能やデータを制限する仕組みであり、適切に設定することでシステムの安全性を確保します。しかし、アクセス制御が不適切に実装されると、本来アクセスできないはずの機密情報にアクセスされたり、システムの不正利用を許してしまうリスクがあります。例えば、一般ユーザーが管理者権限の操作を実行したり、他のユーザーの個人情報を取得したりする可能性があります。
要件 | 仕様・実装詳細 |
---|---|
ロールベースアクセス制御(RBAC)の導入 | ・ユーザーに役割(例: 一般、管理者)を割り当て、操作やリソースごとに権限を定義 ・例: 一般ユーザー:閲覧・注文作成 管理者:商品追加・価格変更・ユーザー管理 |
最低権限の原則(PoLP)の徹底 | ・APIやDBへのアクセスに必要最小限の操作(SELECT, INSERTなど)のみ許可 ・DROPやALTERなどの操作は管理者に限定 |
デフォルトでアクセス拒否 | ・許可されていないリソースはすべて拒否する設定をデフォルトとする ・例(Python): return False # デフォルトで拒否
|
水平・垂直なアクセス制御の実装 | ・水平制御:ユーザーIDでフィルタして他ユーザーのデータを取得不可に 例: SELECT * FROM orders WHERE user_id = ?; ・垂直制御:管理者のみに更新処理を許可 例: if user.role != "admin": raise PermissionError()
|
アクセス制御のサーバー側での適用 | ・権限チェックはクライアント側ではなくサーバーで実施 ・例(Python): if request.user.role != "admin": return HttpResponseForbidden()
|
まとめ
Webアプリケーションは非常に便利ですが、その分、セキュリティリスクも潜んでいます。特に個人情報や取引データを扱うオンラインショッピングサイトなどは、攻撃者にとって魅力的なターゲットです。攻撃的セキュリティの視点からWebアプリケーションの脆弱性やリスクを理解し、基本的な防御策を学ぶ必要があります。
Discussion