log

安全なwebアプリケーションの作り方 68-118

  • 脆弱性は処理起因と出力起因がある:出力起因の脆弱性インジェクションってつくことがおおい
    • XSS も HTML インジェクションとか JavaScript インジェクションって呼ばれる時がある。
      • {XSS / HTTP ヘッダ / SQL / OS コマンド / メールヘッダ } インジェクションとか。
      • 機能との関連性が強いから、設計とかコーディングの段階で注意するところはわかる
  • 入力に起因するものはない!←アプリケーションだとないけど、ミドルウェアだと可能性がある
  • SQL インジェクション
  • 入力データの検証:文字エンコーディングの検証
    • 言語側に脆弱性あるとか、正しくコーディング出来てないときにヤバイ
  • 入力データの検証:文字エンコーディングの変換
    • HTTPメッセージとコード内部で文字エンコーディングが異なるときにやる。自動でやってくれたり明示的に変換したりする言語がある。
    • 文字エンコーディングを変換すると、不正なのは削除、?とかは別の文字に置き換えられるから、自動変換使ったら楽だし危険になるわけでもない!→ただ文字化けとか怒っても気づかない可能性がある
  • 入力データの検証:入力値の検証
    • 検証しないと、(1)数字だけのところに変なの入れてこわれる (2) データベースの不整合 (3) なんか間違えて入力したとき、全部入れ直す必要があってめんどくさい (4) メアド入れてないのにメール送ろうとしてこわれる とかが起こる
    • つらいことを防ぐために検証したい。でも検証するのは書式チェックだけだからエラーは防げないけど、早期発見出来るから総合的にアド
  • バイナリセーフ
    • 入力値がどんなバイト列であっても、値ゼロのバイトが現れても正しく処理出来るかどうか
    • C/Unix/Windows とかだと文字列の終端に見なせるのでこわれる→バイナリセーフでない関数
    • ヌルバイト攻撃というらしい、他の脆弱性の対策を回避するために使うこともあるらしい。  NULLバイト攻撃への対策(ヌルバイトアタック) - Qiita  脆弱性の対策を回避するためのアレ見つけられなかった。!!!誰か教えて!!!
      • \0 対策は \0 に気を遣う or 間に \0 入ってても問題なく取り扱える実装を使おう以外にない thanks:sora_h
  • 入力値検証
    • これだけでは脆弱性対策にはならない!
    • アプリケーションの仕様によって変えるべき。制御文字/文字数のチェック
  • 検証する対象

  • XSSの影響
    • なりすまし
    • webアプリケーションの機能の悪用
    • フィッシング
  • 対策するところが多いのに、影響を軽視しがち!よくない!!!攻撃も被害もいっぱいあるから対策しろ!!!
  • 基本的な対策は、メタ文字をエスケープすること?
  • 攻撃手法:Cookie値の盗み出し
    • 外部からのJSでセッションIDの読み出しが出来る
    • 実際は脆弱なサイトの利用者を誘導して、iframe (前やったやつ!)でデータを盗む
  • 攻撃手法:JavaScriptによる攻撃
  • 攻撃手法:画面の書き換え
    • ログイン機能のないものでもXSS脆弱性は影響がある。ボタンをリンクに見せかけたりして、元のフォームを隠して攻撃元にデータが送られる。formのaction属性が罠サイトに変えられる。
    • !!!!! 見破る手がかりがない !!!!! ←どうするの?
  • 攻撃用JSが対象と別のサイトにあるやつ:反射型XSS reflected XSS
    • 入力値をそのまま表示するときとかに使われる
  • 攻撃用JSが対象のデータベースに保存されてるやつ:持続型XSS stored XSS / persistent XSS
    • webメールSNSとかに。ユーザを誘導する手間がかからないこと、気をつけてるひとも引っ掛けやすいのがよい◎
  • 脆弱性が生まれる原因
    • HTML生成の時にメタ文字をちゃんとエスケープしないのが原因
  • XSS対策の基本
    • 要素内容については、「<」と「&」をエスケープする
    • 属性値については、ダブルクォートで囲って、「<」と「”」と「&」をエスケープする
  • レスポンスの文字エンコーディング指定
    • webアプリ側とブラウザで文字エンコーディングが違うとXSSの原因になるので、↓みたいに指定しちゃうと楽で確実っぽい!
    • header('Content-Type: text/html; charset=UTF-8
  • XSSに対する保険的対策

  • まとめ!
    • 必須対策(個別)
      • 要素内容:htmlspecialchars とかでエスケープ
      • 属性値:htmlspecialcharsでエスケープしてダブルクォートで囲む
    • 共通対策
    • 保険
      • 入力値を検証
      • Cookie に HttpOnly 設定する
      • TRACE メソッドを無効化する

  • href, img, frame, iframe の src とかはURLを属性値としてとるから、ちゃんと対策しないとJavaScript起動できる。
    • HTMLのエスケープとか関係ないから、対策の方法が違う
    • リンク先URLを検証する/外部ドメインであることのクッションページをつける
    • JavaScript文字列リテラルとしてエスケープ→HTMLエスケープする。最低でも、\, ‘, “, 改行はエスケープすべき!
    • →でも入力文字列に</script>が入ってると、自分で別のscriptを埋め込めるので危ない。HTMLの規格ではこの書き方ダメになってるよ
  • !!!!!!JavaScriptを動的生成するのは避けたほうが良い!!!!!!
    • でも動的なパラメータをわたしたいときはいっぱいある
    • Unicodeエスケープ:英数字以外を全部エスケープする
    • script要素の外部でパラメータ定義して参照する
    • JS動的生成は避けて body タグに data-* 属性で持たせるとか meta タグにするとかが流行ってそう。 thanks:sora_h
  • つまづいたところ p.114
    • <script>の外、例えばinput type=“hidden”でファイルの上らへんにパラメータを書いておいて、<script>からは変数を呼び出すみたいな感じ?
    • 感覚的にはグローバル変数っぽいんだけど、どうなんだろう?定義の場所が離れるから読みづらいとかもそれっぽい
  • DOM based XSS
    • URL で script とか書くことで攻撃出来る、生成されたHTMLには攻撃者のJSは入らない
    • JS の標準関数にはHTMLエスケープないので、jQueryでエスケープするとよい!
  • ブログシステムとかSNSとか、ユーザがHTML書くやつは信用ならんので、構文解析したいけどむずい→なんか便利な強そうなライブラリがある、PHPだとHTML Purifierがあるらしい
  • エラーメッセージから情報漏えいする可能性があるし、ちゃんとログに出力してユーザには見えないようにするべき(秘密の国のアリスでもやってた)

  • 新規開発でXSS対策するのは比較的楽だが、後から対策するのは!!激ムズ!!だから、最初からちゃんとした設計をしよう