ウェブ・セキュリティ基礎試験(徳丸基礎試験)④
徳丸基礎試験勉強まとめ④
「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版」の4章の4.3、4.4を自分なりにまとめる
アドバイスや間違い指摘など歓迎です
4章 「Webアプリケーションの機能別に見るセキュリティバグ」
4.3 表示処理に伴う問題
表示処理が原因でなにが起こるの?
- XSS: クロスサイトスクリプティング(サーバー側処理)
- エラーメッセージからの情報漏洩
XSS(Javascript処理)は4.17で扱う
XSSがあるとどんな影響があるの?
- クッキーを盗まれ、なりすましされる
- サイトのアプリ機能を悪用される
- 個人情報を盗まれる
XSSの対策は?
- 属性値(input要素のvalue属性など)をダブルクオート(””)で囲んで(", <, &など)をエスケープ
- HTMLで特別な意味を持つ記号文字(<, &)をエスケープ
- レスポンスヘッダにContent-type: text/html; charset=UTF-8など文字エンコーディングを指定
- レスポンスヘッダにX-XSS-Protectionを追加(X-XSS-protection: 1; mode=block)
- 入力値検証
- クッキーにHttpOnly属性を付与(Javascriptからクッキーにアクセスできないようにする)
- TRACEメソッド無効化
PHPでエスケープにはhtmlspecialchars関数を使用する。
関数のクオートスタイルはENT_QUOTES(シングルクオート、ダブルクオートどちらもエスケープするオプション)を指定するのが望ましい
-
用語「XSSフィルタ」
反射型XSSをブラウザが検知し無害な出力に変更する機能(ブラウザに実装されている)
X-XSS-Protectionをレスポンスヘッダに追加することで、ブラウザのXSSフィルタ設定を強制でONにする -
用語「TRACEメソッド」
古いブラウザにはクロスサイトトレーシング(XST)攻撃ができる。これはJSでHTTPのTRACEメソッドを送信することでクッキーやBasic認証のID、パスワードを盗む手法
Apacheの場合、httpd.confにTraceEnable Off設定を記載。nginxはデフォルトでOffなので設定不要
クッキーはどうやって盗むの?
- 罠サイト内のiframeのsrcに正規サイトのURL(パラメータにJSのコードを埋め込む)を指定
- ユーザーが正規サイトにログイン
- ユーザーが罠サイトにアクセス
- 罠サイト内のiframe内のJSコードが正規サイトで実行される
例えば上記のJSコードが、window.location=罠サイトのURL(パラメータにクッキーを指定)などの場合
罠サイトに正規サイトのクッキーがパラメータで渡ってしまう。
罠サイトは渡ってきたクッキーを罠サイト管理者にメール送信や、罠サイトDBに登録などでクッキーを盗むことができる
=> 対策:GETのパラメータを取得した時、パラメータ内の文字をエスケープする
- 用語「反射型XSS」
クッキーを盗む例のように、攻撃用スクリプトが正規サイト以外(罠サイトやメール)にある場合のXSSのこと - 用語「持続型XSS」
攻撃用スクリプトが正規サイトにある場合(正規サイトDBにスクリプトが保存され、正規サイト内でスクリプトが展開される場合など)
クッキーを使うログイン機能のあるサイトだけ脆弱性対策すればいいの?
NO。全てのサイトで対策する必要がある
- XSSで正規サイト画面を書き換えられてしまう場合がある
どうやって画面を書き換えるの?
- 罠サイトの属性値(input要素のvalue属性など)にHTML文字列を指定。Submitボタンをリンクに見せかけておく。actionは正規サイトURLを指定
- ユーザーが罠サイトのSubmitボタンを押す(リンクに見せかけてPOSTで属性値を送信)
- actionに指定された正規サイトURLに遷移する
- 正規サイトは、POSTで送信された属性値を取得し、HTML文字列が展開される(ここで画面が書き換えられる場合がある)
=> 対策:POST
上記XSSの場合はJSを埋め込むのではなくHTML文字列を埋め込む。
なのでXSSは常にJSを使用するわけではない!注意!!
その他危ない場所って?
- 属性値(url)
- a要素のhref属性、img&frame&iframe要素のsrc属性はurlを属性値としてとる
- これらはURlとしてjavascript:Javascript式(javascriptスキーム)でJSを起動できる
- 対策としては属性値としてのエスケープを行った上で、「入力値がURLの形式をとっているか、外部URLではないか、外部URLなら利用者に注意喚起するクッションページを表示する」などが挙げられる
- イベントハンドラ(onloadなど)
- 文字列を動的生成する場合、HTMLエスケープの前に、JS文字列リテラルとしてのエスケープが必要
- JS文字列リテラルとしてのエスケープ:バックスラッシュ()、シングルクオート、ダブルクオート、改行をエスケープ
- Script要素内部
- 文字列を動的生成する場合、JS文字列リテラルとしてのエスケープ+ </scriptという文字列が出現しないようにする
- カスタムデータ属性の取得によってHTMLエスケープを行う(属性値としてのエスケープを行ったカスタムデータ属性値をScript内部で取得)
- インラインJSONPによる方法(JSONでエンコードすることでエスケープされる)
エラーメッセージからの情報漏洩って?
- エラーメッセージにアプリケーションの内部情報が表示される
- エラーメッセージに個人情報などが表示される
詳細のエラーはログに出力し、本番環境では詳細のエラーメッセージを表示しないように設定する
PHPではphp.iniにdisplay_errors=Offを設定しておく
4.4 SQL呼び出しに伴う脆弱性
SQL呼び出しが原因でなにが起こるの?
- SQLインジェクション
SQLインジェクションがあるとどんな影響があるの?
- データベース内の情報を盗まれる
- データベースの内容が書き換えられる
- 認証回避される(IDとパスワードなしでログインされる)
- データベースサーバー上のファイルの読み書きやプログラムの実行など
SQLインジェクションの対策は?
-
プレースホルダによるSQL文組み立て
-
PDOの安全な利用
- PDOで例外処理(PDO::ATTR_ERRMODE = PDO::ERRMODE_EXCEPTION)
- 復文(;で区切った複数のSQL文)の実行を禁止(PDO::MYSQL_ATTR_MULTI_STATEMENTS = false)
- 静的プレースホルダを指定(PDO::ATTR_EMULATE_PREPARES = false)
-
ワイルドカードのエスケープ (SQLでは、_ => #_, % => #%, # => ##)
-
詳細のエラーメッセージを表示しないように設定
- PHPではphp.iniにdisplay_errors=Offを設定しておく
-
入力値の妥当性検証
- 数字のみ許可、英数字のみ許可など
- ただし、コメント欄など文字種制限のない入力には効果なし
-
データベースの権限設定
- 読み出しのみアプリケーションに権限を与えるなど
- ただし、アプリケーションに多くの権限が必要な場合には効果なし
-
用語「リテラル」
SQL文中で決まった値を表すもの。
author='O'Reilly' なら、Oがリテラル、Reillyがリテラルをはみ出した部分 -
用語「PDO」
PHP Data Objects
第四引数にはオプションが入る
オプションの例
オプション | 意味 | デフォルト値 |
---|---|---|
PDO::ATTR_ERRMODE | PDOエラーモード | PDO::ERRMODE_SILENT |
PDO::MYSQL_ATTR_MULTI_STATEMENTS | 復文の実行を許可 | true |
PDO::ATTR_EMULATE_PREPARES | 動的プレースホルダを使用 | true |
- 用語「プレースホルダ」
下記の「?」のこと
SELECT * FROM books WHERE author = ?
-
用語「動的プレースホルダ」
アプリケーション内でSQLを組み立ててデータベースに送る -
用語「静的プレースホルダ」
データベース内でSQL文を組み立てる