はじめに
最近、自分でWebサービスを開発し、クラウド上で運営するようになりました。
実際にサービスをインターネットへ公開すると、
- WAFをどうするか
- DBをどこまで外部から隔離するか
- ログをどう残すか
- 不審なアクセスをどう検知するか
- 攻撃されたらどうするか
といった「作った後」のことを考えるようになります。
そんな中、2026年9月にタイムズカーがWebシステムへの不正アクセスと情報漏えいを公表しました。
公表された内容を読みながら、自分のWebサービスだったらどうするだろう、と考えてみました。
最初に思いついたのは、かなり単純なものでした。
「攻撃を検知したらDBを落としてしまえばいいのでは?」
ただ、考えていくと、DBを停止すること自体が目的ではありません。
本当に止めたいのは、
攻撃者からデータへ到達する経路
です。
そこで今回は、Webサービスに「非常停止」の考え方を取り入れられないか考えてみます。
「侵入されない」だけではなく「侵入された後」を考える
Webセキュリティというと、
- WAF
- Firewall
- IAM
- SQLインジェクション対策
- XSS対策
- 多要素認証
- パッチ適用
- 脆弱性診断
など、「侵入させない」対策を最初に考えます。
もちろん重要です。
しかし、どれだけ対策しても脆弱性を完全にゼロにできるとは限りません。
そこで設計段階から、
侵入される可能性をゼロにはできない。
ならば、侵入された後に被害を拡大させない。
という考え方を持っておく必要があるのではないでしょうか。
DBを落とすより「経路を切る」
単純化すると、一般的なWebサービスは次のような構成になります。
Internet
|
v
WAF / Load Balancer
|
v
Web / API
|
v
Database
通常、DatabaseをInternetへ直接公開する必要はありません。
Web/APIだけがDatabaseへ接続できる構成にします。
問題は、Web/API側が侵害された場合です。
攻撃者がアプリケーション経由でDatabaseへアクセスできれば、DBをPrivate Networkに置いていてもデータへ到達できる可能性があります。
そこで重大な異常を検知した場合、
Internet
|
v
WAF / Load Balancer
|
v
Web / API
|
X
Database
とする。
DBそのものをshutdownするのではなく、
Web/API → Databaseの経路を遮断する
という考え方です。
これならDatabase自体を残しながら、アプリケーションからのデータ流出を止められる可能性があります。
0か1ではなくSecurity Modeを作る
ただし、少し怪しいアクセスが来ただけで毎回サービスを完全停止していたら運営できません。
そこで、サービスの状態を段階化してみます。
NORMAL
|
v
RESTRICTED
|
v
READ_ONLY
|
v
ISOLATED
NORMAL
通常運転です。
Web/API -> READ/WRITE -> DB
RESTRICTED
不審なアクセスが増加した状態です。
例えば、
- Rate Limit強化
- 特定IPの遮断
- 特定APIの制限
- 認証要求の強化
- 管理系APIの停止
などを行います。
Web/API -> Limited Access -> DB
まだサービス自体は提供します。
READ_ONLY
さらに危険度が上がった場合です。
Web/API -> READ ONLY -> DB
例えば、
- 会員情報変更
- ファイルアップロード
- 管理機能
- バッチ更新
などを停止します。
ただし、情報漏えい対策としては注意が必要です。
READ ONLYは「改ざん防止」には有効でも、「情報流出防止」になるとは限りません。
データを盗む攻撃では、むしろSELECTが問題になるからです。
そのため、大量データ取得が疑われる場合にはREAD ONLYを飛ばしてISOLATEDへ移行する判断も必要です。
ISOLATED
重大な侵害が疑われる場合です。
Web/API
|
X
Database
DBへの接続そのものを遮断します。
サービス画面では、
現在メンテナンス中です。
しばらくしてから再度アクセスしてください。
などを表示します。
可用性を捨ててでも、情報保護を優先する状態です。
では、何をもって「異常」と判断するのか
ここが一番難しいところです。
単純に、
アクセス数 > 1000
なら停止、では正常ユーザーまで巻き込んでしまいます。
そこで、複数の指標を見る必要があります。
例えば、
Requests / sec
DB Queries / sec
SELECT rows / min
Download bytes / min
Authentication failures
API errors
Requests per user
Requests per IP
などです。
特に情報漏えい防止という意味では、
アクセス数より「どれだけデータが外へ出ているか」
を見る方が重要かもしれません。
「大量SELECT」を監視する
例えば通常のユーザーが1分間に取得するデータ量が、
10~100 records
程度だったとします。
ところが突然、
1,000
10,000
100,000
と増えた。
これは非常に分かりやすい異常です。
アプリケーション側で、
rows_returned_per_user
のようなメトリクスを持ってもよいでしょう。
さらに、
bytes_returned_per_user
を見る方法もあります。
正常なAPIを利用していても、大量にデータを抜き出そうとしていれば検知できます。
「入口」ではなく「振る舞い」を見る
ここで面白いと思うのが、攻撃そのものを判定しなくてもいいということです。
例えば、
同一ユーザー
+
短時間
+
大量APIアクセス
+
大量SELECT
+
大量レスポンス
という状態なら、
「これはSQL Injectionなのか?」
「アカウント乗っ取りなのか?」
「APIキーが盗まれたのか?」
を即座に特定できなくても、
正常ではない
とは判断できます。
だったら、
if abnormal_behavior:
security_mode = "RESTRICTED"
さらに危険なら、
if critical_behavior:
security_mode = "ISOLATED"
としてしまう。
攻撃手法の判定と、被害拡大防止を分けて考えるわけです。
自動停止には当然リスクもある
もちろん、
「怪しかったら自動的に止めればいい」
だけでは危険です。
攻撃者が大量リクエストを送るだけでISOLATEDへ移行できるなら、
攻撃者
|
大量アクセス
|
v
Security System
|
v
ISOLATED
となります。
これでは、セキュリティ機構そのものがDoS攻撃のスイッチになります。
そのため、
単一条件 -> Rate Limit
複数条件 -> RESTRICTED
重大なデータアクセス異常 -> ISOLATED
など、段階的な判定が必要でしょう。
自動遮断と人間の判断を組み合わせる
個人的には完全自動より、
異常検知
|
+--> 自動Rate Limit
|
+--> 管理者通知
|
+--> RESTRICTED
|
+--> Criticalなら自動ISOLATED
くらいが現実的ではないかと思っています。
つまり、
軽度の異常は自動防御、重大な異常だけ非常停止
です。
さらに管理者側には、
[ NORMAL ]
[ RESTRICTED ]
[ READ ONLY ]
[ ISOLATED ]
のような切り替えを用意しておく。
いわばWebサービスの非常停止ボタンです。
ISOLATEDにした後のことも設計しておく
実際には止めて終わりではありません。
むしろ、その後が重要です。
Detect
|
Contain
|
Preserve
|
Investigate
|
Recover
という流れを考える必要があります。
例えばISOLATEDへ移行したら、
- アプリケーションログ保存
- DB監査ログ保存
- Cloud Audit Log等の保存
- VM/DBスナップショット取得
- 認証情報のローテーション
- APIキー失効
- セッション失効
- 原因調査
- 脆弱性修正
- 復旧
と進みます。
つまり非常停止機構は、
インシデントレスポンスの入口
でもあります。
個人開発こそ自動防御が必要かもしれない
企業ならSOCや運用担当者がいる場合があります。
しかし個人開発では、
Developer
Infrastructure Engineer
SRE
Security Engineer
Operator
が全部自分です。
しかも24時間監視などできません。
寝ている間にもサービスは公開されています。
そう考えると個人開発ほど、
人間が見ていなくても安全側へ倒れる仕組み
が重要なのかもしれません。
「止めない」だけがインフラではない
インフラエンジニアとして仕事をしていると、
冗長化
Failover
Backup
Disaster Recovery
High Availability
など、「止めない」ための技術をたくさん扱います。
しかしセキュリティでは、
意図的に止める
という逆方向の設計も必要になります。
これは特別新しい発想というより、工学で昔から使われているフェイルセーフに近いと思います。
危険な状態になったら、
安全側へ倒す。
Webサービスでも、
異常を検知する
↓
アクセスを制限する
↓
機能を縮退する
↓
データを隔離する
という設計を最初から持っていてもよいのではないでしょうか。
まとめ
今回、自分でWebサービスを運営するようになり、タイムズカーの情報漏えい事案を見て考えたことは、
「侵入を完全に防ぐ」だけがセキュリティではない
ということでした。
重要なのは、
Prevent
+
Detect
+
Contain
+
Recover
まで考えること。
特に情報漏えいでは、一度外へ出てしまったデータを取り戻すことはできません。
だったら、
侵入されても被害を広げない。
さらに、
必要ならサービス自身が安全側へ止まる。
そんなWebサービス設計もありなのではないかと思います。
個人的には、自分のサービスでも、
NORMAL
RESTRICTED
READ_ONLY
ISOLATED
というSecurity Modeを実際に実装してみたいところです。
「落ちないシステム」だけではなく、
「必要なときに正しく止まれるシステム」も、良いインフラなのではないでしょうか。