🔐

安全なWebサイトを作ろう!②

2024/03/08に公開

ごあいさつ

こんにちは!
オアシステクノロジーズの古本です。

今日はWebアプリケーションを構築する上でめちゃめちゃ重要な「セキュリティ」に関する話題です。

この記事の続きです
https://zenn.dev/oasys/articles/ece3f1f78e8222

ウェブページのセキュリティ実装

パス名パラメータの未チェック/ディレクトリ・トラバーサル

まずはディレクトリ・トラバーサルから見ていきましょう。

セキュリティリスク

ウェブアプリケーションの中には、外部からのパラメータにウェブサーバ内のファイル名を直接指定しているものがあります。このようなウェブアプリケーションでは、ファイル名指定の実装に問題がある場合、攻撃者に任意のファイルを指定され、ウェブアプリケーションが意図しない処理を行ってしまう可能性があります。

簡単に言うと、入力値を使ってユーザが自由にファイルを参照できるよ!ってことですね。

個人情報を含むようなセキュリティレベルの高いファイルは、適切なユーザしかアクセスできないようにしたいですよね。
そんな時に例えばユーザが入力したディレクトリやファイル名に基づいてファイルを取得するような処理になっていると、結局誰でもどんなファイルでもアクセスできちゃうって状況が生まれるわけです。

解決策としては以下の2点があります。

解決策

  1. 外部からのパラメータでウェブサーバ内のファイル名を直接指定する実装を避ける。
    じゃあどうやってファイルを特定するの?って言うのが課題になりますが、よくある方式としては「ファイル管理テーブル」を作ってDBの情報をもとに適切な認可を行ってファイルの場所を特定するって方法です。

  2. ファイルを開く際は、固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれないようにする。
    これもファイル管理テーブルを利用したアクセスにすれば解決ですね。
    皆さんもシステム開発においてファイル管理テーブルを使ってもらっていると思いますが、こういう目的なんですね。

結論

ファイルアクセスはファイル管理テーブルを使って認可&パスを特定しましょう

ファイル管理テーブルの構造はシステムごとにいろいろあると思いますが、基本的には以下のような項目があると思います。

  • ID
  • 保存先パス、ファイル名
  • 元のファイル名
  • サイズ
  • MIMEタイプ
  • 作成日時
  • 削除日時

つまり、ファイルの実体を抽象化したようなイメージです。
またセキュリティとは少し違う観点ですが、ファイルのライフサイクルとDBのトランザクションは異なるため、それらを適切に分離する意味でも非常に便利なテーブルになります。

セッション管理の不備

セキュリティリスク

ウェブアプリケーションの中には、セッション ID(利用者を識別するための情報)を発行し、セッション管理を行っているものがあります。このセッション ID の発行や管理に不備がある場合、悪意のある人にログイン中の利用者のセッション ID を不正に取得され、その利用者になりすましてアクセスされてしまう可能性があります。この問題を悪用した攻撃手法を、「セッション・ハイジャック」と呼びます。

バックエンドのアプリ開発をしてると、セッションって言葉はよく耳にすると思います。
ただ、セッションの意味を正しく理解していない人が結構いるなーって印象です。

セッションというのは一連の操作をしている人が同じだよね!っていうのを検証する仕組みです。
その仕組みを利用して、バックエンドで一時的にデータを保持したりすることができます。これはセッションデータって呼ぶことが多いですね。

じゃあそれはどうやって実現されているのか、ですがこれもいくつかの方式があります。
代表的なものとしてはCookieにセッションを特定するためのキーをもつって方式です。

みなさんデベロッパーツールでCookie見てみてください。
多分SESSIONっていう名前が含まれる項目名が見つかると思います。
ここにはセッションを特定するためのキーが入っており、Cookieなのでリクエスト時にリクエストヘッダに含まれるわけですね。
バックエンドではキーバリューストアみたいなイメージで、このセッションに紐づく情報をDBだったりRedisだったりにもっています。
リクエストヘッダーのセッションIDから、バックエンドで管理しているセッションデータを特定し、認証されたユーザは誰なのか?とかを判断するわけですね。

ここで、セキュリティリスクの登場です。
セッションIDが漏洩しちゃうと、そのセッションIDを利用して「なりすまし」ができちゃうってことなんですね!

解決策

  1. セッションIDを推測が困難なものにする。
  2. セッションIDをURLパラメータに格納しない。
  3. HTTPS通信で利用するCookieにはsecure属性を加える。
  4. ログイン成功後に、既存のセッションIDとは別に秘密情報を発行し、ページの遷移ごとにその値を確認する。

結論

これはもう先に結論を言っちゃいます

フレームワークに任せよ

このあたりは代表的なセキュリティリスクとしてフレームワークがサポートしてくれることがほとんどです。
カスタマイズすることでセキュリティホールがうまれることもあるので、詳しく仕組みがわからない状態だといじらないほうが懸命ですね。。

クロスサイト・スクリプティング

セキュリティリスク

ウェブアプリケーションの中には、検索のキーワードの表示画面や個人情報登録時の確認画面、掲示板、ウェブのログ統計画面等、利用者からの入力内容や HTTP ヘッダの情報を処理し、ウェブページとして出力するものがあります。ここで、ウェブページへの出力処理に問題がある場合、そのウェブページにスクリプト等を埋め込まれてしまいます。この問題を「クロスサイト・スクリプティングの脆弱性」と呼び、この問題を悪用した攻撃手法を、「クロスサイト・スクリプティング攻撃」と呼びます。

これは以前照会したSQLインジェクションとかOSコマンドインジェクションと同じようなものですね。
適切にエンコードしましょうねーっていうのが基本的な方針ですが、CMSやリッチな掲示板などで入力されたHTMLをそのまま表示したい!って場合もあるが悩ましいところです。

解決策

  1. <script></script>の入力を許可しない
  2. スタイルシートを任意のサイトから取り込めるようにしない。
  3. Cookie情報の漏えい対策として、発行するCookieにHttpOnly属性を加え、TRACEメソッドを無効化する。
  4. クロスサイト・スクリプティングの潜在的な脆弱性対策として有効なブラウザの機能を有効にするレスポンスヘッダを返す。

結論

1. 不要な入力値を使った画面描画は行わない。
2. ブラウザの機能を適切に利用する。

1は言わずもがなですね!
2はXSSだけでなく、X-XSS-ProtectionやContent Security Policyなど、レスポンスヘッダを指定することでセキュリティ対策をブラウザに移譲できるものもあります。
そのあたりの仕組みを上手く使って俯瞰的にセキュリティリスクの排除ができているかを検討していくことが重要です。
ただし、2はブラウザやバージョンごとに対応済みであるかどうか差があったりするので、リスクを移譲する限りはどこまでサポートされているのかは確認が必要ですのでご注意ください!

まとめ

特にコンシューマ向けのサービスなど、不特定多数が利用するシステムの場合には性悪説で考えてリスク管理することが重要です。
意外と知らない人が多かったので、他の章も継続してお勉強していこうと思います。

本日は以上!

Discussion