log

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

  • メール送信の問題
    • メールヘッダインジェクション脆弱性
      • HTTPヘッダインジェクションと同じで改行入れることで新しいフィールド入れたり本文改ざんすること
    • hiddenパラメータによる宛先保持
      • 無料提供されるメール送信用フォームについては、楽をするためにhiddenパラメータで送信先指定してたりして、任意のアドレスに変更出来てヤバイ
      • <input type=“hidden” name=“mailaddr” value=“root@example.com” みたいなことがされてたりすると改ざんし放題
      • ハードコーディングとか、サーバの安全な場所に保存すべき
    • メールサーバによる第三者中継
      • 第三者のサーバを中継してメールを送ることがあって、いくら相手をブロックしてても意味がない
      • 最近のMTAはデフォルトで許さない設定になってるけど、 RBL.JP とかいうところでチェック出来るので一応するべき

  • メールヘッダインジェクション脆弱性
    • 影響:件名送信元本文の改変/迷惑メールの送信に悪用/ウイルスメールの送信に悪用
    • メール送信専用のライブラリを使用した上で、外部からのパラメータをヘッダに含まない / 改行を含まないようにする必要がある
  • 宛先の追加:メアド宛先欄をtextareaとかにして、宛先のあとに改行してBcc:bob@example.comみたいなことを入れると送れたりする。bcc以外に、cc, to, reply-to などが追加できる。subject も追加出来るけど、もともとのとどっちが採用されるかは処理系依存
  • 本文の改ざん:Fromに改行を挟んで本文を記述すると、追加したメッセージがメールに追加されてる。明らかに怪しいので、改行たくさんいれてごまかしたりMIME使って隠したりする。
    • MIME? ←どうやって隠すの
  • 添付ファイルをつける:ウイルスファイルを添付したりできる。MIMEのmultipart/mixedという形式を悪用したもの。ウイルス対策ソフトとかだと削除されたり差し替えられたりする。 MIMEデリミタ注入攻撃 これ、↑の本文隠したりもできるんかな?
  • 脆弱性の生まれる原因:まずメールの形式を知ろう f:id:lullasy:20170104222919j:plain
    • 表作るのめんどいから手書きで
    • よく用いられるsendmailコマンドとか、ライブラリの多くはヘッダから送信元アドレスを抽出する
    • なんとなく思ってたけど、HTTPヘッダインジェクション脆弱性と似てるよね?って思ってたら似てるらしい。フィールドが改行で区切られてるから、外部からのパラメータで改行追加できたら†死†
    • 改行には「特別な意味」があるんだけど、アプリケーションがチェックしてないときは本当にやばいので、やばい。太古はCGIプログラムからメール送信するときは自分でsendmailしたりしてたので脆弱性の塊だった。そういえば昔自分のHPで似たようなことしてたな………うっ頭が
  • 対策:専用ライブラリを使う!!!
    • その上で、外部からのパラメータをヘッダに含まない / 改行を含まない
    • 専用ライブラリは(1) sendmailは組み立てをアプリケーションが全部責任持つので脆弱性がやばい (2) OSコマンドインジェクションが起こりやすい (3) まず、専用ライブラリで解決されるべき
    • でも専用ライブラリを使った上で対策するのは、やっぱりそれでも脆弱性がみつかっているため。
    • プラスアルファ対策:外部からのパラメータをヘッダに含まない
      • まずメールヘッダに入れなければ起こらない。管理者宛のメール(お問い合わせなど)ならFromは固定してあげる。
    • プラスアルファ対策:改行を含まない
      • メール送信のタイミングでチェックを走らせるとよい◎
      • mb_send_mailとかのライブラリ関数を呼ぶ……のではなく、ラッパー関数を用意して改行文字チェックするのがよい。フレームワークが提供するライブラリに改行チェック組み込むのもよさげ?でもこれ、ライブラリいじるのなんかちょっと怖いから別関数としてラッパー用意したい気持ちみがある。
    • 保険的対策
      • 入力値の妥当性検証でだいたいなんとかなる
      • メアドのチェック:RFC5322で定義されてるんだけど、ぶっちゃけちゃんと「その文字列がメールアドレスかどうか」チェックするのめっちゃむずいから、あらかじめweb appごとに「これを通す」っていう仕様を決めてチェックしたほうがよい
      • 件名のチェック:「制御文字以外にマッチする」正規表現でチェックすればよさそう。正規表現ぱぱっと書けないんだけど、問題集とかないかなあ………
    • メールでの脆弱性が多い理由:ぐぐるsendmailコマンド用いる手法がたくさん出てくるから!!!!!インターネットの情報が古いのが悪い!!!!!!!!
    • ちゃんとやるならSMTPとか勉強したほうがよさそう、これおすすめらしい:https://www.amazon.co.jp/dp/4774140813

  • webサーバ内のファイルに対する不正アクセスディレクトリトラバーサル
  • OSコマンドの呼び出し:OSコマンドインジェクション←あとで
  • 外部からパラメータって形でファイル指定出来るwebアプリケーションだと、ファイル名のチェックしてないと意図しないファイル見れたりいじれたりする。→ディレクトリトラバーサル
  • 影響多すぎてヤバイんだけど、情報漏えいとか、改ざん、任意のスクリプト実行などなど
  • 対策としては外部からファイル名指定できる仕様をやめる/ファイル名にディレクトリ名を含めない/ファイル名を英数字に限定する
    • ディレクトリ名含めないってなんだ?同じフォルダ内において相対パスだけで指定するってこと?あとファイル名を英数字に限定する理由ってなんだ?
    • 1個目のやつの攻撃方法:クエリ文字列をURLで指定出来たりすると、明らかにヤバイよね(../../../../etc/hosts%00みたいな指定すると/etc/hostsが見られる)
      • %00は[NUL]なので、ファイル名終端させられるので、.htmlとかの拡張子がついてても意味ない
    • 対策としては、外部からファイル名を指定出来ないようにする/異なるディレクトリを指定出来ないようにする/アクセス先の可否をチェックするがよい。異なるディレクトリ指定を防ぐの、忘れやすいっぽい。
  • 対策:外部からファイル名指定できる仕様をやめる
    • ファイル名を固定にする/ファイル名をセッション変数に保存する/番号で間接的に指定する
  • 対策:ファイル名にディレクトリ名を含めない
    • ディレクトリ名、../も含まれるっぽい。でも、こういうのってOSによって違うので、それを吸収したライブラリを使うべき。
  • 対策:ファイル名を英数字に限定する
    • これも↑と一緒で、../も含まれるから、それを弾こうねって話
  • てかもう設計の段階で外部からファイル名渡す仕様を検討しない!!!!!!

  • 意図しないファイル公開
    • ディレクトリをURLで指定すると、中にあるファイルが全部見えるみたいなやつあるよね、あれで見えてたりした
    • →非公開のファイルを公開ディレクトリに置くのが悪い
  • 対策:設計時にファイルの安全な格納場所を決める/サーバ契約時に非公開ディレクトリが利用できることを確認する
  • そもそもそういうのが無理なときは暫定的にApacheで特定のファイルを隠したり出来るので、がんばる

  • OSコマンドインジェクション:意図しないOSコマンドが実行可能になってしまうこと どう考えてもやばいよね、攻撃者のやりたい放題になる
  • パイプとかリダイレクトとかあってシェルって便利なんだけど、それが脆弱性の原因になったりする。;付け加えれば元のコマンドに加えて別のコマンド起動出来るから、そのへんもやばい
  • シェルのメタ文字:;, &, &&, ||とかをちゃんとエスケープするべき。OSコマンドのパラメータとして指定するときに、こういうのを混入させることが脆弱性の原因
  • PerlのOpen関数はやばくて、ファイル名の前後にパイプ記号追加すると攻撃できることがある
  • ↓↓↓ 優先して採用すべき順 ↓↓↓
  • 対策:設計段階で対策方針を決める
    • 実装方針決定→ライブラリだけじゃ🙅→OSコマンド使わなきゃ🙅とかある
    • シェル呼び出せる関数を避ける→パラメータを固定するか標準入力から指定する
  • 対策:まずOSコマンド呼び出しを使わない
    • オーバーヘッドもないから性能も向上するよ
  • 対策:シェル呼び出し機能のある関数の利用を避ける
    • Perlのsystem関数、シェル使ったやつorコマンド名/パラメータを個別に指定するのがあるんだけど、後者は原理的にOSコマンドインジェクション起こらない
  • 対策:外部から入力された文字列をパラメータに渡さない
    • OSコマンド呼び出し関数にシェルを経由するものしかないとき、渡さないのが根本的な対策になるよ
  • 対策:パラメータをエスケープする
    • 自作するな!!!!!ライブラリ関数を用いろ!!!!!
  • 保険的対策
    • 影響が大きすぎるので、がんばる
    • パラメータの検証:パラメータ文字列の文字種を制限するとか。英数字のみとか。
    • アプリケーションの稼働するユーザ権限を最小限にする:adminとかのユーザ権限持ってるやつを取られると即死。ディレクトリトラバーサル脆弱性にもよくきく🙆
    • サーバのOSやミドルウェアのパッチを適用する:最新版にしよう!

