Webシステムのセキュリティ周りを改めて調べてみた
まえがき
エンジニア歴が長い人はセキュリティ講習を受ける機会が数回あったりして、当たり前の知識が多いと思います。
しかし、技術は日々進歩していたり経験が浅いメンバーは知らないこともあると思うので、定期的に調べてみんなで認識を揃える機会は持ちたいところです。
ということで、2024-12-24ぐらいに調べた結果と具体的な対策を書きたいと思います。
攻撃手法と対策
XSS対策(Cross-site scripting)
手口
自分の投稿にJavaScriptコードを書いて、その投稿を見た人のブラウザでJavaScriptを実行する
対策
- フロント表示時に入力をサニタイズして表示する
- ライブラリ(例:DOMPurifyなど)を使用する
- Reactなどを使えばデフォルトでサニタイズ機能が付いている
- Content Security Policy (CSP)の導入
- HttpOnly Cookiesの使用
- 万が一突破された場合でもアクセストークンを盗ませないために設定する
- JavaScriptからのCookieへのアクセスが出来ない設定となる
- 万が一突破された場合でもアクセストークンを盗ませないために設定する
- local storageにアクセストークンは置かない(アクセスできてしまうため)
CSRF対策(Cross Site Request Forgery)
手口
リクエストに自動でcookieが付くことを利用して、他人のアカウントの操作ができる。
例)悪意のあるサイトに行くと自分がログイン中のサービスに勝手に投稿されちゃうとか。
対策
- Refererヘッダーの検証
- CORSの適切な設定
- 許可されたドメイン以外ではリクエストを送信できない
- CookieにSameSite属性の設定
- 同じドメイン以外ではcookieを送信しない
- CSRFトークンの利用
- 上記対策を入れれば不要にも思われるがセキュリティ対策は多層防御が基本なので入れたい
- トークン処理を入れないといけないし、開発時のリクエストにもトークン必須になるので面倒ではある
SQLインジェクション対策
手口
入力項目にSQLを書くことによって、本来取得できないデータが取得できてしまうなど。
対策
- RDBMSの場合、Prepared SQL Statementを使う
- NoSQLの場合は、サニタイズ処理を入れる
セッション固定攻撃への対策
手口
URLにセッションIDをつけて判定しているサービスで、自分がログインしてセッションIDを発行して、そのセッションIDが付いたリンクを他のユーザに踏ませて使わせる。
対策
- ログイン時にセッションIDを再発行し、古いセッションIDを無効にする
- セッションIDをURLパラメータではなくクッキーで扱う
- セッションの有効期限を適切に設定し、使い回しを防ぐ
SSRF(Server-Side Request Forgery)対策
手口
URLを入力できる項目にlocalhostなどを指定して、サーバ内部からしかアクセスできないリソースにアクセスさせる
対策
- 外部へのリクエストを制限し、ホワイトリスト方式で検証
- ユーザの入力URLを使用してサーバでリクエストしない
ディレクトリトラバーサル対策
手口
入力項目にファイルシステムを辿るパスなどを指定する
対策
- ユーザー入力をサニタイズする
- ユーザー入力をもとにファイルシステムにアクセスしない、パスを検証する
パスワードスプレー攻撃
手口
パスワード固定でアカウント名を変えてログインを試していく方法。
アカウントロックも回避できるし、ちゃんとアクセスログ監視を入れておかないと気づきづらい。
対策
- 多要素認証の導入
- ログイン方法をパスワード忘れた時の挙動でログインするようにする(パスワードレスログイン)
- Googleログインなどソーシャルログインを使う(丸投げスタイル)
- IDにメールアドレスなど公開されているものを使わない
- パスワードを複雑で長いものにする
- IPアドレスごとのレート制限の適用
- WAFの導入
キーロガーによるログイン情報取得
手口
ネットカフェなどで不特定多数が使うPCに対してキーロガーのハードウェアかソフトウェアを仕込んで置く。
そのPCでログインをした人のIDとパスワードが盗まれるという仕組み。
対策
- 多要素認証を使う
- 不特定多数が使うPCでログインしない
WIFIアクセスポイントに気を付ける
手口
カフェなどの無料のWIFIアクセスポイントの案内のところにシールなどを貼り付けて攻撃者の用意したアクセスポイントを使うように仕向ける
対策
- 信頼できないWIFIアクセスポイントでログインをしない
- HTTPSのサイトにアクセスした際に警告が出たらマン・イン・ザ・ミドル攻撃(MITM攻撃)だと思うこと
その他
- DNSキャッシュポイズニング
- ARPスプーフィング
- セッションハイジャック
- 辞書攻撃
- ブルートフォース攻撃
- マルウェア感染
- フィッシング攻撃
- スミッシング
- ソーシャルエンジニアリング
- クレデンシャルスタッフィング
とりあえず名前だけ上げておきます。めっちゃ多いですね💦
その他設定など
HTTPSとHSTSの導入
- HSTS(HTTP Strict Transport Security)の設定
- できるならHTTPSの暗号化方式にポスト量子暗号(PQC)を設定する
- TLS1.3を使用する
WAF(Web Application Firewall)の導入
- SQLインジェクションやクロスサイトスクリプティング(XSS)など、一般的なWeb攻撃からアプリケーションの保護機構もある
- アプリケーション層のDDoS攻撃に対する防御機能を提供しているサービスもある
- AWS WAFやCloudflareなど色々なサービスがある
- 特にDDoS攻撃を受けるとサイトがダウンするので設定はマストにしておきたい
Cookieのセキュアな設定
- HttpOnly属性の使用
- Secure属性の使用
- SameSite属性の設定
- 有効期限の設定
- ドメインは設定しない(サブドメインもアクセスできちゃうため)
- パスの設定する(/apiとかだけcookie送信できるようになる)
セキュリティテストツールの使用
OWASP ZAPやBurp Suiteなどのセキュリティテストツールを使用して、アプリケーションの脆弱性を検出できる
- 同僚曰く、OWASP ZAPは設定が大変らしいが、今だと生成AIとかにやってもらえば簡単かも?
アイデンティティ管理・認可制御の強化
- 多要素認証(MFA)の導入
- シングルサインオン(SSO)の実装
- ロールベースアクセス制御(RBAC)(Role-Based Access Control)
- 属性ベースアクセス制御(ABAC)(Attribute-Based Access Control)
定期的な脆弱性診断の実施
- 外部の診断サービスを使うのも良い
- ライブラリの脆弱性などもあるので、変更が無いWebシステムでも定期検診はしたほうが良い
OWASPが公開しているセキュリティ問題のトップ10も確認しておく
2021年がFIX最新。数年に一度公開されていて次回は2025年の公開予定しているっぽい。
Next.jsなど使うフレームワーク特有の問題も把握が必要
Next.jsを使ってシステム構築しているが、Next.jsでフロントもサーバも書く場合、コード境界が曖昧になるので、予期せぬコードや暗号鍵の流出などが心配となる。
下記に説明があるので読んでおくと良いが、複雑になったもんだとも思う。
Next.jsは、セキュリティが最大関心事であるならフロントだけの実装で使った方が良いと思う。
(フロントとバックエンドが同居していることによる開発速度向上の旨みは無くってしまうが。。。)
最後に
セキュリティに問題があると誰も利用してくれなくなるのでとても大事。
しかし、新規事業立ち上げ時は作ることで精一杯だし、ぱっと見動いているので軽んじられる。
さらに、
- 初期の頃からセキュリティ問題を見据えて、基盤を構築することは必要だがやっても評価されない
- 上の人から見るとセキュリティはしっかりしていて当たり前で工数なんて確保されない
- システム開発は変更がなければメンテしなくてよいイメージがある
- 最近は外部APIの変更などで変更しなくても壊れることもある。。。
とまぁ、大事だけどやる気にならないもので溢れている気もします。
個人的には、自分が開発したシステムがセキュリティ突破されたらダサくて恥ずかし過ぎるので、評価されなくても関係なくやる所存です。はい。
Discussion