多くの経営者が初めてセキュリティを真剣に考えるのは、サイトが改ざんされ、管理画面に不正ログインされ、ユーザーデータが一括ダウンロードされた後です。その時点でログを調査し、脆弱性を修正するコストは、最初から対策を講じておく場合よりもはるかに高くつくことが多いです。
正直なところ、Web開発でよくあるセキュリティ脆弱性のほとんどは、高度な技術ではなく、基本的な作業が徹底されていないことが原因です。以下では、実践で最もよく踏む落とし穴を一つずつ明確に説明します。
一、インジェクション系脆弱性:SQLインジェクションとコマンドインジェクション
SQLインジェクションは最も古典的な脆弱性です。原因は非常にシンプルで、プログラムがユーザー入力を直接SQL文に結合していることです。例えば、ログインフォームに巧妙に構成された文字列を入力すると、パスワード検証を回避でき、さらにはユーザーテーブル全体を盗み出すことも可能です。
一般的な対策と回避策:
- パラメータ化クエリやORMを使用し、文字列結合を手書きしない
- データベースアカウントは最小権限で割り当て、読み取り専用の業務には書き込み権限を与えない
- 本番環境の詳細なエラーメッセージを非表示にする。エラー情報自体が情報漏洩源となる
- 入力の型検証を行う。例えばIDは数字のみ許可する
コマンドインジェクションも同様です。画像処理やファイル生成のためにシステムコマンドを呼び出すスクリプト開発シーンでは、ファイル名を直接コマンドに結合すると、攻撃者が別の命令を実行できてしまいます。この種の問題は、管理システムで特に多く見られます。
二、権限と権限逸脱:ログインしているからといって権限があるわけではない
これは企業サイトや管理システムで最も過小評価されがちなカテゴリです。ユーザーは確かにログインしていますが、アクセスすべきでないデータにアクセスしています。
2種類に分けられます:
- 水平権限逸脱:一般ユーザーAがURLの注文番号を変更することで、ユーザーBの注文を閲覧
- 垂直権限逸脱:一般ユーザーが管理者APIに直接アクセス。例えばユーザー削除やデータエクスポート
具体的なシナリオ:ある予約系ミニプログラム開発プロジェクトで、APIは `/api/order/detail?id=1001` でした。フロントエンドは自分の注文のみ表示しますが、バックエンドはこの注文が現在のユーザーに属するか検証していませんでした。idを1002に変更するだけで、他人の電話番号や住所が見えてしまいます。
対策:
- データに関わるすべてのAPIで、「現在のユーザーがこのデータにアクセスする権限があるか」をサーバー側で検証する
- フロントエンドのボタン非表示に依存した権限制御を行わない
- 管理画面とユーザー側APIを分離し、認証ロジックを独立させる
三、ファイルアップロードとファイルインクルード
ファイルアップロード自体に問題はありません。問題は「アップロード後に実行できるかどうか」です。
よくある落とし穴:
- フロントエンドの拡張子のみ検証し、パケットキャプチャで変更すればPHPやJSPをアップロードできる
- アップロードディレクトリに実行権限があり、スクリプトをアップロードしてサーバーを掌握される
- ファイル名が予測可能で、攻撃者が総当たりでダウンロードできる
推奨される対策:
- サーバー側でファイルタイプを検証し、ブラックリストではなくホワイトリストを使用する
- アップロードディレクトリではスクリプト実行を禁止し、静的アクセスのみ許可する
- ファイルをリネームし、ランダム文字列を使用して元のパスを保持しない
- 画像ファイルは二次処理を行い、悪意のあるコンテンツが含まれる可能性を除去する
四、APIとビジネスロジックの脆弱性
多くの脆弱性はコードレベルではなく、ビジネスフローに存在します。例えば:
- SMS認証コードに回数制限がなく、ブルートフォース攻撃が可能
- 決済コールバックに署名検証がなく、「支払い済み」を偽造できる
- クーポンを同時に取得でき、一人で100枚取得できる
- パスワードリセットフローを回避し、他人のパスワードを直接リセットできる
この種の問題は、App開発やミニプログラム開発で特に注意が必要です。APIの露出面が従来のWebサイトより広いためです。「App内でAPIが見えなければ安全」と考える人も多いですが、実際にはパケットキャプチャツールを起動すれば、リクエストは明確に確認できます。
回避策:
- 重要なAPIにレート制限とリスクコントロールを追加する
- 決済や返金などの機密操作は、サーバー側での署名検証と二重確認を必須とする
- ビジネス状態の遷移はサーバー側で判断し、フロントエンドから送信された状態を信頼しない
五、依存コンポーネントと設定の問題
多くの企業サイトで問題が発生するのは、自分たちが書いたコードに穴があるからではなく、使用しているオープンソースフレームワークやプラグインのバージョンが古すぎるためです。
- サードパーティCMSやサイト構築システムが長期間更新されていない
- ミドルウェアのデフォルト設定が変更されておらず、管理画面の弱いパスワードやデフォルトポートが公開されている
- クラウドサーバーのセキュリティグループが広すぎ、データベースが直接インターネットに露出している
- テスト環境、バックアップファイル、.gitディレクトリが本番環境に同期されている
対策は非常にシンプルです:依存関係を定期的に更新し、リリース前に設定チェックを行い、公開すべきでないポートを閉じ、本番環境の不要なデバッグファイルを削除します。
MIC Studioに依頼すべきケース
プロジェクトが以下のいずれかに該当し、自社チームに体系的に調査する余力がない場合、専門チームにセキュリティテストを依頼する方がコスト効率が良いです:
- 企業サイトがリニューアル公開されたばかりで、会員、フォーム、決済が含まれる
- ミニプログラム開発やApp開発がテスト提出段階に入り、APIが多くロジックが複雑
- 管理システムが複数ロールの権限を持ち、権限逸脱リスクが高い
- リバーステストが必要で、APIの一括呼び出しやデータスクレイピングのリスクを評価する必要がある
- 既にセキュリティインシデントが発生し、原因の特定と強化が必要
MIC Studioのアプローチは、まず資産とAPIを整理し、次にインジェクション、権限、アップロード、ロジック、設定の各方向からテストを実施し、再現可能な問題リストと修正提案を提供することです。理解できないスキャンレポートを渡すだけではありません。
まとめ:すぐにできる3つのこと
1. リリース前に権限の自己チェックを行う:すべてのAPIをリストアップし、「ログインせずにアクセスできるか」「ユーザーIDを変更して他人のデータが見えるか」を一つずつ確認する。
2. 入力と出力を適切に管理する:すべてのユーザー入力を検証し、すべてのデータベース操作をパラメータ化し、すべてのエラーメッセージを外部に漏らさない。
3. セキュリティを継続的な活動とする:依存関係を定期的に更新し、設定を定期的に確認し、重要なバージョンのリリース前にセキュリティテストを実施する。問題が発生してから対処しない。
セキュリティは一度きりのプロジェクトではなく、開発プロセスの一部です。早めに考えておけば、後々のトラブルが大幅に減ります。