アルゴリズムとデータ構造 3章

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

  • ログイン後にあるURLに飛ぶやつ→リダイレクト処理
    • ログインとかしなくてもリダイレクトって呼ぶと思うんだけど、これは特にセキュリティに関係あるからまとめて呼んでる?特別な名前がついてるわけではない?
  • オープンリダイレクタ脆弱性
    • パラメータで指定したURLに飛べて、任意のURLに飛べるので、ユーザが知らないうちにわるいところに飛ばされる可能性がある:フィッシング
    • 信頼しているサービスがこれの被害にあっていた場合、ユーザ「俺ここめっちゃ信頼してるからクレカ情報入力しちゃうぜ!」→情報漏えいみたいなことが起こってしまう 「釣り」ですね
    • リダイレクト先を固定もしくは先を許可されたドメインに制限すると🙆
    • 文書よりこの図見たほうがわかりやすいかも
    • フィッシング対策協議会 Council of Anti-Phishing Japan | STOP!フィッシング詐欺 | フィッシング詐欺って何?
    • リダイレクト先のURLを外部から指定できる AND ドメインチェックがないなら脆弱性が生まれる。でも、オープンリダイレクタが全部脆弱性ってわけじゃないよ
      • もともと外部ドメインへ遷移する仕様
      • 利用者にとって外部ドメインに遷移することが自明
    • これがそろってるときは脆弱性じゃない。web広告とかもそうだよね
      • 対策:リダイレクト先のURLを固定にする
        • 仕様を見直して、固定URLに遷移するようにする。URLパラメータから渡されたtrap.example.comに遷移するんじゃなくて、「パスワードが間違ってたらこのページに絶対遷移する!】みたいな感じかなあ
      • 対策:リダイレクト先を直接指定せず番号指定する
        • リダイレクト先を可変というか自由?にしないといけないときは、そのまま指定するんじゃなくて番号指定する。URL <-> 番号の対応は外部から見えないところで管理する。任意ドメインのURL指定は出来なくなるから、まあオッケー?
      • 対策:リダイレクト先のドメインをチェック
    • リダイレクトするとき、クッションページを挟んだりすると人間にもやさしいかも。携帯電話向けだったら、セッションIDの漏洩防止のために使ったりするよ

  • HTTPヘッダ・インジェクション
    • 外部からのパラメータを元にHTTPレスポンスヘッダを出力する際に発生する脆弱性 範囲広すぎ??
    • 改行でヘッダかボディかわかれるので、それだけで任意のレスポンスヘッダの追加/レスポンスボディの偽造が出来るよ
      • 改行に特別な意味があるのにそのまま出力するからダメ
    • 任意の🍪の生成/任意のURLへのリダイレクト/表示内容の改変/任意のJS実行によるXSSと同じ被害が起こりうる。ありすぎでしょ。
    • !!!HTTPヘッダの出力部分を手作りするな!!!ライブラリやAPIを使え!!!改行コード含まれてたらエラーとして中止しろ!!!
    • これに載ってる攻撃例こわすぎ。改行挟んでLocationを書くと、2回書くことになって、それだと後者のほう(攻撃の方)が優先される。
    • パラメータに改行いれることで好きなHTTPレスポンスヘッダを入れて好き勝手出来るのをHTTPヘッダ・インジェクション脆弱性という。
    • ↑このHTTPリクエスト好き勝手いじれるときに🍪もいじれる。セッションIDの固定化攻撃との組み合わせるとヤバイ><
    • 偽画面表示出来て、CSS工夫することで元の画面隠してフィッシングとか、🍪盗むとか、XSSと共通の影響があるんだけど、攻撃方法がいまいちわからない
    • 対策:外部からのパラメータをHTTPレスポンスヘッダとして出力しない!!!
    • どうしても無理なときは、リダイレクト, 🍪を専用APIにさせる/改行文字チェックの両方をやる。
    • 専用APIとかライブラリにちゃんと入ってるので、できるだけそっちを利用する!
      • ただこれだけだと完全な対策にはなれないため(悲しいね)、改行文字チェック(URL中のはエラーして、🍪はパーセントエンコードするなど)をする
      • 使うライブラリが、ちゃんとパーセントエンコードした🍪を作るかチェックしようね

  • 🍪の脆弱性は、別目的で使っている/出力方法に問題があるに大別できる
  • 本来はセッションIDを保存するべきで、データを🍪に保存しない!!
  • 不適切な利用
    • 🍪、自分で書き換えられるので、困るものを保存しない。たとえばゲームのデータとかを残してたらつよくてニューゲームがし放題?
    • ただ、困らないものでも保存しないほうがよい。🍪とセッション変数で変わるのは情報寿命の制御/異なるサーバとの情報共有だけ。これ以外はセッション変数が便利だから、普通はそっち使う。
    • ナイショの情報を表示するときにセッションだともっかい入力求めさせられる。タイムアウトすると表示すらされなくなる。
    • ただ、セッションやサーバをまたがって情報を保存したいときは🍪使う。「ログイン状態を保存」とか。ただ、これで保存されているのはデータじゃなくてトークンであって、認証状態はサーバ側で管理してる。
    • 「ログイン状態を保存」って結局保存してるやん!!と思って読んでたらトークンで保存してるから大丈夫やでwって言われた

  • 🍪のセキュア属性不備
    • Secure あったよね、アプリケーションがいくらHTTPS通信してても、これがついてないと平文で送信される可能性があり危険🌽
    • Secure つけるのが一番いいんだけど、HTTPとHTTPSが混ざってると動かなくなる可能性があるから、トークンをセキュア属性付き🍪として発行→ページごとに確認とか!
    • 🍪にセキュア属性つけないと、HTTPにリクエストしたときのレスポンスに入ってる🍪値を盗聴される可能性がある:これどうやって盗聴するのかよくわからなかった わかった!!!
    • HTTPSのサイトにアクセスしてログインしておく:このときSecure属性オフ
    • 罠ページにユーザを誘導させる。そんで、Cookie持ってくるために、ここでは、width = height = 0img src = 攻撃先することで、imgしてるから、ブラウザにそこにアクセスさせることになるので、クッキーを送信させることができる
    • HTTPリクエストを見ると、HTTPSでセットされたはずのCookieが平文で送信されている!!!←ここを盗聴できる
  • セキュア属性なんでつけないの?
    • まず知らない←死
    • つけるとアプリケーションが壊れる
    • こういうとき f:id:lullasy:20170103205134j:plain
    • こういうときは、トークンを保持する🍪にSecureつけるとセッション共有できるしセッションハイジャック防止出来てラッキー
    • ラッキーじゃなくてブースター
    • トークンで安全性が確保出来る理由:トークンがサーバとブラウザの双方向で確実に暗号化されること、HTTPSのページを見るにはトークンが必要だから
  • HTTPSを使ってもCookieの改変は防げないことを実験で試してみた | 徳丸浩の日記 全然関係ないんだけど、このページめっちゃ参考になって面白かった。

