Open1

ウェブ・セキュリティ基礎試験(徳丸基礎試験)④

445445

徳丸基礎試験勉強まとめ④

「体系的に学ぶ 安全な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なので設定不要

クッキーはどうやって盗むの?

  1. 罠サイト内のiframeのsrcに正規サイトのURL(パラメータにJSのコードを埋め込む)を指定
  2. ユーザーが正規サイトにログイン
  3. ユーザーが罠サイトにアクセス
  4. 罠サイト内のiframe内のJSコードが正規サイトで実行される

例えば上記のJSコードが、window.location=罠サイトのURL(パラメータにクッキーを指定)などの場合
罠サイトに正規サイトのクッキーがパラメータで渡ってしまう。
罠サイトは渡ってきたクッキーを罠サイト管理者にメール送信や、罠サイトDBに登録などでクッキーを盗むことができる

=> 対策:GETのパラメータを取得した時、パラメータ内の文字をエスケープする

  • 用語「反射型XSS」
    クッキーを盗む例のように、攻撃用スクリプトが正規サイト以外(罠サイトやメール)にある場合のXSSのこと
  • 用語「持続型XSS」
    攻撃用スクリプトが正規サイトにある場合(正規サイトDBにスクリプトが保存され、正規サイト内でスクリプトが展開される場合など)

クッキーを使うログイン機能のあるサイトだけ脆弱性対策すればいいの?

NO。全てのサイトで対策する必要がある

  • XSSで正規サイト画面を書き換えられてしまう場合がある

どうやって画面を書き換えるの?

  1. 罠サイトの属性値(input要素のvalue属性など)にHTML文字列を指定。Submitボタンをリンクに見せかけておく。actionは正規サイトURLを指定
  2. ユーザーが罠サイトのSubmitボタンを押す(リンクに見せかけてPOSTで属性値を送信)
  3. actionに指定された正規サイトURLに遷移する
  4. 正規サイトは、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

https://www.php.net/manual/en/class.pdo.php

  • 用語「プレースホルダ」
    下記の「?」のこと
SELECT * FROM books WHERE author = ?
  • 用語「動的プレースホルダ」
    アプリケーション内でSQLを組み立ててデータベースに送る

  • 用語「静的プレースホルダ」
    データベース内でSQL文を組み立てる