「安全なウェブサイトの作り方」を読む
Details
IPA が公開している資料の一つに、「安全なウェブサイトの作り方」がある。
これをよんでいく。
はじめに
- 2015年時点で日本におけるインターネット利用者は1億人を超え、なお拡大し続けている
- 一方、ウェブサイトの脆弱性を狙った事件も増加している
- 2020年末時点で累計11,526件が報告されている
- なので、既存の脆弱性から学び、対策していこうね
本書の構成
以下の三部構成。
- ウェブアプリケーションのセキュリティ実装(各種インジェクション対策など)
- ウェブサイトの安全性向上のための取り組み(主に運用面)
- 既存の失敗例
前章:脆弱性対策について
ここでは、脆弱性への対策を2つに分類してある。
- 根本的解決
- 脆弱性を作りこまない実装を行うこと
- 保険的対策
- 攻撃による影響を軽減するための対策のこと
- 攻撃される可能性を下げる
- 攻撃された際、脆弱性を突かれる可能性を下げる
- 脆弱性を突かれた際、発生する被害を少なくする
- 被害を早期に発見する
- 攻撃による影響を軽減するための対策のこと
ウェブアプリケーションのセキュリティ実装
ここでは以下の11パターンが取り上げられている。
1) SQL インジェクション
2) OS コマンド・インジェクション
3) パス名パラメータの未チェック/ディレクトリ・トラバーサル
4) セッション管理の不備
5) クロスサイト・スクリプティング
6) CSRF(クロスサイト・リクエスト・フォージェリ)
7) HTTP ヘッダ・インジェクション
8) メールヘッダ・インジェクション
9) クリックジャッキング
10)バッファオーバーフロー
11)アクセス制御や認可制御の欠落
1.1 SQL インジェクション
Webサービス内部で使用されているSQLを悪用し、外部から意図しない情報を引き出したり改ざんしたりすること。
比較的発生件数が多く、全届出件数の11%を占めている(届出開始~2014/第四四半期)。
対象となるウェブサイト
データベースを使用しているウェブサイト全般。
発生しうる脅威
- データベースに存在する非公開情報の閲覧
- 例:他ユーザーの個人情報が漏洩する
- データベースに存在する情報の改ざん、消去
- 例:ページの改ざん、パスワードの変更、システム停止
- 認証を回避することによる不正なログイン
- 例:非ログイン状態で投稿を行う
- ストアドプロシージャなどを介したOSコマンドの実行
- 例:システムの乗っ取り、踏み台攻撃での利用
根本的解決
-
SQL 文の組み立てはすべてプレースホルダで実装する
- 式の中に値をはめ込む部分を記述し、値はあとからはめ込む形式のこと
- ほとんどの SQL が対応している(例:PostgresSQL)
- 静的プレースホルダ:SQL とパラメータを別々に送信し、データベース上で組み立てる
- 動的 〃 :呼び出し元のライブラリなどで組み立て、データベースに送信する
- ライブラリによって無害化されたクエリを、しばしば Prepared Statement(準備された文) という
-
SQL 文の組み立てを文字列連結により行う場合は、エスケープ処理等を行うデータベースエンジンの API を用いて、SQL 文のリテラルを正しく構成する
- 訳:クエリ中の可変な値はちゃんと無害化してから入れてね
- 文字列:シングルクォート(')とか危険な文字はエスケープ処理(「'」→「"」)して入れる
- 数値:型チェックとかで数値リテラルであると確定させる
- 訳:クエリ中の可変な値はちゃんと無害化してから入れてね
-
ウェブアプリケーションに渡されるパラメータに SQL 文を直接指定しない
- 「論外の実装」って書いてあった(当たり前)
- ユーザーがSQLを指定する形式には絶対しないこと
- hidden に入れてたとしてもダメ!改変の可能性がある
- ユーザーにSQLを意識させないように実装されるべき
保険的対策
-
エラーメッセージをそのままブラウザに表示しない
- エラーを細かく教えてしまうと、SQLインジェクションに繋がる有益な情報となる
- 利用者のブラウザには表示しないのが好ましい
-
データベースアカウントに適切な権限を与える
- アプリケーションの権限を不要に上げている場合、被害が深刻化する恐れがある
- サービスの運用に必要な最低限の権限のみを付与するべき
届出例
- 「サイボウズ ガルーン」における SQL インジェクションの脆弱性
- ファイルのダウンロード処理に SQL インジェクションを可能とする脆弱性が発見された
https://jvndb.jvn.jp/jvndb/JVNDB-2014-000024
- ファイルのダウンロード処理に SQL インジェクションを可能とする脆弱性が発見された
OS コマンド・インジェクション
Webアプリケーションを介して、アプリを起動しているサーバのOSコマンドを不正に実行すること。
Perl による Web アプリケーションや、組み込み製品の管理画面で用いられる CGI[1] からの報告が多い。
対象となるウェブサイト
サービスの性質を問わず、外部プログラムを呼び出すような関数を使用するアプリケーション(例:eval()
)。
発生しうる脅威
- サーバ内ファイルの閲覧、改ざん、削除
- 不正なシステム操作
- 不正なプログラムのダウンロード、実行
- 他システムへの攻撃の踏み台
根本的対策
-
シェルを起動できるような言語機能を使用することを避ける
- 例:Perl の
open
関数は、ファイルパスに「|」(パイプ)を使用することで- 後続して書かれた OS コマンドを実行できる
- この場合、
sysopen
で代用すればシェルは起動しない
- 迂回策があれば、そちらを使用するのがベスト
- 例:Perl の
保険的対策
-
シェルを起動できる機能を利用する場合、引数を構成する変数すべてに対してチェックを行う
- 本来想定している動作のみを許可し、他はすべて弾くように実装する(ホワイトリスト方式)
- 攻撃に悪用される記号文字(「|」、「<」、「>」等)を弾く(ブラックリスト方式)
- こちらは漏れが出るため、あまりおすすめしない
届出例
- 「Usermin」における OS コマンド・インジェクションの脆弱性 https://jvndb.jvn.jp/jvndb/JVNDB-2014-000057
-
WebサーバーがWebブラウザなどからの要求に応じてプログラムを実行する仕組み ↩︎
1.3 パス名パラメータの未チェック / ディレクトリ・トラバーサル
webアプリケーションの中には、直接ファイル名を指定しているものがある(例:http://hoge.com/hugahuga.xml
などのURLを受け付ける)。これを処理する実装に問題がある場合、攻撃者に任意のファイルを指定され、意図しない挙動を許すことがある。こうした挙動の一種を 「ディレクトリ・トラバーサル」 と呼ぶ。
対象となるウェブサイト
サービスの性質を問わず、外部から指定できるパラメータにファイル名を直接指定しているアプリケーション。
発生しうる脅威
- サーバ内ファイルの閲覧、改ざん、削除
根本的解決
- 外部からのパラメータでファイル名を指定する実装を避ける
-
ファイルを開く際は固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれるようにする
- パラメータに絶対パス名を指定することで、任意ディレクトリのファイルが開けてしまう場合がある
open(filename) // 絶対パスだと任意ファイルが開けてしまう!
- これを避ける実装として、固定のディレクトリ + ファイル名 でファイル名を指定するようにする
open(dirname + filename) // dirname を固定して絶対パスを対策する
- ただし、
../
などで迂回される
- ただし、
- パス名からファイル名のみを取り出す API を使用する(最善)
- 例:PHP の
basename()
open(dirname + basename(filename))
- 例:PHP の
- パラメータに絶対パス名を指定することで、任意ディレクトリのファイルが開けてしまう場合がある
保険的対策
- webサーバ内のファイルへのアクセス権限の設定を正しく管理する
- ファイルへのアクセス権限を正しく設定することで
- 想定外のアクセスが発生しても、読み込まれることがない
- ファイル名のチェックを行う
-
/
../
..\
等、ディレクトリを指定できる文字列を事前に弾く- ただし、これも完全ではない
- URL エンコードにより、誤って通してしまう場合がある
- 例:
/
-> エンコードすることで%2F
になる - デコード後にチェックするようにする
- 例:
-
届出例
「Spring Framework」におけるディレクトリ・トラバーサルの脆弱性 https://jvndb.jvn.jp/jvndb/JVNDB-2014-000054