HTTPS へ置き換えてアクセスすることを試みるように伝達することが可能になります。

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

例えば、下記のURLのように、明示的にPHPSESSIDパラメータを付けてリクエストを送ってみる。
http://foo/bar.php?PHPSESSID=3333
すると、このリクエストに対する応答のヘッダには下記の内容が含まれる。
Set-Cookie: PHPSESSID=3333; …
つまり、ブラウザから与えた値がセッションIDとして採用されてしまう。
攻撃者は上記のセッションIDを仕込んだハイパーリンクをクリックさせることによって、被害者を罠にかけることができる。このセッションIDが使われたままユーザがログイン手続きを行うと、攻撃者もそのユーザのプライベートなページを見て回る機会を得る。

  • なるほどなぁ、これはすごい納得出来たかも
    • セッションハイジャックの原因は多様で個別対応する👼
    • 推測可能なセッションID
      • 自分で作らない!!!実績ある言語などが提供しているものを使うべき!!!暗号アルゴリズムと一緒
      • (1) 攻撃対象からセッションIDを集める (2) 規則性の仮説をたてる (3) 推測したものを試す
      • ユーザID/メアド/リモートIPアドレス/日時/乱数を生成に使う場合が多い。組み合わせとかエンコードとかハッシュ値されることもある。
      • ユーザIDと日時は外部から推測可能なので🙅
      • セッション取れるからなりすましは出来るけど、パスワードとかはわからないので、再認証要求とかである程度被害軽減出来る(前やった!)
      • 現実的で効果的な対策:あらかじめ提供されているセッション管理機構使え!!!
    • URL埋め込みのセッションID
      • 🍪に保存せずそのまま渡すものがあって、携帯電話向けとかの過去の遺産はそんな感じらしい?
      • セッションIDを持った状態で外部へのリンクとかをクリックしたとき、その情報がRefererに乗ってるので、やばやばのやば やっとこの問題納得した
      • webメールサービスとかで、メール内に書いてあるリンク踏んで飛ぶとやばいことになるんだけど、あんまり認知されたとは言えない←明らかにやばやばい
      • 一時期🍪は🙅とかやばいって風潮になったり、携帯電話ブラウザが対応してなかったりしたのでこういう脆弱性が生まれた→URL埋め込みを完全になくすのはむずい
      • 対策:CookieにセッションIDを保存しろ!!!
    • セッションIDの固定化
      • さっきの記事の通り
      • ログイン後にセッションIDを変更するとかで攻撃者にわからなくさせる
      • いま気付いたけど、ログインIDというか認証情報とセッションID誤認してたかも。全然違うわ
      • 認証とか関係なしに、たとえばユーザ登録とかの場面でもこの攻撃出来て、ユーザが入力した時点でサーバの🍪に残るから、別のところでガン待ちしてれば情報が盗める。
      • ただなりすましして権限使ってるわけじゃないから、情報漏えいだけで防げる………とも言える
      • 知らないセッションIDを受け入れる設定でも受け入れない設定でも、結局適当なの作ってそれつかって攻撃すればいいから、攻撃し放題😢
      • URLじゃなくて🍪に情報保存してても、ブラウザとかwebappに脆弱性があれば攻撃出来る。前やった!
      • 脆弱性が生まれる原因っていっぱいあるんだけど、全部対策するのは不可能??だし修正予定もなかったりするから(!!!IE!!!)、これはもう許容して、ハイジャックされないように気をつけるのがよい。認証の後セッションID変更するとか!
      • ものによっては明示的に変更できないので、トークンを🍪とセッション変数両方に記憶→比較→同じならおk、みたいな感じ
      • これが外部に出るタイミングはログイン時の🍪生成のときだけなので、攻撃者はわからないので防げる。
      • トークンは予測困難性とかが必要で、秘密の国のアリスでやったようなアレが必要
      • ただ、↑のはログイン後の対策で、ログイン前の対策ではない。ログイン前はhiddenパラメータで値を回すのが現実的!

  • セッション管理機構を自作するな
  • クッキーにはセッションID保存しろ、情報保存するな
  • 認証成功したらセッションID変更しろ
  • 認証前はセッション変数に情報保存するな

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

  • SQLインジェクション
    • SQLの呼び出し方がヤバイと起こる
    • 行動者が能動的にサーバーを攻撃出来る
      • DB内の情報を盗める
      • 内容書き換えができる
      • 認証回避
      • ファイルR/W/run
    • 影響が大きすぎるので、絶対に起こらないコーディングをする。確実な対策は、「静的プレースホルダを利用してSQLを呼び出す」こと。
    • 些細な情報に対するSQL呼び出しに脆弱性があって、DBの任意の情報が取れるから、ヤバイ
    • エラーメッセージの内部エラー情報をそのまま表示するのもヤバイからちゃんと隠す(前もやったね)
    • UNION SELECT を使った攻撃
      • UNION SELECT:2つのSQL文の和集合を求める
      • union select id, pwd, name, … from users みたいなことが出来るから、一度で大量の情報が漏れる
    • 認証回避
      • よくあるBasic認証のやつで、パスワード欄に’ or ‘a’ = ‘aって入れると、SELECT * FROM users WHERE id = ‘yamada’ AND pwd =‘’ OR ‘a’=‘a’ みたいな感じになってWHEREが常に成立し、ログイン出来てヤバイ
    • データ改ざん
      • update なんたらかんたら — で改ざんできる。-- 以降はコメントなので、無視されるからやばい
      • HTMLタグが有効になるので、iframeとかscript埋め込めるから、マルウェア感染させられたりしてやばい。
    • ほかにも OSコマンドの実行/ファイルの読み書き/他サーバの攻撃が出来る場合がある
    • DB内にどんな表や列があるかは、INFORMATION_SCHEMAの中のtablesやcolumnsで見られる

SQL中に、後に可変値を埋め込みたい場所を「$1」「$2」あるいは「?」などの特別な文字列、すなわちプレースホルダで確保しておき、ここに埋め込む値はSQL本体とは分離して渡す、というのが根本的な考え方です。これらを別々に渡すことで、SQLサーバは、パラメータの内容はあくまでも「値」として解釈し、たとえその値にSQLとして解釈できる文字列が記述されていても、それをSQLとして実行することはしない、という仕組みです。

指定されたエンコーディングへの変換の前にエスケープ処理を行っており、適切なエスケープ処理ができていなかった。
⇒その結果、エスケープ処理をバイパスしてSQLインジェクションが成立する形になっていた。

  • ワイルドカード文字のエスケープを怠る != SQLインジェクション
  • p.135のサンプルコードの意味がわからん
  • SQLインジェクションの保険的対策
    • 万が一なんか起きた時、被害を軽減するときのためのやつ
    • 詳細なエラーメッセージを表示しない(前もやった!)/入力値の検証(前もやった!)/DBの権限設定
    • DBの権限:最低限のアクセスだけ許可する!
  • プレースホルダが使えないけど対策したいとき
    • 記号文字のエスケープ:quoteメソッドとかがある
    • 数値リテラルは数値以外の文字を入れない:キャストor正規表現

  • 重要な処理(クレカとかログインとかメールとか)にある脆弱性Cross-Site Request Forgeries; CSRF
  • 利用者の意図したリクエストか確認しないと、物品購入/退会/書き込み/id, pass変更などの影響がある
  • この脆弱性では情報盗むことは出来ない。でもやばいから、利用者の意図したリクエストか確認する!
  • 攻撃の手法としては、iframe のXSSと似た感じ、罠サイト用意して通信する感じだけど、CSRFと反射型XSSは途中から違う。HTMLの改変、スクリプト実行がXSSで、不正操作するのがCSRF
  • XSSはブラウザ上で出来ることはなんでもできるから(ん?)、これのほうが脅威大きいんだけど、CSRF設計段階で対策する必要がある/認知度が低いから対策進んでないのでちゃんと気をつけよう!
  • 確認画面から実行画面の間にクッションがあっても、hiddenパラメータとかセッション変数とかで攻撃出来る
  • iframe を2つ使って、時間差で呼び出したりしてPOST→セッション変数に保存みたいなことが出来る。原理的にはどれだけ多段でもiframe増やせば攻撃出来る🙆
  • CSRF脆弱性が生まれる原因:form > action にはどのドメインでもOK/クッキーに保存されたセッションIDは対象サイトに自動的に送信される
    • ふつうのとCSRF攻撃のリクエストではRefererだけが違ったりするんだけど、気をつけない限りチェックしないから脆弱性が生まれる👶
    • 🍪以外にも自動で送信されるパラメータを使ってセッション管理してるサイトはヤバイ。HTTP/SSLクライアント/携帯ID認証使ってるところもヤバイ🙅
  • 対策:CSRF対策の必要なページを区別する
    • 購入ページ、パス変更、個人情報変更するところとか
  • 意図したリクエストかチェックする
    • トークンの埋め込み:実行ページの直前に!POSTじゃないとダメ!
    • パス確認:最終実行ページで!意思を念押し確認!正規利用者か確認!
    • Refererチェック:送信しない設定してるとダメ!漏れとかもある!前方一致検索で絶対URLをチェック、スラッシュのあとも確認!でも他に比べて実装が楽だから、社内システムとかはこれでもいいかも〜
  • CSRFへの保険的対策
    • 「重要な処理」実行後に、利用者に通知メール送る。でもこれ来るのめんどいよね、わかるけど
    • XSSでなりすまされたときも気づけるからメリット大きい
    • メールは平文で送るから、ヤバイ情報載せちゃダメー🙅 詳細見せたかったらログイン必要なページでするべき
  • ログイン後のCSRF対策はしてるけど、ログイン前はどうしてるの???あとで調べる thanks
  • ログイン機能がない掲示板で自分が意図してない書き込みを、URL踏むだけでされるのは嫌だよね?

安全な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対策するのは比較的楽だが、後から対策するのは!!激ムズ!!だから、最初からちゃんとした設計をしよう

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

  • 脆弱性は悪用出来るバグで、経済的にかなり損失が起こることがおおい
    • 信用失った結果売上落ちる
    • 小さくても法的にヤバイ
    • 黒歴史ばらまいたり個人情報ばらまくのでダメ
  • リファラで持ってくる URL にセッション ID 含まれてたら漏洩する可能性がある←セッション ID ってどうやって管理するべき? URL に乗らないように隠して持つ?
    • A. Webブラウザ向けならクッキー thanks:sora_h
  • GET はデータを取ってくるときだけ使いたい、副作用ないようにしよう!
    • hidden は 第三者からの書き換え には強いけど、本人では hidden パラメータをいじれる。これは対策する必要あるのかなあ?
    • hiddenのあまりにも馬鹿げた使い方 - ockeghem(徳丸浩)の日記 必要ありました、これさすがに怖すぎると思うんだけど、こういうことをしているサイトがあるのがびっくり
  • ステートレス

    ステートレスとは、システムが現在の状態を表すデータなどを保持せず、入力の内容によってのみ出力が決定される方式。

  • Basic認証はステートレスなので、やりとりのたびに認証情報を全部わたす。めっちゃ不便そう、一回の情報盗まれるだけで認証取られるのやばすぎ

    • Basic認証はこんな感じ↓
    • 別にクッキーでも何にせよ情報は毎回渡しているけど、根本的な資格情報かセッションかどうかの違いが大きい(機械的に変わるし無効ともできるし) thanks:sora_h f:id:lullasy:20161230223731j:plain
  • クッキーでセッション管理するのが便利、そのまま残すのはアレだから整理番号(セッション ID?)で管理するとよい。通しはあぶないので、漏洩しない/強制しない/推測できない🙈🙉🙊が条件

  • Cookie属性は色々あって、Domain/Path/Expires/Secure/HttpOnly
    • Domain:Domain = example.jp → a.example.jp / b.example.jp にも送られる。レンタルサーバとかだと漏洩するからダメ!
    • Secure:SSL 通信してるときだけCookie送る
    • HttpOnly:JS からアクセス出来なくなるので、XSS対策になる?攻撃を「難しく」することは出来る
  • 能動的と受動的攻撃、直接いじるのは能動的で、いじったデータを元に色々させる?被害を与える?のが受動的?
    • ブラウザで受動的攻撃を防ぐにはサンドボックスがよい。よくある、この機能にはアクセス出来ますよというやつ。最近の iOS とかでは標準で搭載されてたりするの、すごいのか人間が信頼出来ないのかどっちだろう。
  • 同一生成元ポリシー
    • こういう状況が起こりうる↓ f:id:lullasy:20161231003045j:plain -同一生成元ポリシーがあると、ホスト一致(Fully Qualified Domain Name)/ プロトコル一致 / ポート番号一致 でないところからデータを取れなくなる = JS アクセスが拒否される -普通だと拒否されるので、がんばって iframe の内側に JS 送り込んで情報を盗もうとする→XSS攻撃
  • X-FRAME-OPTIONS
  • ブラウザで対策してても回避する方法たくさんある。webアプリケーション側でしないといけない対策はこんどね