commew
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # 輪読会 ## 書籍 体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 https://amzn.to/38EvUMZ ## 開催日時 土曜 20:00 ~ 21:00 読書タイム 21:00 ~ 22:00 ディスカッションタイム ## 実施記録 ### 第1回 2021/02/06 #### 予定 P.2 ~ P.18 #### 進捗 P.2 ~ P.18 #### ファシリテーター むちょこ #### ディスカッション ##### 1-1 > 別の利用者に成りすまし、秘密情報の閲覧、投稿、買い物、送金などを行う * 他人のID・パスワードを盗んで個人情報を閲覧したり * 少し前のLINEアカウントの乗っ取りして「電子マネー購入して」を友だちに送られたりとかですね * セッションハイジャックとかもかな ##### 1-2 実際に経済的損失が発生したことはありますか? * サイトを止めてしまったり、システムの不具合が原因でユーザへ(ソーシャルゲームの)宝石を配る対応をさせてしまったことがあります * バグハンターから連絡がきた * ユーザへお詫びを配る系ならいっぱい * リリースから1時間後にバグが発覚 ##### 1-3 チェック機能不足ってキリがない * テストコードをどこまで書くか? * 時間の都合もある * 重大なミスがないようにがんばろ、、 脆弱性の原因がA,Bどちらに属するのかわかりづらい * "バグによるもの"は、htmlspecialchars忘れとか ##### 2-2 FireFoxを使う理由 * > 著名ブラウザで唯一XSSフィルタが標準で実装されていないため チェックサイトで確認したところ、Chromeでも無効になっている https://misc.laboradian.com/xss/xss-auditor-test/1/ * > Chrome 78 (2019年8月) で XSS Auditor は削除されました。 * 書籍の発行日が2019年8月より前なので、発行当時はFireFoxだけだったのかも * XSSフィルタをバイパス(迂回)する方法が周知されてしまったので、効果がなくなってきたため他ブラウザでも削除されるようになったみたい ##### 2-3 CORSとOWASPの発音は? * CORS コルス * OWASP オワスプ VirtualBoxは最新ですか?書籍通りのバージョンですか? * 最新使ってます! * 大抵バージョン違いで書籍通りに行かずハマるので合わせるかと思ってました * トラブルが起きたらその時考えればいいかなと Macだとホストネットワークマネージャーの名前が違うので不安 * 名前が違くても大丈夫 * Windowsは書籍どおりの名前でした ##### 2-4 アーカイブはどこから取ってくるんですか? * 2-1にURLがあります * 一番上の「実習用仮想マシン」をダウンロード インポート開始画面のボタンが表示されない(モニタ設定の都合上) * Alt+Nでどうでしょう → 反応なし * タブでいきましょう → いけた --- ### 第2回 2021/02/13 #### 予定 P.19 ~ P.40 #### 進捗 P.19 ~ P.49(入力-確認-登録パターンの直前まで) #### ファシリテーター 林 雅之さん #### ディスカッション ##### 2-4 P26: @mh Firefoxで「[http://example.jp/](http://example.jp/)」を閲覧すると、「アクセスしようとしているサイトを見つけられません。」の警告が表示される * OWASP ZAPのバージョンアップに伴い、HUDという機能がデフォルトで有効になったことが原因らしい。 * https://teratail.com/questions/197984 * そもそも、HUDって何よ。わからん。 * [ OWASP ZAP Heads Up Display](https://github.com/zaproxy/zap-hud) * Heads Up Displayの略らしい。 >The HUD is an interface that provides the functionality of ZAP directly in the browser. >HUDは、ZAPの機能をブラウザ上で直接提供するインターフェースです。 * OWASP ZAPのスタンドアローンのアプリがブラウザで動く感じかな p26: @mh Firefoxで「[https://example.jp/](https://example.jp/)」をhttpsで閲覧すると、ブラウザで証明書エラーが表示される。 * 対策として、p631の「OWASP ZAPのルート証明書を導入する」を実施するとよいらしい。 * ただし、OWASP ZAPのルート証明書をブラウザに導入すると、ブラウザでエラーが表示されない状態で盗聴ができる状態になるので、セキュリティ的には危険な状態であることに注意が必要。 ##### 2-5 p28: @mh OWASP ZAPの公式サイトのURL内にindex.phpのパスがあるのはセキュリティ的にどうなんだ。 * [https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project](https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project)みたいなURL p29: @mh OWASP ZapのダウンロードURLは[https://www.zaproxy.org/download/](https://www.zaproxy.org/download/)のようだ。 -> 戸惑ったので助かります!ありがとうございます! ##### 2-6 p36: OWASP ZAP起動した状態で http://example.jp/ に接続してもタイムアウトになっちゃうのですが、、これどうしたらいいですか?TT -> 仮想マシン起動し忘れでした! p38: @mh 図2-46 設定ファイルをインポートしたの箇所 * 「Use Enabled Proxies By Patterns and Priority」ではなく「Use Enabled Proxies By Patterns and Order」が選択された * 特に問題なしかな? ##### 2-7 #### 備考 * OWASP ZAPにリクエスト、レスポンスが表示されない事象 * もし遭遇したら、以下のサポートMLのスレッドが参考になるかも * https://groups.google.com/g/wasbook-readers/c/m_VIaCcT-2I * https://groups.google.com/g/wasbook-readers/c/liAl2RABLQI * 本書籍の正誤表も載せておく * https://www.sbcr.jp/support/14647/ * 今回該当する箇所は、以下のp37 ``` p.37 下から3行目 誤) ページ最下行付近の「参照」ボタン 正) 「Import Settings from FoxyProxy 6.x(current version)」の「参照」ボタン ``` * 先輩に学ぶ HTTP Status Code * https://gist.github.com/rosylilly/3401612 --- ### 第3回 2021/02/20 #### 予定 P.49(入力-確認-登録パターン) ~ P.72 #### 進捗 P.49(入力-確認-登録パターン) ~ P.70 #### ファシリテーター むちょこ #### ディスカッション * example.jpにつながらなくなったときの対処法 * VirtualBoxでwasbookを起動済みであることを確認 * IPアドレスでアクセスしてみる * PC, アプリの再起動 ##### 3.1 * p61: @mh 一度認証したBasic認証をクリアしたい場合は、Firefoxをキルして再起動すればよい。Cookieとかキャッシュクリアではダメだった。 --- ### 第4回 2021/02/27 #### 予定 P.70 ~ P.88(プリフライトリクエストまで) #### 進捗 P.70 ~ P.83(script要素まで) #### ファシリテーター 林 雅之さん #### ディスカッション * P74)受動的攻撃3がわかりにくい * たとえばPHPを実行するurlが貼ってあって、それをクリックするとPHPでポストリクエストを正規サイトに送ることもできる、みたいなイメージかも(むちょこさん * となると罠サイトは2段階(1.手前のhtml、2.奥のphp)あると考えるとわかりやすいかも(林さん * P81コラム)グリースモンキーとはFirefox版のChrome拡張みたいなもの?(Hiroさん) * アドオンがChromeの拡張機能。グリースモンキーはFirefoxのアドオンのひとつ。 * グリースモンキー使えばサイト毎にユーザー側で拡張したいことをJavaScriptで拡張できる機能をもっている。 * フォキシープロキシーはグリースモンキーとは言わない? * フォキシープロキシーもグリースモンキーも同じFirefoxのアドオンとして並列な位置付け。 * たとえばグリースモンキー使えばいろんなサイトで自分の書いたJavaScriptを実行できる?(むちょこさん) * そう。ただこの場合は自分で書くだけでなく人の書いたJavaScriptを使うこともできる。ここではそのセキュリティの説明が書いてある(林さん) * P82)img要素の認証はクロスオリジン属性にユーズクレデンシャルズをつける認証方法であっている?(むちょこさん) * これは普通にbasic認証のはず。セッションによる認証方法でもとおるはず(林さん) * キャンバス要素でイメージ要素編集したら汚染がどうのこううのという記事を見つけた。これは今学んでいることと関係している?(むちょこさん) * 2100サイト読んでみると別のサイトの別のドメインの画像を指定してもその画像に対し送られる、と書いてあるのでhttp認証でなくても表示できる模様。で、この表示したものをhtml5のキャンバス要素で編集するのはJavaScriptからのアクセスが理由からか同一オリジンポリシーの制約をうけると書いてある。CORSの成約も受けるので、CORSで許可したら他のドメインの画像をキャンバスで編集することもできるようになるはず(林さん) * 認証の必要な画像とはインスタとか自分の投稿した画像などログインしてないと見れない画像ということ?(Hiroさん) * 2222その認識であっていると思う( * ログインしてないと見れない画像のurlを別のサイトで吐いても表示される? * そういうことになる。 * POSTに対するクッキーがつくのでというのは、そのインスタにログインされるなら表示されるということ? * そういうことになる。 * では自分だけしか見れないurlをどこかに貼り付けても他人はログインしてないからそれは見れないが、自分はインスタにログインさえしていれば他のサイトでも見れるということ? * おそらくそう。 * むちょこさんがさっき言ってたのって「画像にアクセスするのに認証が要る」ではなく「認証に画像を使う」と勘違いしていた?画像を使ってログインする、みたいな(Hiroさん) * そうかも。phpでも画像にアクセスできるか制御するけどそっちかと今の話で気づいた(むちょこさん) * 別のサイトでインスタの画像を表示できるとしても、表示されるのはユーザーに対してだけなので問題にはならないはず(林さん) * JSONPってなんだ? * 普通のJavaScriptアクセスは同一オリジンでないとだめだけど、  隠したい情報を読める(林さん * JSONPに変数を宣言する、その中にシークレットな情報を入れてしまうと外部から読まれてしまう(林さん * コールバック関数をレスポンスで返す(mhさん * 気になった人が各自自分で調べることに。 #### 学習メモ ##### 3-2 * 3つの受動的攻撃のパターン * ①単純な受動的攻撃 * ②正規サイトに罠を仕込む受動的攻撃 * サンドボックスとは * 利用者のブラウザ上で悪意のあるプログラムが動かないように、JavaScriptなどは安全性を高めるための機能のこと * サンドボックス=“砂場”、幼児が好きなだけ騒いでも外部に迷惑がかからないようにとの発想から * JavaScriptのサンドボックスで制限される機能は以下 * ローカルファイルへのアクセス禁止 * プリンタなどの資源の利用禁止 * ネットワークアクセスの制限(=同一オリジンポリシー) * 同一オリジンポリシーとは * ブラウザのサンドボックスに用意された制限のひとつ * JavaScriptなどのクライアントスクリプトからサイトをまたがったアクセスを禁止する制限のひとつ * JSONPとは * Ajaxアプリケーションから同一オリジンでないサーバー上のデータにアクセスする手法として利用される * ただし認証状態によりJavaScriptのソース(JSONPのデータ)が変化すると、意図しない形で情報が漏洩する可能性があり危険。よってJSONPでは公開情報のみを提供するようにするべき --- ### 第5回 2021/03/06 #### 予定 P.83(CSS) ~ P.103(文字エンコーディングの検証まで) #### 進捗 P.83(CSS) ~ P.101(4-1) #### ファシリテーター しばたさん #### 書記 まっきー #### ディスカッション * P.85:「相手側の許可なしに可能」とあるが、実際は情報提供元がCORSヘッダ「Access-Control-Allow-Origin」でリクエスト側に許可を出しているわけなのでやっぱり許可いるのでは?(林さん) * 通常のフォーム程度のリクエストなら必要ない?(mhさん) * 「特定の条件(P88)を満たす」とあるから?(Hiroさん) * そもそもここでいう「許可」とは?「Access-ControlAllow-Origin」はここでいう許可ではなく別の許可を指していそう(junさん) * ここでいう許可はP.90の表にある「オリジンに対する許可」、ということかも(mhさん)→納得 * 今やっている例はシンプルなリクエストを満たしていないのでは?Content-Typeヘッダがapplication/jsonになっているのでP88の要件と異なる(Hiroさん) * application/jsonはレスポンスの話であってリクエスト側はGETになっている(林さん) * OWASP ZAPでリクエストメッセージ側にContent-Typeヘッダに記載が何もないことを確認できる(林さん) * Content-Typeヘッダに何もないからやっぱりシンプルなリクエストの要件を満たしていないのでは?(イッシーさん) * 満たしている。あくまで「設定する場合」はContent-Typeヘッダ要件が必要なのであり、今回は設定がないので不要(むちょこさん) * ここでいう「設定」とはXMLHttpRequestオブジェクトのsetRequestHeaderメソッドで設定するリクエストヘッダのこと * 誰でも自由使えるAPI(登録不要なタイプ)はaccess-control-arrow-originの設定はしてあるのか?(Hiroさん) * URLで叩く場合はHTTPの場合とは異なりaccess-control-arrow-originがなくてもいいと思っていた(むちょこさん) * API叩くときにXMLHttpRequestを送ることがそもそもない→PHPからAPI叩くときもCURL使うときはaccess-control-allow-originはいらないはず(今までもAPI作成の際に設定したことない)(むちょこさん) * サーバーサイドからコールするときは不要(フロントからは必要)(mhさん) * Access-Control-Allow-Originの値でアクセスを許可するオリジンを指定する。 値に*を指定するとすべてのアクセスを許可できる(mhさん) * https://qiita.com/eshow/items/e47e7214dc12f130f456#%E8%A8%AD%E5%AE%9A%E3%81%99%E3%81%B9%E3%81%8D%E3%81%93%E3%81%A8-1 * javaでは公開APIでも自分は設定していた。設定しないと誰でもアクセスできる(イッシーさん) * 設定はデフォルトが*ということかも(むちょこさん) →その後Hiroさん調査でLaravelにも\*設定を確認 * 今ためしに郵便番号のAPIをscript書いて叩いてみたらエラーになった(林さん) * ためしたコードは以下 * <script>fetch('https://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060');</script> * コンソールから「CROSS-ORIGIN要求をブロックしました」と言われた ←別ドメイン扱いされた * この郵便番号のAPIの場合、サーバーサイドからこのAPI叩いたうえでその結果を同じドメインから渡す、などして取得するのかも(林さん) * get-jsonならいける、という記事を発見(むちょこさん) * それってjsonpのことかも?jsonpを利用してクロスオリジンを回避している可能性高そう。jsonpはCORSなかった頃に使われていた方法みたい(hiroさん) * 自分でURL叩いてアクセスするときは同一originエラーが出ないのは、同エラーはJavaScriptのみを対象としているから(林さん) * なぜ? * JavaScriptでXMLHttpRequestとかfetchで使っている場合とちがって自分でアクセスしに行っているので同一オリジンポリシー関係なくなる * XSSなどはJavaScriptを送り込んで悪意のあるサーバーに無理やりアクセスさせることができてしまう。なのでXSSはJavaScriptだとできないようになっている * ほかのページからJavaScriptでXMLHttpRequestでアクセスするときは同一オリジンポリシーに引っかかる、ということ * PHPからアクセスするのも大丈夫?(むちょこさん) * そのはず(林さん) * PHPでCURLでアクセスするのを許してしまって大丈夫なの?(Hiroさん) * JavaScriptが悪意のある罠サイトから実行されるからJavaScriptのみを厳しく見ている、それが同一オリジンポリシーが必要な理由 * つぎの本がおすすめ(mhさん) * https://www.lambdanote.com/products/wbs * jxckさんのorigin解体新書 https://zenn.dev/jxck/books/origin-anatomia #### 学習MEMO ##### 3-3 * Access-Control-Allow-Originとは * クロスオリジンからの読み出しを許可するための仕掛けであり、情報の提供元がHTTPレスポンスヘッダとして出力する * 仮にhttp://example.jp に対してXMLHttpRequestなどのアクセスを許可する場合は下記のHTTPレスポンスヘッダを送信する * header('Access-Control-Allow-Origin:http://example.jp'); * クロスオリジンとは * オリジン = プロトコル(http, https) + ドメイン(example.com) + ポート(80, 443) * クロスオリジン = 同一でないオリジン * XMLHttpRequestとは * HTTPリクエストを投げて、テキストやjson形式などのレスポンスを受け取る * Ajaxの基幹技術 * シンプルなリクエストの要件 * メソッドが「GET,HEAD,POST」のいずれか * XMLHttpRequestオブジェクトのsetRequestHeaderメソッドで設定するリクエストヘッダが「Accept,Accept-Language,Content-Language,Content-Type」のいずれか * Content-Typeヘッダが「application/x-www-form-urlencoded、multipart/form-data、text/plain」のいずれか * プリフライトリクエスト * 「シンプルなリクエスト」ではない場合、ブラウザがプリフライトリクエストを発行して、そのリクエストが許可されるかどうかをリクエスト先のサーバに尋ねる * API側はheaderで許可範囲を設定することができる * 教材以外の参考URL:https://developer.mozilla.org/ja/docs/Glossary/Preflight_request * リクエスト側のContent-Typeがapprication/jsonなので、メソッドに対する許可とヘッダに対する許可をAPI側でしてあげないといけない→これを満たしてはじめて例ではPOST送信がされるようになる→33--004b.phpではここからPOSTリクエスト時のヘッダをapplication/json対応にすることでAPIの取得に成功している(まっきー追記) ##### 4-1 * インジェクション系脆弱性 * 「出力」で発生する脆弱性 * データの中に引用符やデリミタなど「データの終端」を示すマークを混入させて、その後の文字列の構造を変化させてしまう --- ### 第6回 2021/03/13 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.102 ~ P.119(4-2の最後まで) #### 進捗 P.102 ~ P.119(4-2の最後まで) #### ファシリテーター むちょこ #### 書記 イッシー #### ディスカッション * 4-2 * 文字エンコーディングや入力チェックの種類について * エラーチェックについてはここまでやってるっけ?という再確認になった(エンジニア婦人さん) * mb_check_encodingって使ってる?(むちょこさん) 使ってない。フルスクラッチの時はチェックしてた気がするけど、今はフレームワーク対応? 昔は文字コードにより脆弱性が多かったが、ブラウザや言語のセキュリティが強化されたことから今はそこまで対策しなくてもよさそう(林さん) * 入力値の検証 * 更新処理を行った時にバリデーションチェックをしっかりやってNGがなかったのにも関わらず、SQLエラーが発生した経験あり デフォルト値が設定されてなかったのが原因(エンジニア婦人さん) * メールアドレスの入力を忘れた状態でメール送信したら画面側にエラー起きる?(エンジニア婦人さん) アプリケーション側で制御はできる(むちょこさん) ログには出てるケース多い(しばたさん) * バイナリセーフとヌルバイト攻撃 * eregって使用する?(エンジニア婦人さん) eregはPHP7からない削除された模様(林さん) PHP5.3から非推奨(むちょこさん) eregの検査を回避された理由 『ファイル名のように仕様上ヌルバイトを許容しないパラメータがあるからです。』の部分がひっかかる(junさん) teratailはこちら:https://teratail.com/questions/214473?sort=2#720 バイナリセーフのみの関数で開発する分にはPHP内では問題ない。 外部システム(ファイルシステム等)上に連携するときにヌルバイトチェックに引っかかってしまうケースがある。(林さん) ヌルバイトチェックに引っかからないようにしようねが着地点 * 「制御文字というのは改行やタブなど…」のタブって何のことか(Jangariccoさん) テキストエディタで入力するときにtabキーを押して入力する文字のこと タブはスペース何個って言語で決まってるので、エディタで設定しとかないと人によってタブに入るスペースが違うので大変なことになるのでちゃんと設定しよう(しばたさん) psrのコーディング規約:インデントには4つのスペースを使用し、タブは使用してはいけません。(むちょこさん) * フレームワークのバリデーション機能を使用したほうが綺麗に書けるのでfilter_inputはフルスクラッチ専用かも(むちょこさん) * barやbazが何なのか教えてほしい fooの仲間 メタ構文変数:これは変数名!というのをわかりやすくするために、暗黙の了解みたいな感じになってる(しばたさん) wikiはこちら:https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF%E6%A7%8B%E6%96%87%E5%A4%89%E6%95%B0 * 正規表現の書き方はPHPに限らずほかの言語でも同じ?(まっきーさん)   一部異なるところがあるが、基本は同じ(むちょこさん) 正規表現ツールはこちら:http://okumocchi.jp/php/re.php * フレームワーク使用されている方で、フレームワークでチェックされているか事前に確認してるか(junさん) ZendFrameWorkで改行文字が文字数カウントしちゃうとかあったので、テストでおかしい動きした場合は追う感じ(エンジニア婦人さん) #### 学習MEMO ##### 4-2 * 不正な文字エンコーディングを使った脆弱性 * 不正な文字エンコーディングが混ざると、エンコーディング変換時にバックスラッシュ等が出現してしまう可能性がある。エスケープの後に変換して出現した場合、そのままSQLなどで使われる危険性がある(→認識があってるかちょっと不安。6章のときでも良いので、確認したいです)。 * P.524 ~ P.528あたり * https://www.slideshare.net/ockeghem/ss-5620584 * 普段からmb_check_encoding()を使ってチェックしている人がいるのか聞いてみたい * Laravel, CodeIgniterの最新バージョンでは使っていなさそう。特にマルチバイトの取り扱い中に起こる問題なので、英語圏発のフレームワークでは考慮されていないことが多いのでは。 * 文字コード周りの脆弱性関係の参考 * 昔(2009年頃)の状況の話。 [本当は怖い文字コードの話:連載|gihyo.jp … 技術評論社](https://gihyo.jp/admin/serial/01/charcode) * 最近の話 by 徳丸さん。 "基本的な前提として、文字エンコーディングによるセキュリティ的な攻撃をすることは、昔と比べずいぶんと難しくなっています。" [PHP - Laravel 文字エンコーディングのセキュリティー対策|teratail](https://teratail.com/questions/181025) * デコード * [SJISのURLデコードツール https://www.benricho.org/moji_conv/16-URLencode_Shift_JIS.html](https://www.benricho.org/moji_conv/16-URLencode_Shift_JIS.html) * (↑興味のある方向け。使わなくても大丈夫。) * [DrupalのSQLインジェクションCVE-2014-3704(Drupageddon)について調べてみた https://blog.tokumaru.org/2014/10/drupal-sql-injection-cve-2014-3704.html](https://blog.tokumaru.org/2014/10/drupal-sql-injection-cve-2014-3704.html) * filter_input() * フレームワークを使用する場合は、代わりにバリデーション機能を使うのが良いと思う * 例えばLaravelならValidatorファサードを使用する [Laravel 8.x バリデーション https://readouble.com/laravel/8.x/ja/validation.html#manually-creating-validators](https://readouble.com/laravel/8.x/ja/validation.html#manually-creating-validators) * 正規表現 * 全体の先頭\A、末尾\z * 行の先頭^、末尾$ * サンプル(PHPでクエリ文字列を受け取り、表示するスクリプト) * 宿題:エラーメッセージが簡素すぎて分かりにくい * 制御文字のチェック * Perl、Java、.NETでもたぶん可能な方法 [不必要な制御文字への対処 https://inside.pixiv.blog/2020/05/13/181507](https://inside.pixiv.blog/2020/05/13/181507) --- ### 第7回 2021/03/20 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.120(4.3.1の始め) ~ P.138(4.3.1の最後) #### 進捗 予定通り #### ファシリテーター 林 雅之さん #### 書記 まっきーさん #### ディスカッション * ワームとは?(林さん) * 自身を複製できること、単独で活動し、感染拡大機能を持つ(junさん) * P123でやっていることはP81の図と同じ?(まっきー) * 同じ。 * 脆弱性があったからって何ができるの?とお客さんに言われることもある。SQLインジェクションより優先下がりがちなことも(林さん) * 説明しなければならないときはどう説明する(婦人さん) * 被害の可能性を説明する。勝手にJS実行されちゃいますよ、とか(林さん) * 個人情報盗まれる、とかだとインパクト出せるかも(junさん) * P126のようなサイトを使ったことありますか?(林さん) * 使ったことある。ex.静岡市や神戸市など(婦人さん林さん) * 参考)静岡市のサイト:https://gomi.city.shizuoka.jp/gomi/Top;jsessionid=258A1BA2F31372D64F6846226B27DAAA * 最近のテレビでの詐欺サイトの注意説明でhttpsかをチェックみたいなの見かけるので、引っかかりそう(junさん) * 画面の書き換えの箇所ですが、この注入するHTMLを入力フォームに入力すると、見た目は変わると思うのですが、他の人がアクセスしたときも表示されるのでしょうか?(Jangariccoさん) * 罠サイト経由で入った人だけトラップ表示される * 罠サイトからPOSTリクエストが送られている感じ * 反射型のメリットはあるの?(林さん) * サーバーを攻撃しなくていいので手軽そう。掲示板にURL記載するだけとか(junさん) * 「<」の読み方は? * 小なり。「左基準」と覚えるといい。 * 「&lt」はless thanの意 * lを「left」と覚えるのも覚えやすいかも * SQLの日付指定でよく使う(イッシーさん婦人さん) * 雑学)Perlは文字列を比較するときはltやgt、eqを使う←文字列と数値で比較演算子がちがうという(林さん) * 宇宙船演算子ともいう(mhさん) * 属性値をダブルクオートで囲む理由は①htmlの仕様上必要、②入れないとエスケープできないから、の2点ある(林さん婦人さん) * htmlspecialchars()で空白がエスケープできないから?(むちょこさん) * そもそも属性値に一部の文字以外を含む場合はダブルクオートで囲む必要がある、が正しい * 属性値にダブルクォーテーションの中に変数突っ込む時にシングルコーテーションで突っ込めませんでした?(イッシーさん) * 可能。value='"{$test}"'とか。(むちょこさん) * P133の真ん中の例でイベントハンドラをタグに直接書いているが、これはやめてほしい。スクリプト内に書いてほしい(林さん) * ENT_QUOTEしか使ったことない(婦人さん) * LaravelはENT_QUOTE。Laravel以外のフレームワークはどうなんだろう? * CakePHPは「ENT_QUOTES | ENT_SUBSTITUTE」とちゃんとやっている(※ENT_SUBSTITUTEは文字コードまわりの面倒なやつでセキュリティには無関係) * 「無効な符号単位シーケンスを含む文字列を渡したときに、 空の文字列を返すのではなく Unicode の置換文字に置き換えます。 UTF-8 の場合は U+FFFD、それ以外の場合は &#xFFFD; となります」とある(むちょこさん) * X-XSSーProtectionは古いブラウザしか効果ない&最近のブラウザでもXSS対策はされてないので効果は限定的。それでも場合によっては使ったほうがいいかも(林さん) * フレームワークはXSS対策をある程度吸収してくれているので便利 * TRACEメソッドは古いので今はあまり必要ないかも(林さん) * ここでしか言えないけど、ヘッダチェックサイトで自分の手掛けたサイトをチェックしたら「✕✕✕」と出てしまったww * Cakeはhtmlspecialcharsの省略形「h()」自分で入力しないといけないのでたまに忘れる * Laravelは自動でしたっけ? * {{ }}ならエスケープ,{!! !!}なら非エスケープ * javaはタグ書かないと画面表示できないので、忘れないやつだ。タグ属性の中身でエスケープやってくれてる感じですね。Thymeleaf。[[ ]]←こんなやつ。th:text="${id}" #### 学習MEMO * P123 window.location * 代入されたURLページに遷移 * 反射型XSSと持続型XSS * 反射型XSS:攻撃用スクリプトが攻撃対象サイトとは別のサイト(罠サイトやメールのURL)にある場合 * 持続型XSS:攻撃用スクリプトが攻撃対象のデータベースなどに埋め込まれている場合 * XSS脆弱性 * 読み方は「クロスサイトスクリプティング」 * XSS脆弱性の原因は特殊記号(メタ文字)を正しく扱っていないこと * PHPで行う対策は特殊文字の「エスケープ」 * https://php-junkie.net/security/xss/ (https://php-junkie.net/security/xss/) * 属性値はダブルクオートで囲む * 理由:ダブルクオートがないとエスケープ処理できないから? * 「htmlspecialchars」によるエスケープ * 読み方は「エイチティーエムエルスペシャルチャーズ」 * 最大4つの引数をとり、セキュリティ上は最初の3つが重要 * 第一:変換対象文字列(例.$p) * 第二:変換方法(例.ENT_COMPATかENT_QUOTES) * 第三:文字エンコーディング(例."UTF-8") * フレームワークのエスケープ処理 * bladeの{{ }}(Laravelのe()) -> htmlspecialchars: ENT_QUOTES [source](https://github.com/laravel/framework/blob/56dcc1e23bcb8dca99b6fb533cdb28f3a777bb9e/src/Illuminate/Support/helpers.php) * XSSに対する保険的対策「X-XSS-Protectionレスポンスヘッダ」 * 利用者によるXSSフィルタ設定を上書きして有効化・無効化を設定したり、その動作モードを変更したりするための機能 * htmlspecialcharsは根本的対策である一方で、対策漏れが発生しやすい。そのための保険的位置付け * すべてのHTTPレスポンスで以下を出力することが望ましい * X-XSS-Protection: 1; mode=block * [MDN X-XSS-Protection](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-XSS-Protection) * [HTTPヘッダーセキュリティチェッカー](https://rakko.tools/tools/26/) * クッキーにHttpOnly属性を付与する * [PHPのマニュアル](https://www.php.net/manual/ja/session.configuration.php#ini.session.cookie-httponly) --- ### 第8回 2021/03/27 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.138(4.3.2) ~ P.157(SQLインジェクション攻撃によるデータ改ざんの手前) #### 進捗 P.138(4.3.2) ~ P.150(4.3完了) #### ファシリテーター むちょこ #### 書記 Hiroさん #### ディスカッション * P142)init関数がわからない。 * 何もしていない(ダミー)関数。ユーザ定義関数である(もとからある関数ではない)。これを使う理由はonloadで使いたかったから。 * P144)mb_ereg_replaceの正規表現のスラッシュがたくさんある理由 * 最初の二つはスラッシュ、最後の一つはシングルクオーテーションのエスケープ * P144)mb_ereg_replaceの正規表現の第二引数は何に置換しているか * [\1]一致した文字列の1番目に対応する文字列に置換します。 * https://murashun.jp/article/programming/regular-expression.html * P144)PHP正規表現を簡単に試すサイト教えてほしい * https://php-regexp.a-zumi.net/preg_replace * P144)スクリプトが何をしているのかわからない * 無理やり</script>を閉じて自分のスクリプトを実行 * P146)文字列リテラルとは? * “xxx” や ‘xxxx’ みたいな文字列 * 1とか2は数値リテラル * P150)以下のケースもエラーメッセージからの情報漏洩のケース?(説明の内部情報にあたるかな?) * ログイン時のチェックで、IDがOK、パスワードが間違っている場合のメッセージを「パスワードが間違ってい」と表示すると、そのIDが有効であることが分かる →そのIDで総当りのパスワードを試みることができてしまう https://www.ipa.go.jp/security/awareness/vendor/programmingv1/b09_03.html * P150)IDとパスワードを違うページで入力するサイトがある。その理由。 * 宿題!! #### 学習MEMO * P141)urlチェック関数 * 条件式の\Ahttpsの直後の“?”は「直前の文字(=s)が0回か1回」の意 * P142)init関数とは?←初期化する関数?←何を初期化している?それともこの例ではただの空っぽの関数? * bodyのonloadで初期化するみたいなことをすることが多いので、そういう例として`init`なのではないかと。 * mb_ereg_replace関数 * https://www.php.net/manual/ja/function.mb-ereg-replace.php * 第一引数:正規表現パターン<'([\\\\\\\\\\'"])'>←なぜこう書くのかわからなかったので知りたい * 第二引数:置換文字列<'\\\\\1'>←なぜこう書くのかわからなかったので知りたい * この辺は、文字列としてのエスケープと、正規表現としてのエスケープで二回必要になるためです。 https://www.php.net/manual/ja/regexp.reference.escape.php この辺など参考になるかと。 * 第三引数:調べたい文字列<$s> ### 第9回 2021/04/03 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.151(4.4はじめ) ~ P.168(「プレースホルダーを用いた様々な処理」の直前) #### 進捗 P.151(4.4はじめ) ~ P.166(「参考:LIKE術語とワイルドカード」の直前) #### ファシリテーター むちょこ #### 書記 まっきーさん #### ディスカッション * P152)44-001のコードは値そのまま突っ込む人っているの?って思った(婦人さん) * P154)Xパスとして無効な構文・・・のところががわからない(婦人さん) * Xパス表記法がXMLの書き方を指定できる、ということ(むちょこさん)←あとで追記します * ヌル3つって必要?2つでいいのでは?(婦人さん) * (議論) * データベース覗いてみると7つめの「コメント」カラムを発見!!(婦人さん) * さいしょヌル2つにして攻撃してみたら3つあることに気づいた、的な?(Hiroさん)← * なんで攻撃側がテーブル構造知ってるの?と突っ込みたくなる(junさん) * P160でもヌルが続いている(Hiroさん) * P158)SQLインジェクションはデータベースだけが対象という印象だったけどこれはこわいと感じた(婦人さん) * P161)MySQLだけはダブルクオートでもいける。MySQLだけ特殊(むちょこさん) * 基本シングルクォートと覚えておけばよさそう(婦人さん) * これは直打ちするときの話?(Hiroさん) * アプリケーション側はなんであっても関係なし。送られたSQL文の中でMySQLだけはダブルクオートで囲われた文字列リテラルも認識してくれる(むちょこさん) * 参考サイト(イッシーさんより) * SQLの文字列リテラルについて https://style.potepan.com/articles/24875.html * 今でもPDOで書く人っているの?(婦人さんHiroさん) * フレームワークを飛び出して書きたい層がいる気がする(むちょこさん) * フレームワーク使うなら飛び出して書かないほうがいい(むちょこさん) * P164)認証をくぐり抜けるところについて、ログインのところ(P156-157)はP162のa,bでは回避できないのでは?複文?(Hiroさん) * プレースホルダーでここも防ぐことはできる。ORもバインドとして渡されればただの文字として識別されるのでSQL文になることはない(むちょこさん) * 複文だと情報漏えい防げないと書いてあるが、ここでの情報漏えいとはユニオンセレクトのことであってる? * 合ってる。複文は情報漏えいには効果はない。データベース改ざんするときはUPDATEなどが必要になる。(むちょこさん) * 複文かどうかはセミコロンがあるかどうか。例えばP162のような(むちょこさん) * P166)デフォルトが動的になっているのはどうしてなんだろう?(Hiroさん) * PHPの肌感的には緩い方にデフォルト設定されていることが多い印象(むちょこさん) * Amazonレビューで以下コメントをみつけた。『PDO::ATTR_EMULATE_PREPARES のデフォルト値が true になっている理由はデータベースの負荷が問題になったからである。』 ### 第10回 2021/04/10 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.166(「参考:LIKE術語とワイルドカード」) ~ P.181(「確認画面がある場合のCSRF攻撃」の直前) #### 進捗 P.166(「参考:LIKE術語とワイルドカード」) ~ P.184(「ファイルアップロードフォームでのCSRF攻撃」の直前) #### ファシリテーター むちょこ #### 書記 Hiroさん #### ディスカッション * P179)罠ファイルを置く場所はどこか 置く場所は攻撃者が用意したサーバー。そのリンクを掲示板などに載せて踏ませる。攻撃対象のサイトをいじる必要はない。 * P175)CSRFはシーサーフと読む * P182)確認画面がない場合と同じとは 実行画面にデータをポストしているので、前ページで使用した罠サイトのスクリプトがそのまま使える * P184)ウィザード形式とは アプリインストール時の次へ->次へみたいなやつ 対話形式のように、選択していくことで必要な操作が自動的に終了するしくみのこと。 #### 学習MEMO ##### 4.5 「重要な処理」の際に混入する脆弱性 (P.175) この章で学ぶこと 取り消しできない「重要な処理」(クレジットカード決済、メール送信など)に関する脆弱性**CSRF**や**クリックジャッキング**について ##### 4.5.1 クロスサイト・リクエストフォージェリ(CSRF) ###### 概要 CSRF脆弱性とは 利用者が意図していないうちに「重要な処理」が勝手に実行されてしまう可能性のある脆弱性のこと。 Web APIでもCSRF脆弱性が混入する場合がある。 個人情報を盗むなど、「重要な処理」の悪用以外は含まれない。 影響例 * 利用者のアカウントによる物品の購入 * 利用者の退会処理 * 利用者のアカウントによるSNSや問い合わせフォームなどへの書き込み * 利用者のパスワードやメールアドレスの変更 ###### 攻撃手法と影響 (P.176) 前提 入力-実行でパスワード更新ができる 動作条件 * POSTメソッドで実行パスがリクエストされる * ログイン状態である * POSTパラメータpwdの値にパスワードが指定されている 攻撃例 攻撃対象サイトにログイン済みのユーザ(被害者)が 攻撃者のサイトにアクセスすると 被害者のブラウザから攻撃対象サイトへ勝手にパスワード変更のPOSTリクエストが送られる 攻撃者が指定したパスワードに変更されるので、その後情報漏洩につながる可能性も。 ### 第11回 2021/04/24 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.184(「ファイルアップロードフォームでのCSRF攻撃」) ~ P.203(4.5の最後) #### 進捗 #### ファシリテーター むちょこ #### 書記 junさん #### ディスカッション * P184)ファイル名がランダムな文字列で攻撃者が想定できなければ対策になる? 他の人がそのファイルにアクセスする→登録されたファイルをアプリケーションが表示するなどアクセスすればアップしたファイルによる攻撃が実行される恐れがある * P191)POSTリクエストって全部CSRC対策しません? フレームワークだとPOSTはすべて対策しているので… 結論、徳丸さんは古い人! * P193)openssl_random_pseudo_tytesの「pseudo」ってなんて読むの? pseudoはカタカナ読みでは「スードウ」。 「にせの」「〜まがいの」を意味する形容詞 * P196)ログイン後によくメールが来るやつかな そうかも? ログインされてしまうようになったパスワード変更などの通知が該当、その結果のログイン後の通知は別のもの? どちらだろう?(宿題) * P202)DENY→デニー? デナイ(Google先生の発音で確認) * ワンタイムパスワードってどういうときに使う? 二要素認証(二段階認証とは異なる) 経路が違う2つの認証を組み合わせるのが二要素認証(同じ経路は二段階) 知識認証、生体人書、書字認証 知識認証、生体認証、所持認証 のうち2つを組みあわせる ID/パスワードと上記の組み合わせなど ワンタイムパスワードのみの入力のケースとしては銀行の決済とか * P198)(本題から外れるが)QRコードなどでログインできるようクエリパラメータにID/パスワードを設定すると、Refererにより他サイトで情報が漏れる危険性あり? 問題になりそう。でもどうやってログインさせる? 要望:紙でID/パスワード渡さないと行けないケースなので、それを見て入力させるのではなく、QRコードなどでログインまでできるようにしたい 紙に片仮名でよみがなを記載する 短い仮パスワードを伝えて、新たにパスワードを設定してもらう とか、 IP制限、ユーザによる入力などが理想かな 別の例で、現場だとPCにログインするためのなので紙でID/パスワードの提供必須 2段階認証、生体認証 答え出ず… #### 学習MEMO ###### ファイルアップロードフォームでのCSRF攻撃 (P.184) クロスオリジンに対応したXMLHttpRequestによって、ファイルアップロードを伴う攻撃が可能。 サンプルスクリプト: ログイン後、アップロードされたファイルを画像として出力するスクリプト。 Refererヘッダ・Originヘッダは確認しない。 罠: 正規サイトにログイン済みのユーザが罠サイトにアクセスすると 画像の代わりにphpinfo()を実行するPHPファイルをアップロードするスクリプト。 クロスオリジン要求のエラーは出るものの、アップロード処理自体は正常に完了する。 攻撃者がアップロード後のファイルにアクセスすると、phpinfo()で出力された正規サイトの情報が閲覧できてしまう。 ###### 認証機能のないWebアプリケーションに対するCSRF攻撃 (P.188) 不正な投稿などが業務に支障をきたすリスクが大きい場合は、認証機能のないWebサイトにもCSRF攻撃対策を行うと良い。 ###### 内部ネットワークに対するCSRF攻撃 (P.189) CSRF攻撃では、内部ネットワークに接続されたサーバも攻撃可能。 XSSなど他の受動的攻撃についても可能なので、内部システムであっても脆弱性対策は必要。 ###### 脆弱性が生まれる原因 * form要素のaction属性にはどのドメインのURLでも指定できる = 他のサイトからでもリクエストを送信できる * クッキーに保管されたセッションIDは、対策サイトに自動的に送信される = 経由サイトに関わらず、セッションIDのクッキーが送信されて認証が通ってしまう 正常なリクエストとCSRF攻撃によるリクエストの違いは、Refererヘッダのみ。 クッキー以外でも、自動的に送信されるパラメータを使ってセッション管理しているサイトはCSRF脆弱性の可能性がある。 ###### 対策 (P.190) * CSRF対策の必要なページを区別する * 正規利用者の意図したリクエストを確認できるよう実装する ###### CSRF対策の必要なページを区別する 対策しない: 商品カタログページなど、外部からリンクされることが好ましいページ 対策する: パスワード変更の確定画面など、他のサイトから勝手に実行されると困るページ 開発プロセスですること 1. 要件定義工程で機能一覧を作成し、CSRF対策の必要な機能にマークする 2. 基本設計工程で画面遷移図を作成し、CSRF対策の必要なページにマークする 3. 開発工程でCSRF対策を作り込む ###### 正規利用者の意図したリクエストであることを確認する (P.191) 対象のアプリケーション上で正規利用者が自ら実行した結果のリクエストであることを確認する 具体的な方法 * 秘密情報(トークン)の埋め込み * パスワード再入力 * Refereのチェック ###### 秘密情報(トークン)の埋め込み (P.192) CSRF攻撃対策が必要なページに、秘密情報(トークン)を要求することで判別する。 最近はアプリケーションフレームワーク側でトークンの生成とチェックの機能を持つものが増えてきたので、その機能を有効化して活用すると良い。 トークンは、第三者に推測されにくい乱数を用いて生成する。 このような性質を持つ乱数を「暗号論的疑似乱数生成器」と呼ぶ。 ###### PHPで利用できる暗号論的疑似乱数生成器 * /dev/urandom から読み込み(Windows以外で利用可能) * /dev/urandom は乱数が取得できるファイル * openssl_random_pseudo_bytes(PHP5.3以降) * random_bytes(PHP7.0以降) bin2hex(): バイナリのデータを16進表現に変換する https://www.php.net/manual/ja/function.bin2hex.php 1. 実行画面の直前の画面でトークン埋め込み 2. セッションに保存されたトークンと同じトークンをフォームで送信する 3. 実行画面で、セッションに保存されたトークンとPOSTリクエストで送られたトークンが一致するか確認 ※トークンが空の場合を見逃さないように注意。また、トークンを受け取るような重要な処理では機密情報がRefereで漏れないようにPOSTリクエストにする ###### パスワード再入力 (P.194) * CSRF対策 * 正規利用者であることの再確認 パスワードの確認は最終実行ページで行う ###### Refererのチェック 実行画面の1つ手前のページURLがRefereにセットされていることを確認する デメリット * 正規利用者の中にRefereが送信されないように設定している人もいる * プログラムの書き方によって漏れが生じやすい メリット * 対策のためのプログラミングの量が最も少ない 使いどころ 社内システムなど利用者の環境が限られる && 既存アプリケーション ###### CSRF対策の比較 (P.195) 特別な理由がなければトークン埋め込みが無難そう ###### CSRF攻撃への保険的対策 (P.196) 「重要な処理」の実行後に、対象利用者のメールアドレス宛に処理内容を通知することで 万が一の場合にも被害を最小限に抑えることが期待できる。 これはCSRF攻撃だけでなくXSS攻撃にも有用。 ただし、通知メールを送るときは盗聴などのリスクを避けるため、重要情報は含まずに実行された事実のみを通知するべき。。 ###### 対策のまとめ 根本的な対策 * CSRF対策の必要なページを区別する * 利用者の意図したリクエストであることを確認する 利用者の意図したリクエストであることの確認方法 * トークンの埋め込み * パスワード再入力 * Refereのチェック 保険的対策 「重要な処理」の実行後に、登録済みメールアドレスに通知メールを送信する ##### クリックジャッキング (P.197) ###### 概要 クリックジャッキングとは、利用者が気づかないうちに攻撃対象サイトでのクリックを誘導する攻撃手法。 クリックジャッキング脆弱性があると、被害者の権限で「重要な処理」が実行させられる可能性がある。 ###### 攻撃手法と影響 (P.198) 題材:Twitter風掲示板 ###### Twitterのウェブインデント機能 クエリー文字列を投稿フォームに埋め込める機能 利用者が投稿ボタンをクリックすると、攻撃者が用意した任意の文字列が投稿されてしまう ###### サンプルスクリプトの説明 ログイン機能を持つ掲示板 * テキストエリアに入力して「投稿」ボタンを押すと投稿される * intentパラメータの値がテキストエリアに設定される 罠 1. ボタンをクリックさせるための偽画像を表示 2. iframe要素で攻撃対象のフォームを上から重ねる 3. iframe要素を透明にする ユーザは偽画像の「応募」ボタンをクリックしたつもりが、実際には攻撃対象フォームの「投稿」ボタンをクリックしてしまう ###### 脆弱性が生まれる原因 (P.202) バグではなく、HTMLの仕様を悪用した攻撃 ###### 対策 ブラウザのX-Frame-Optionsという仕様に対応すると容易に対策できる * DENY: frameなどの内側で表示されなくなる * SAMEORIGIN: アドレスバーに表示されたオリジンと同じオリジンなら表示される 「重要な処理」の手前の入力フォームでX-Frame-Optionsヘッダを出力するか すべてのページで出力しておいても良い。 ###### 保険的対策 (P.203) CSRF対策と同様に、「重要な処理」の実行後に登録済みメールアドレスに通知メールを送信する ###### まとめ X-Frame-Optionsヘッダで容易に対策できるので怠らずに対策すべし ### 第12回 5月15日(土) 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.204(「セッション管理の不備」)~ P.226(「4.6.4脆弱性が生まれる原因」の直前) #### 進捗 P.204(「セッション管理の不備」)~ P.226(「4.6.4脆弱性が生まれる原因」の直前) #### ファシリテーター むちょこ #### 書記 #### ディスカッション #### 学習MEMO ##### セッション管理の不備 (P.204) この章で学ぶこと「セッション管理機構そのものや、その使い方に起因する脆弱性について」 ###### セッションハイジャックの原因と影響 第三者がセッションIDを悪用して成りすますことを**セッションハイジャック**と呼ぶ 第三者がセッションIDを知るための手段 * セッションIDの推測 * セッションIDの盗み出し * セッションIDの強制 ###### セッションIDの推測 * 連番 * 日時やユーザIDを元に生成 * セッションIDの生成ロジックが公開されている * 外部から時間をかけて解読される ###### セッションIDの盗み出し * クッキー生成の際の属性の不備により漏洩 * ネットワーク的にセッションIDが盗聴される * アプリケーションの脆弱性により漏洩 * PHPやブラウザなどプラットフォームの脆弱性により漏洩 * Refereヘッダから漏洩 セッションIDの盗み出しに悪用可能なアプリケーションの脆弱性 * クロスサイト・スクリプティング(XSS) * HTTPヘッダ・インジェクション * URLに埋め込まれたセッションID ###### セッションハイジャック手法のまとめ セッションハイジャックの原因となる脆弱性は多様で、個別対応の必要がある。 セッションIDを発行する箇所で発生する脆弱性 * 推測可能なセッションID * URL埋め込みのセッションID * セッションIDの固定化 ###### セッションハイジャックの影響 (P.206) * 利用者の重要情報の閲覧 * 利用者の持つ権限での操作 * 利用者のIDによるメール、ブログなどへの投稿、設定の変更など ###### 4.6.2 推測可能なセッションID ###### 概要 セッションIDの生成規則に問題があると、利用者のセッションIDが推測される可能性がある。 セッション管理機構は自作せず、実績のある言語やミドルウェアが提供するセッション管理機構を利用することが推奨される。 ###### 攻撃手法と影響 (P.207) 推測可能なセッションIDに対する攻撃 1. 対象アプリケーションからセッションIDを集める 2. セッションIDの規則性の仮説を立てる 3. 推測したセッションIDを対象アプリケーションで試す ###### ありがちなセッションID生成方法 * ユーザIDやメールアドレス * リモートIPアドレス * 日時 * 乱数 上記を元に、組み合わせたりハッシュ化したりすることも。 このうち、ユーザIDや日時は推測可能な元データなので脆弱性の原因となる。 ###### 推測したセッションIDで成りすまし試行する 推測で得たセッションIDをターゲットのアプリケーションで試し、セッションが有効になるかどうかを確認する ###### 成りすましの影響 ターゲットのアプリケーションが持つ機能を利用者が持つ権限によりすべて利用可能。 パスワードの変更および重要な処理の前にパスワードの再入力を要求することで、それらの悪用はできなくなるので保険的対策になる。 ###### 脆弱性が生まれる原因 アプリケーション側でセッション管理機構を自作することが原因となる。 自作する意味がない理由 * 主要なWebアプリケーション開発ツールはセッション管理機構を備えている * 安全なセッションID生成プログラムを開発することは技術的難易度が高い ###### 対策 (P.209) もっとも現実的で効果的な対策は、Webアプリケーション開発ツールのセッション管理機構を利用すること。 やむを得ず自作する場合は、暗号論的疑似乱数生成器を元に、十分な桁数のセッションIDを生成する。 ###### PHPのセッションIDのランダム性を改善する方法 PHPのデフォルト設定でセッションIDを生成するために使われている組み合わせ * リモートIPアドレス * 現在時刻 * 乱数(暗号論的疑似乱数生成系ではない) ありがちなセッションIDの生成方法に該当し、推測される危険性がある php.iniの設定を追加することで改善できる session.entropy_file = /dev/urandom session.entropy_length = 32 /dev/urandomは多くのUnix系OSで実装されている乱数生成器。現段階で大きな問題は見つかっていないので安心と考えて良い。 PHP5.4以降ではデフォルトでこの設定になっているので対策不要。 関連: [DSAS開発者の部屋:PHPのセッションIDは暗号論的に弱い乱数生成器を使っており、セッションハイジャックの危険性がある](http://dsas.blog.klab.org/archives/52136166.html) ###### 参考:自作セッション管理機構にまつわるその他の脆弱性 (P.210) セッション管理機構を自作・カスタマイズする場合は、セッションIDの推測以外の脆弱性にも気を付ける必要がある。 例えば * SQLインジェクション脆弱性 * ディレクトリ・トラバーサル脆弱性 など ###### 4.6.3 URL埋め込みのセッションID ###### 概要 以前はクライアント端末の都合で、セッションIDをクッキーに保存せずにURLに埋め込ませる手法を取ることがあった。 セッションIDをURLに埋め込んでいると、Refererヘッダを経由してセッションIDが漏洩し、成りすましの原因になることがある。 これを防ぐには、URL埋め込みのセッションIDを禁止する設定あるいはプログラミングを行う。 ###### 攻撃手法と影響 (P.211) このセクションでは、URL埋め込みセッションIDを用いている場合にReferer経由で漏洩する様子とその影響を説明する。 ###### セッションIDがURL埋め込みになる条件 * php.iniでsession.use_trans_sidがOnに設定されている * アプリケーション側で明示的にセッションIDの埋め込み処理をしている場合 ###### サンプルスクリプトの説明 (P.212) セッションIDをURL埋め込みにする(クッキーは使わない)設定 ① スタートページ ② 外部リンクが貼られたページ ③ 外部のページ(実は攻撃者の情報収集サイト) 1. ①から②に画面遷移すると、URLにセッションIDが付与される 2. ②から③にセッションID付きのURLがRefererとして送られる 3. 漏洩 ###### RefererによりセッションIDが漏洩する条件 (P.214) * URL埋め込みのセッションIDを使える * 外部サイトへのリンクがある。あるいは、リンクを利用者が作成できる ###### 攻撃のシナリオ 外部から意図的に攻撃を仕掛けることができるのは、利用者がリンクを作成できる場合のみ。 例)Webメール、掲示板、ブログ、SNSなど Webメールの例 1. 攻撃者がターゲットアプリケーションの利用者に対して、URLつきのメールを送信 2. URLがリンクに自動変換される 3. 利用者がリンクから攻撃者サイトにアクセス 4. 利用者のWebメールシステムのセッションIDが、Refererとして攻撃者に漏洩 5. 攻撃者が利用者へ成りすましできる ###### 攻撃ではなく事故としてセッションIDが漏洩するケース (P.215) * サイト運営者が自ら貼ったリンク先の運営者に悪意があった * 利用者がセッションIDを含むURLを第三者に公開した * セッションID付きのURLが検索サイトに登録された ###### 影響 漏洩した場合、セッションハイジャックの影響と同じ影響が出る。 ###### 脆弱性が生まれる原因 (P.216) 直接の原因は、不適切な設定あるいはプログラミング。 意図的にセッションIDをURLに埋め込んだ理由 * 2000年前後に「クッキー有害論」が起こっていた * 携帯電話(フィーチャーフォン)のブラウザがクッキーに対応していないものがあったため、携帯電話向けWebアプリケーションはURL埋め込みのセッションIDが主流だった 現在はクッキーの利用が受け入れられているため、上記のような理由は発生しない。 通常はセッションIDをクッキーに保存する方法が最も安全。 ###### 対策 URL埋め込みのセッションIDを使わず、クッキーに保存するための設定 ###### PHPの場合 php.ini ``` session.use_cookies = 1 session.use_only_cookies = 1 ``` ###### Java Servlet(JSEE)の場合 明示的にURLを書き換える処理を行わなければ大丈夫 ###### ASP.NETの場合 デフォルトではセッションIDはクッキーに保存される 既存サイトの設定変更をする際は、以下のように行う ``` <?xml version="1.0" encoding="UTF-8"> <configuration> <system.web> <sessionState cookieless="false" /> </system.web> </configuration> ``` ###### 4.6.4 セッションIDの固定化 (P.217) ###### 概要 セッションIDの固定化攻撃とは、セッションハイジャックを引き起こす攻撃手法の1つで、セッションIDを外部から強制する方法 攻撃手順 1. セッションIDを入手する 2. 被害者に対して、1のセッションIDを強制する 3. 被害者は標的アプリケーションにログインする 4. 攻撃者は、被害者に強制したセッションIDを使って標的アプリケーションにアクセスする 影響 * 成りすましによる情報漏洩 * 被害者の権限によるアプリケーション機能の悪用 * データの投稿・変更・削除 など 対策 * ログイン時にセッションIDを変更する ###### 攻撃手法と影響 (P.218) ###### サンプルスクリプトの説明 セッションIDをクッキーにもURLにも保持できる設定(こうするとセッションIDの固定化が簡単になる)。 .user.ini(ディレクトリ単位のINIファイル) ``` session.use_cookies=On session.use_only_cookies=false session.use_trans_sid=On ``` 画面構成 1. ユーザIDの入力画面 2. 認証画面 3. 個人情報表示画面 ###### セッションIDの固定化攻撃の説明 (P.220) 1. 攻撃者は利用者に対してセッションIDが含まれるURLでログインするよう誘導する 2. 利用者はクッキーにセッションIDが保存されていない状態で誘導されたURLからログイン 3. 攻撃者が指定したセッションIDが有効となる 4. 攻撃者は同じセッションIDを使って利用者(被害者)の個人情報を閲覧 ###### ログイン前のセッションIDの固定化攻撃 (P.222) ログイン前のページでも、セッション変数を使用していると同攻撃が成立する場合がある。 これを「ログイン前のセッションIDの固定化攻撃」という。 サンプルスクリプト 1. 個人情報の入力 2. 個人情報の確認 3. 個人情報の登録 入力内容はセッション変数に保存され、確認画面から「戻る」リンクをクリックした場合はフォームの各項目に入力内容が反映される仕組み 攻撃手順 1. 攻撃者は利用者に対してセッションIDが含まれるURLから個人情報を入力するよう誘導する 2. 利用者が個人情報を入力したタイミングで、攻撃者が同URLを閲覧する 3. 攻撃者のブラウザに利用者が入力した個人情報が表示される 影響 * 利用者が入力した個人情報の漏洩のみ ###### セッションアダプション (P.225) PHPやASP.NETには、未知のセッションIDを受け入れる特性がある。 これを「セッションアダプション」という。 Tomcatなどではセッションアダプションがないので、勝手に作成したセッションIDは無視される。 セッションアダプションがある方が攻撃が楽だが、 なくても有効なセッションIDを取得することが可能なため対策は必要。 ###### クッキーのみにセッションIDを保存するサイトのセッションIDの固定化 (P.226) クッキーにセッションIDを保持していても、セッションIDの固定化が可能になる場合がある。 クッキーを第三者が設定できる脆弱性の例 * クッキーモンスターバグ * クロスサイト・スクリプティング脆弱性 * HTTPヘッダ・インジェクション脆弱性 その他、通信路上に攻撃者が存在する場合にも改変が可能。 関連: [HTTPSを使ってもCookieの改変は防げないことを実験で試してみた | 徳丸浩の日記](https://blog.tokumaru.org/2013/09/cookie-manipulation-is-possible-even-on-ssl.html) ### 第13回 6月5日(土) 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.226(「(4.6.4) 脆弱性が生まれる原因」)~ P.239(「4.7.2 HTTPヘッダ・インジェクションの直前」) #### 進捗 P.226(「(4.6.4) 脆弱性が生まれる原因」)~ P.239(「4.7.2 HTTPヘッダ・インジェクションの直前」) #### ファシリテーター むちょこ #### 学習MEMO ###### 脆弱性が生まれる原因 (P.226) セッションIDを外部から強制できるのが原因。 本質的な対策をすべて満たすことは困難なので、セッションIDの固定化攻撃が行われてもセッションハイジャックは防ぐように対策するのが一般的。 セッションハイジャックの防止には、認証が成功した際にセッションIDを変更することが有効。 ###### 対策 (P.227) 認証後にセッションIDを変更する PHPの場合 session_regenerate_id($delete_old_session) $delete_old_sessionをtrueにすると、変更前のセッションIDに対応するセッションを削除してくれるので 常にtrueにするのが良い。 1. ログイン処理 2. セッションIDの変更 3. データをセッションに保存 という流れで実装する。 ###### セッションIDの変更ができない場合はトークンにより対策する Webアプリケーションの開発言語やミドルウェアによっては、セッションIDを明示的に変更できないものがある。 その場合には代わりにトークンによる対策方法を行うと良い。 トークンによる対策方法 1. ログイン処理後に暗号論的疑似乱数生成器を用いてトークンを生成 2. 生成したトークンをクッキーとセッションに保存 3. 認証が必要なページでクッキーとセッションのトークンが一致していることを確認 ###### ログイン前のセッションIDの固定化攻撃の対策 (P.229) ログインIDの固定化攻撃に完全に対策することは困難なため、ログイン前にはセッション管理機構を使わずにhiddenパラメータで値を引きまわすのが現実的で効果的な対策となる。 やむを得ずログイン前にセッション変数を使う場合には、秘密情報をセッション変数にセットするページで毎回セッションIDを変更することで対策となる。 ただし、その場合はセッションIDを変更したレスポンスをブラウザが受信できなかった場合にセッションが維持できなくなるという副作用がある。 ###### 4.6節のまとめ (P.230) セッションハイジャックは大きな影響がある。 セッション管理不備の対策 * セッション管理機構を自作せずアプリケーション開発ツールのものを使う * クッキーにセッションIDを保存する * 認証成功時にセッションIDを変更する * 認証前にはセッション変数に秘密情報を保存しない ##### 4.7 リダイレクト処理にまつわる脆弱性 (P.231) Webアプリケーションには、外部から指定したURLにリダイレクトするものがある。 典型的な例 ログインページのパラメータにURLを指定しておき、ログイン成功後にそのURLにリダイレクトするサイト リダイレクト処理に際して発生する代表的な脆弱性 * オープンリダイレクト脆弱性 * HTTPヘッダ・インジェクション脆弱性 ###### 4.7.1 オープンリダイレクト ###### 概要 パラメータにより指定したURLにリダイレクトする機能のうち、任意のドメインにリダイレクトできる脆弱性を「オープンリダイレクト脆弱性」と呼ぶ。 特に利用者が知らないうちに別ドメインに遷移する場合、フィッシング詐欺に悪用される危険性がある。 フィッシングとは、著名なWebサイトなどを偽装したサイトに利用者を誘導して、個人情報などを入力させる手口。 他にも、プログラムやデバイスドライバなどを配布するサイトにオープンリダイレクト脆弱性があると、そのサイトからマルウェア(不正プログラム)を配布される可能性がある。 対策 可能であれば、リダイレクト先を固定にする。 固定が難しい場合は、リダイレクト先を許可されたドメインのみに制限する。 ###### 攻撃手法と影響 (P.232) サンプル 47-001.php ログインフォーム 47-002.php ログイン認証し、成功すればPOSTパラメータで指定されたURLにリダイレクト 47-003.php GETパラメータが空のときにリダイレクト先となるログイン完了画面 正常系 GETパラメータが空なので、ログインが空なら47-003.phpにリダイレクトされる 攻撃例 1. ログインが失敗したと見せかけて再度IDとパスワードを入力させる偽装ページを用意 2. 正規のログインページのリダイレクト先に偽装ページへのURLパラメータをつけてリンクを拡散 3. 正規サイトのログイン情報が取得される ###### 脆弱性が生まれる原因 (P.236) * リダイレクト先のURLを外部から指定できる * リダイレクト先のドメイン名のチェックがない オープンリダイレクトが脆弱性にならない条件 * もともと外部のドメインに遷移する仕様である * 利用者にとって外部ドメインに遷移することが自明である 例)バナー広告など ###### 対策 * リダイレクト先のURLを固定にする * リダイレクト先のURLを直接指定せず番号指定にする * リダイレクト先のドメインをチェックする リダイレクト先のURLを固定にする → 固定のURLに遷移する仕様 それがだめなら リダイレクト先のURLを直接指定せず番号指定にする → URLではなく、予め用意した対応する番号でリダイレクト先を指定できるようにする それもできないなら リダイレクト先のドメイン名をチェックする → 任意のドメインには遷移できないようにする。ただし、このチェックは落とし穴が多いのでできるだけURLの固定や番号指定が望ましい URLチェックの失敗例 * URL中に許可したいドメインが含まれていることを確認しているが、URLの途中にそのドメインが入っているだけでも通過してしまう * URLがスラッシュから始まっていることを確認していて一見外部ドメインにはリダイレクトされなさそうだが、//で始まるURLが指定されるとすり抜けてしまう * URLが http://example.jp で始まっていることを確認しているが、HTTPヘッダ・インジェクション攻撃に対して脆弱な場合がある 望ましい例 http://example.jp で始まることと、その後はURL(URI)で使用できる文字でのみ構成されていることを確認する ###### クッションページ (P.239) 外部ドメインに対してはそのままリダイレクトせず、利用者に注意喚起文とリンクを掲載したページをまず表示してから遷移する。 このページをクッションページと呼ぶ。 クッションページをはさむことにより、フィッシング詐欺の防止につながる。 ### 第14回 6/12(土) 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.240(「4.7.2 HTTPヘッダ・インジェクション」) ~ P.256(「4.8.2 クッキーのセキュア属性不明の直前」) #### 進捗 P.240(「4.7.2 HTTPヘッダ・インジェクション」) ~ P.256(「4.8.2 クッキーのセキュア属性不明の直前」) #### ファシリテーター 林 雅之さん #### 学習MEMO ###### 4.7.2 HTTPヘッダ・インジェクション (P.240) HTTPヘッダ・インジェクションは、リダイレクト処理以外にクッキー出力など、すべてのHTTPレスポンスヘッダの出力処理で発生する恐れのある脆弱性 ###### 概要 リダイレクトやクッキー発行など、外部からのパラメータを元にHTTPレスポンスヘッダを出力する際に 外部から指定された改行をそのまま出力してしまうことによって、HTTPヘッダ・インジェクション脆弱性が発生する。 この脆弱性を悪用したHTTPヘッダ・インジェクション攻撃によって * 任意のクッキーの生成 * 任意のURLへのリダイレクト * 表示内容の改変 * 任意のJavaScript実行によるXSSと同様の被害 といった影響が起こり得る。 HTTPヘッダの出力部分は手作りせず、ヘッダ出力用のライブラリやAPIを利用し、レスポンスヘッダを構成する文字列中に改行コードが含まれていないことを確認することで対策可能。 ###### 攻撃手法と影響 (P.241) サンプルスクリプト urlというクエリ文字を受け取り、urlの指すURLにリダイレクトするCGI ###### 外部ドメインへのリダイレクト (P.242) 攻撃例 まずurlパラメータの前方に正規URLを指定することでチェックを回避し、 その後に改行を指定することでLocationヘッダを追加(上書き)して外部ドメインへリダイレクトさせている。 ###### HTTPレスポンス分割攻撃 (P.244) HTTPヘッダ・インジェクション攻撃により複数のHTTPレスポンスを作り出し、キャッシュサーバー(プロキシサーバ)に偽のコンテンツをキャッシュさせる攻撃手法。 HTTP/1.1では、複数のリクエストをまとめて送信することができ、その場合はレスポンスもまとめて返される。 その特性を利用して偽のコンテンツをキャッシュサーバに誤認させキャッシュさせる攻撃があった。 考察) 最近はHTTP2が主流で、古いサービスであってもそこは優先的に対応するなどしてHTTP/1.1は淘汰されつつあるのでこの脆弱性は発生しにくいと思って良いのでは。 →そうでもなさそう [手軽にHTTP2通信を判断する方法](https://nelog.jp/http2-browser-extensions#%E6%89%8B%E8%BB%BD%E3%81%ABHTTP2%E9%80%9A%E4%BF%A1%E3%82%92%E5%88%A4%E6%96%AD%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95) ###### 任意のクッキー生成 (P.245) urlパラメータの値に、まず正しいURLを指定し、その後ろに改行とSet-Cookieヘッダを指定することで 任意のクッキーをブラウザにセットしている例。 セッションIDの固定化攻撃と組み合わせて成りすましに使われる危険性がある。 ###### 偽画面の表示 (P.246) HTTPヘッダ・インジェクション攻撃によって偽の画面を表示させる例。 pageidというクエリー文字を受け取って、PAGEIDという名前のクッキーにそのまま保存するCGI。 pageidクエリーに改行コードを2回連続で指定することで、その後の文字列をレスポンスボディと認識させ、画面に出力させている。 同じ手口で、単なる文字列の出力だけでなく、偽のフォームを作成して個人情報を盗んだり、JavaScriptを実行させてクッキー値を盗むことも可能。XSSと共通の影響がある。 ###### 脆弱性が生まれる原因 (P.249) HTTPレスポンスヘッダが改行区切りで定義できる性質を悪用して、 パラメータの中に改行を含められたときに、改行がそのままレスポンスとして出力されることがHTTPヘッダ・インジェクション脆弱性の原因となる。 ###### HTTPヘッダと改行 (P.250) URLの場合、リダイレクト処理にURLを渡す時点で改行が含まれていることは異常。 クッキー値の場合は、値をパーセントエンコードしていればHTTPヘッダ・インジェクション脆弱性の余地はない。 ###### 対策 もっとも確実な対策は、外部からのパラメータをHTTPレスポンスヘッダとして出力しないこと * リダイレクト先をURLとして直接指定するのではなく、固定にするか番号などで指定する * Webアプリケーション開発ツールの提供するセッション変数を使ってURLを受け渡す どうしても外部からのパラメータをHTTPレスポンスヘッダとして出力しないといけない場合 * リダイレクトやクッキー生成を専用APIにまかせる * ヘッダ生成するパラメータの改行文字をチェックする 「リダイレクトやクッキー生成を専用APIにまかせる」 (P.251) Webアプリケーション開発用の言語やライブラリに用意されているHTTPヘッダを出力するための高機能な関数を使う。 中でも、できるだけクッキー生成やリダイレクト機能を提供するライブラリ機能を利用し、汎用のレスポンスヘッダ出力機能を使うのは最後の手段にする。 ただし、ライブラリ機能を使っても完全な脆弱性対策にはならないため改行文字のチェックも併用して行う。 「ヘッダ生成するパラメータの改行文字をチェックする」 HTTPレスポンスヘッダに関するAPIには改行をチェックしないものが多く存在するため、アプリケーション側で自衛する。 * URL中の改行はエラーとする * クッキー値の改行はパーセントエンコードする(※ライブラリ側でエンコードしている場合を除く) ###### PHPのheader関数はどこまで改行をチェックするか (P.253) PHP5.4.38, PHP5.5.22, PHP5.6.6より前のバージョンでは、PHPのheader関数のチェックでのみリダイレクト処理を実装すると危険。 (MEMO) CentOS 7系の標準yumリポジトリでは、PHP5.4.16がインストールされる ###### 4.7.3 リダイレクト処理にまつわる脆弱性のまとめ オープンリダイレクト脆弱性とHTTPヘッダ・インジェクション脆弱性への対策 * リダイレクト処理にはできるだけ専用のAPI(ライブラリ関数)を使用する * 以下のいずれかを実施する * リダイレクト先を固定にする(推奨) * 外部から指定するリダイレクト先のURLは、必ず文字種とドメイン名をチェックする ##### 4.8 クッキー出力にまつわる脆弱性 (P.254) クッキーにまつわる脆弱性は大きく分けて2つ * クッキーを利用すべきでない目的でクッキーを使っている クッキーはセッションIDの保管場所として利用すべきであり、データそのものをクッキーに保存するのは良くない。 * クッキーの出力方法に問題がある * HTTPヘッダ・インジェクション脆弱性 * クッキーのセキュア属性不備 ###### 4.8.1 クッキーの不適切な利用 一般的に、セッション管理機構ではセッションIDのみをクッキーに保存し、データ自体はサーバ上、DB上に保存する。 クッキーに保存すべきでない情報をクッキーに保存すると脆弱性が発生する場合がある。 「クッキーに保存すべきでない情報」 クッキー値はアプリケーションの利用者による書き換えが可能。 書き換えられると困る情報をクッキーに保存すると脆弱性の原因になる。 例)ユーザID、権限情報など 「参考:クッキーにデータを保存しない方がよい理由」 (P.255) クッキーとセッション変数ではセッション変数の方が便利で安全なため 脆弱性にはならない場合でも、クッキーよりもセッション変数にデータを保存する方がよい。 セッション変数は次の理由から漏洩のしにくさを制御可能。 * 機密性の高い情報を表示する場合にパスワードの再入力(再認証)を求めるように実装することができる。 (MEMO)クッキーに情報を入れてしまうと、ユーザ側が認証済みデータを持っているので再認証がしづらい(?) * セッションに入っている情報はセッションタイムアウトすると表示されなくなる セッションやサーバをまたがって情報を保存する必要性がある場合にはクッキーを使用する 例)「ログインしたままにする」機能など ###### パディングオラクル攻撃とMS10-070 (P.256) ### 第15回 7/3(土) 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.257(「4.8.2 クッキーのセキュア属性不備」)~ P.269(「4.9.2 メールヘッダ・インジェクションの直前」) #### ファシリテーター #### 学習MEMO ###### 4.8.2 クッキーのセキュア属性不備 (P.257) ###### 概要 Secure属性が指定されたCookieはHTTPSの場合のみサーバに送信される。 アプリケーション側がHTTPS通信を利用していてもCookieにSecure属性が指定されていないケースでは、Cookieが平文で送信され盗聴の可能性がある。 Cookieが盗聴されると、セッションIDが漏洩して成りすましの被害にあう危険性がある。 CookieのSecure属性不備への対策は、Secure属性を設定すること。 ただし、HTTPとHTTPSの混在するサイトではセッションIDのCookieに対してSecure属性を設定すると不具合の原因になってしまうので、代わりにSecure属性つきのトークンを発行し、ページごとにトークンを確認する方法がある。 ###### 攻撃手法と影響 (P.258) クッキーのセキュア属性不備を悪用した攻撃パターンとその影響について。 脆弱性のある正規サイト * HTTPSでかつセキュア属性がオフになっている環境 * 悪用防止のため、クッキーのパスを限定し、セッションID名称を変更してある 罠サイト * HTTP環境 * ユーザからは見えない画像で、正規サイトへリクエストを送るようになっている 1. 被害者がset_non_secure_cookie.phpにアクセス 2. 被害者のブラウザにクッキー(PXPSESID)がセットされる 3. 被害者が罠サイトにアクセス 4. 罠サイトが被害者のブラウザに対して正規サイトの画像をHTTPリクエストするよう指示 5. 被害者のブラウザから送信されるリクエストヘッダに平文のクッキー値が含まれる 6. 攻撃者がクッキー値を盗聴→セッションハイジャックなどに悪用 ###### 脆弱性が生まれる原因 (P.261) 直接原因は、単にsecure属性をつけていないこと。 secure属性をつけない原因は、次の2つ。 * 開発者がsecure属性を知らない * secure属性をつけるとアプリケーションが動かなくなる secure属性がつけられないアプリケーション 「cookieにsecure属性がつけられないアプリケーションとは」 HTTPとHTTPSが混在するWebアプリケーション。 解決策 → サイト全体をHTTPSにする"常時TLS"にした上で、secure属性をつける ###### 対策 (P.262) secure属性不備の対策は、secure属性をつけること。 「セッションIDのcookieにsecure属性をつける方法」 PHPの場合 php.iniでsession.cookie_secure = Onに設定する Apache Tomcatの場合 HTTPS接続されたリクエストに対しては自動でsecure属性が設定される ASP.NETの場合 web.configで設定する 「トークンを用いた対策」 (P.263) どうしてもsecure属性をつけられない場合は、トークンを利用してセッションハイジャックを防止する。 セッションIDの固定化の対策で紹介された方法と同様、トークンを保持するcookieにsecure属性をつける。 こうすることで、仮にセッションIDを盗聴された場合でもHTTPSのページではセッションハイジャックを防止できる。 サンプルスクリプト /48/48-001.php secure属性をつけたcookieとセッションIDを再生成したセッションにトークンを保存 /48/48-002.php cookieに保存されたトークンとセッションに保存されたトークンが一致していることを確認 トークンが一致しているかどうかは、タイミング攻撃に耐性のあるhash_equals()関数がオススメ。 HTTPでアクセスすると、secure属性つきのcookieは受け取れないため、認証失敗となる。 「トークンにより安全性が確保できる理由」 (P.266) トークンはサーバとブラウザの双方向で確実に暗号化され、 HTTPSのページを閲覧するには第三者の知りえないトークンが必要であることから 安全性が確保されていることになります。 ###### セキュア属性以外の属性値に関する注意 セッションIDを保持するcookieの属性 「Domain属性」 特別な事情でセッションIDを複数のサーバ間で共有したい場合に設定する。 デフォルト状態が最も安全。 「Path属性」 ディレクトリ毎に異なるセッションIDを発行したい場合に設定する。 これを変更しても安全性には影響しない。 参考: https://qiita.com/HAYASHI-Masayuki/items/88a2b784bde1be9580a8 https://qiita.com/ockeghem/items/6590b2e18af1d062e780 「Expires属性」 ブラウザを終了した後も認証状態を維持したい場合に設定する。 通常は設定せず、ブラウザ終了と同時にcookieが削除される状態にする。 「HttpOnly属性」 JavaScriptからcookieを参照させたくないときはOnにする。 通常はOnにしておくと良い。 PHPの場合はphp.iniで設定できる。 ###### まとめ (P.267) 原則としてcookieはセッションIDのみに用いること、 HTTPS通信を用いるアプリケーションのcookieにはsecure属性を指定することが重要 ##### 4.9 メール送信の問題 (P.268) メール送信機能に不備があると、第三者のメール中継や、意図とは異なるメール送信の危険性がある。 この章では、Webアプリケーションのメール送信機能にまつわる脆弱性について説明する。 ###### 4.9.1 メール送信の問題の概要 メール送信の問題 * メールヘッダ・インジェクション脆弱性 * hiddenパラメータいnよる宛先保持 * メールサーバーによる第三者中継 「メールヘッダ・インジェクション脆弱性」 メールのヘッダフィールド(宛先や件名など)に改行を挿入することにより 新たなフィールドを追加したり、本文を改ざんする攻撃をメールヘッダ・インジェクションという。 「hiddenパラメータによる宛先保持」 メールの送信先などをhiddenパラメータに指定しているフォームでは、 値を任意のアドレスに変更され迷惑メールの送信に悪用される可能性がある。 「参考:メールサーバによる第三者中継」 (P.269) メールサーバの設定に問題があると、第三者のメールを中継してしまい迷惑メールなどの送信に悪用される可能性がある。 脆弱性診断ツール(NessusやOpenVASなど)で第三者中継をチェックできるものがあるので、メールサーバをセットアップした際には確認しておくと良い。 ### 第16回 7/17(土) 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.270(「4.9.2 メールヘッダ・インジェクション」) ~ P.288(「4.10.2 意図しないファイル公開」の直前) #### ファシリテーター #### 学習MEMO ###### 4.9.2 メールヘッダ・インジェクション ###### 概要 (P.270) メールヘッダ・インジェクションとは、宛先や件名などのメールヘッダを外部から指定する際に、改行文字を使ってメールヘッダや本文を追加・変更する手法のこと。 影響 * 件名や送信元、本文を改変される * 迷惑メールの送信に悪用される * ウイルスメールの送信に悪用される 対策 メール送信専用のライブラリを使用した上で、 外部からのパラメータをメールヘッダに含ませないようにするか 外部からのパラメータには改行を含まないようにチェックする。 ###### 攻撃手法と影響 (P.271) 49-001.html メール送信フォーム 49-002.php メール送信フォームからのリクエストを受けてメール送信するスクリプト。mb_send_mail()関数の第4引数にフォームから受け取ったパラメータの値を渡す。パラメータの値に改行が含まれる可能性は考慮されていない。 正常系 1. フォームのメール欄に「alice@example.jp」、本文欄に「発注番号4309の納期を回答ください」と入力して送信ボタンをクリック。 2. 予め指定された宛先に、送信者「alice@example.jp」本文「発注番号4309の納期を回答ください」のメールが届く。 「攻撃1:宛先の追加」 (P.273) 1. 攻撃者のサイトに、49-002.phpへPOSTリクエストを送るフォームを置く。 2. フォームのメール欄に任意のメールアドレスを入れたあと、改行でつなげてbccで別のメールアドレスを入力して送信。 3. 予め指定された管理者の宛先と、bccで指定されたアドレスにメールが届く。 「攻撃2:本文の改ざん」 (P.274) フォームのメール欄にメールアドレスを入れた後、1行空行をはさんで本文を記述すると任意の本文を設定できる。 続けて本来送られるはずだったメールの情報も表示されるが、MIMEを使って隠す方法などがある。 「メールヘッダ・インジェクション攻撃で添付ファイルをつける」 (P.275) MIMEのmultipart/mixedという形式を悪用して、添付ファイルをつけることが可能。 ###### 脆弱性が生まれる原因 (P.276) メールのメッセージ形式 ヘッダとボディは空行で区切る。 ヘッダ To:宛先 Submit:件名 From:送信者のメールアドレス ヘッダの各フィールドは改行で区切られている。 外部から指定するパラメータに改行が挿入できる状態だと、ヘッダや本文を不正に追加・変更できてしまいメールヘッダ・インジェクションの脆弱性が発生する原因となる。 ###### 対策 (P.277) * メール送信の専用ライブラリを使用する * 下記のいずれかを実施する * 外部からのパラメータをメールヘッダに含ませないようにする * 外部からのパラメータには改行含まないようにメール送信時にチェックする 「メール送信の専用ライブラリを使用する」 sendmailコマンドを利用して自力で組み立てると、 アプリケーション側の責任が大きくなりメールヘッダ・インジェクション脆弱性が入り込みやすかったり OSコマンド・インジェクション脆弱性という他の脆弱性が入り込む危険性がある。 メールヘッダ・インジェクション脆弱性は本来専用ライブラリで対策されるべきで、専用ライブラリの使用を推奨する。 ただし、専用ライブラリの対策も完璧ではないので次のいずれかの対策をあわせて行うと良い。 「外部からのパラメータをメールヘッダに含ませないようにする」 (P.278) 外部からのパラメータをメールヘッダに含まなければ、メールヘッダ・インジェクション脆弱性の混入する余地はない。 可能であれば含ませない仕様にする。 「外部からのパラメータには改行含まないようにメール送信時にチェックする」 メール送信時のタイミングで改行文字をチェックすることでメールヘッダ・インジェクション脆弱性の根本対策となる。 メール送信用のラッパー関数を用意して、ラッパー関数側で改行文字をチェックするとよい。 また、フレームワークの提供するメール送信機能に改行チェックを組み込むことも有効。 「メールヘッダ・インジェクションに対する保険的対策」 メールアドレスや件名には本来改行は含まれないはずなので、入力値の妥当性検証で検出できるようにしておくとメールヘッダ・インジェクション脆弱性の保険的対策となる。 * メールアドレスのチェック メールアドレスの書式はRFC5322で規定されているが、すべてのメールサーバやメーラー、WebメールサービスがRFCの仕様を完全にサポートしているわけではないので Webサイトごとにメールアドレスの仕様を要件として定めて検査を行う。 メールアドレスのチェックがないと、カンマなどで複数のメールアドレスを不正に指定されてしまう可能性も考えられる。 RFC5322については↓↓↓のURLが参考記事  ・https://ponsuke-tarou.hatenablog.com/entry/2018/02/24/163729  ・https://qiita.com/yoshitake_1201/items/40268332cd23f67c504c * 件名のチェック 件名には書式や文字数の制限はないので、制御文字以外にマッチする正規表現を用いてチェックするとよい。 今回のメールヘッダ・インジェクション脆弱性の根本的原因となっている改行文字も制御文字の一種。 内部文字エンコーディングがUTF-8ならpreg_match()、UTF-8以外ならmb_ereg()を使用する。 「mail関数、mb_send_mail関数の第5引数に注意」 第5引数のadditional_paramsは、メール送信プログラムに渡されるコマンドライン引数。 重大な脆弱性があるため、外部由来の値を指定することは避けた方が良い。 → 重大な脆弱性 = OSコマンドインジェクション脆弱性 PHPMailer 5.2.20 以降のバージョンなら問題はない? https://jvn.jp/vu/JVNVU99931177/ PHPMailerバージョンアップ対応内容について↓↓↓ https://blog.tokumaru.org/2016/12/PHPMailer-Vulnerability-CVE-2016-10033.html ###### まとめ (P.280) インターネット上には古い開発手法がヒットしてしまうこともあるので、正しいメール送信の方法を学び脆弱性を作り込まないようにしよう。 ###### さらに進んだ学習のために メールプロトコル(特にSMTP)への理解があると、メール送信に関する脆弱性だけでなく文字化けなどのトラブルシューティングにも役立つ。 ##### 4.10 ファイルアクセスにまつわる問題 (P.281) この節では、ファイルの取り扱いに関する脆弱性について説明。 * ディレクトリ・トラバーサル脆弱性 * 意図しないファイル公開 ###### 4.10.1 ディレクトリ・トラバーサル ###### 概要 外部からのパラメータでサーバ上のファイル名を指定できるWebアプリケーションでは、不正にファイルの閲覧や改ざん、削除ができる場合がある。 この脆弱性をディレクトリ・トラバーサル脆弱性という。 影響 * Webサーバ内のファイルの閲覧 * Webサーバ内のファイルの改ざん、削除 対策 * 外部からファイル名で指定できる仕様を避ける * ファイル名にディレクトリ名が含まれないようにする * ファイル名を英数字にする ###### 攻撃手法と影響 (P.282) 4a-001.php 画面テンプレートのファイルをGETパラメータ"template"で指定できるスクリプト 正常例 templateパラメータに"spring"という文字列が指定され、/var/www/html/4a/tmpl/spring.htmlが出力される 攻撃例 templateパラメータに"../../../../../etc/hosts%00"という文字列が指定され、/etc/hostsが出力される このように、ディレクトリ・トラバーサル脆弱性があるとWebサーバ上の任意のファイルにアクセスが可能となる。 書き込みや削除が可能なアプリケーションでは、データの改ざんなどの影響があったり 改ざん対象がPHPなどのスクリプトファイルになると不正プログラムのダウンロードやシステムに対する不正操作などのリスクもある。 「COLUMN スクリプトのソースから芋づる式に情報が漏洩する」 (P.285) 一見ファイル名が分からないから大丈夫と思われるファイルでも、ディレクトリ・トラバーサル攻撃でスクリプトのファイルを閲覧され そこから他のファイル名を知られる危険性がある ###### 脆弱性が生まれる原因 次の3つの条件をすべて満たす場合に、ディレクトリ・トラバーサル脆弱性が発生する。 * ファイル名を外部から指定することができる * ファイル名として、絶対パスや相対パスの形で異なるディレクトリを指定できる * 組み立てたファイル名に対するアクセスの可否をチェックしていない ###### 対策 「外部からファイル名を指定できる仕様を避ける」 * ファイル名を固定する * ファイル名をセッション変数に保持する * ファイル名を直接指定するのではなく番号などで間接的に指定する 「ファイル名にディレクトリ名が含まれないようにする」 ディレクトリを示す記号がOSにより異なることを考慮したライブラリを使用し、ファイル名にディレクトリ名が含まれないようにする。 PHPの場合はbasename()関数が利用できる。 「COLUMN basename関数とヌルバイト」 PHPのbasename()関数は、ヌルバイトがあっても削除などはしないため、basename()関数を使っても想定した拡張子にならないことがある。 ファイル名を外部から渡す場合は、ファイル名の妥当性チェックにより、ヌルバイトがないことを保証する必要がある。 「ファイル名を英数字に限定する」 →ヌルバイト攻撃については紙媒体P106ページに記載されている (P.287) ファイル名に指定できるのは英数字だけに限定することで、ディレクトリ・トラバーサル攻撃に用いる記号文字が使えなくなり、対策となる。 ###### まとめ (P.288) ディレクトリ・トラバーサル脆弱性はファイルアクセス処理の際に混入しやすい脆弱性。 最善の対策は、設計の段階で外部からファイル名を渡さない仕様にすること。 ### 第17回 8/7(土) 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.288(「4.10.2 意図しないファイル公開」)~ P.307(「4.12 ファイルアップロードにまつわる問題」の直前) #### ファシリテーター #### 学習MEMO ###### 4.10.2 意図しないファイル公開 ###### 概要 外部から閲覧されると困るファイルをWebサーバの公開ディレクトリに配置している場合、 ファイルに対するURLが分かると秘密ファイルの閲覧が可能になります。 ###### 攻撃手法と影響 (P.289) URLでディレクトリを指定した場合にファイル一覧を表示する機能のとこをディレクトリ・リスティングと呼ぶ。 一覧にあるリンクをクリックすると、ファイルの内容が表示される。 非常に単純な手口だが、昔はこの手法で漏洩事件・事故がよく起きていた。 ###### 脆弱性が生まれる原因 (P.290) ファイルを外部から閲覧できる条件 * ファイルが公開ディレクトリに置かれている * ファイルに対するURLを知る手段がある * ファイルに対するアクセス制限が掛かっていない ファイルに対するURLを知る手段 * ディレクトリ・リスティングが有効 * ファイル名が日付やユーザ名、連番など類推可能 * user.dat、data.txtなどのありがちな名前 * エラーメッセージや、他の脆弱性によりファイルのパス名が分かる * 外部サイトからリンクされるなどして検索エンジンに登録される Apache等の設定のみで閲覧を禁止すると、うっかり設定変更してしまうミスが起こり得るので危険。 ###### 対策 根本対策は、非公開ファイルを公開ディレクトリに置かないこと。 * アプリケーションの設計時に、ファイルの安全な格納場所を決める * レンタルサーバを契約する場合は非公開ディレクトリが利用できることを確認する また、保険的対策でディレクトリ・リスティングを無効にする。 Apacheの場合はhttpd.confや.htaccessで設定できる。 ###### 参考:Apache HTTP Serverで特定のファイルを隠す方法 やむを得ず公開ディレクトリに非公開ファイルが置いておく必要がある場合、apacheの設定で外部からの閲覧を禁止する方法がある。 ##### 4.11 OSコマンド呼び出しの際に発生する脆弱性 (P.292) シェル経由でOSコマンドを実行する場合や、開発に用いた機能が内部的にシェルを用いて実装されている場合、意図しないOSコマンドまで実行可能になる場合がある。この現象をOSコマンド・インジェクションと呼ぶ。 ###### 4.11.1 OSコマンド・インジェクション ###### 概要 シェルを呼び出せる機能の使い方に問題があると、意図しないOSコマンドが実行可能になる場合がある。これをOSコマンド・インジェクション脆弱性と呼ぶ。 シェルとは、Windowsのcmd.exeやUnixのsh、bashなど、コマンドラインからプログラムを起動するためのインターフェース。 OSコマンド・インジェクション脆弱性はシェル機能の悪用と言える。 悪用されるとすべてのページが影響を受け、たとえば以下のような被害が考えられる。 * Webサーバ内のファイルの閲覧・改ざん・削除 * 外部へのメール送信 * 別のサーバーへの攻撃(踏み台にされる) * 暗号通貨の採掘(マイニング) ###### 攻撃手法と影響 (P.293) 「sendmailコマンドを呼び出すメール送信の例」 お問い合わせフォーム 4b-001.html POSTメソッドで4b-002.phpにリクエストを送るフォームを表示するHTMLファイル 4b-002.php filter_input()でmailパラメータの値を受け取り、system関数でsendmailコマンドを実行するスクリプト template.txt 4b-002.phpでsendmailコマンドの実行時に指定されるメールのテンプレート (MEMO) filter_input() https://www.php.net/manual/ja/function.filter-input.php 指定した名前の変数を外部から受け取り、オプションでそれをフィルタリングする関数。 今回は第二引数までしか指定されていないので、フィルタリングしていない状態。 正常な例 1. 4b-001.htmlのフォームにメールアドレスに「「bob@example.jp」、お問い合わせ内容に「よろしくお願いします」を入力して送信。 2. ブラウザに「お問い合わせを受け付けました」が表示され、入力したメールアドレス宛に「お問い合わせを受け付けました」が送信される。 「OSコマンド・インジェクションによる攻撃と影響」 (P.295) 攻撃例 1. 4b-001.htmlのフォームのメールアドレス欄に「bob@example.jp; cat /etc/passwd」、お問い合わせ内容に「よろしくお願いします」を入力して送信。 2. ブラウザに/etc/passwdの中身が表示される。 その他にもファイルの削除、変更、外部からのファイルダウンロード、ダウンロードした不正ツールの悪用などWebアプリケーションが稼働するユーザ権限で実行できるコマンドはすべて悪用可能。 「オプションを追加指定することによる攻撃」 (P.296) アプリケーションが呼び出すOSコマンドによっては、オプションを追加することで悪用される危険性がある。 たとえばUnixのfindコマンドは、-execオプションをつけることで検索したファイル名に対してコマンドを実行することができてしまう。 ###### 脆弱性が生まれる原因 シェルには複数のコマンドを起動するための構文があるため、外部からのパラメータ操作で想定外のコマンドを起動させられる場合がある。これがOSコマンド・インジェクションである。 また、開発者がOSコマンドを呼び出す意図がないときにも、無意識にシェル起動のできる関数を使っていることがある。 つまり、OSコマンド・インジェクション脆弱性が発生するケースには次の2通りがある。 * シェル経由でOSコマンドを呼び出す際に、シェルのメタ文字がエスケープされていない場合 * シェル機能を呼び出せる関数を使用している場合 「シェルによる複数コマンド実行」 (P.297) シェルには、1行で複数のプログラムを実行する方法が用意されている。 Unixシェルで使える記法 ・コマンドの後、改行の代わりに「;」を書いて、続けて次のコマンドを実行 ・コマンドの後に「&」を書いてバックグラウンドで実行させ、次のコマンドをフォアグラウンドで実行 ・コマンドの後に「&&」を書いて、1つ目のコマンドが成功したら次のコマンドを実行 ・コマンドの後に「||」を書いて、1つ目のコマンドが失敗したら次のコマンドを実行 ・「` `(バッククォート)」で囲った文字列をコマンドとして実行 ・コマンドの後に「|」を書いて、1つ目のコマンドの出力を2つ目のコマンドの入力にして実行 シェルの利用時に特別な意味を持つ「;」や「&」などの記号をシェルのメタ文字と呼ぶ。 これを悪用したのがOSコマンド・インジェクション攻撃。 OSコマンドのパラメータとなる文字列にシェルのメタ文字を混入させることで、不正にOSコマンドを実行可能となることがOSコマンド・インジェクション脆弱性の原因。 「シェル機能を呼び出せる関数を使用している場合」 (P.298) Perlのopen関数は、呼び出し方によってはシェル経由でOSコマンドを実行することも可能。 4b-003.cgi パイプ記号「|」をコマンド名の後ろにつけてopen関数を呼び出している。 (openの第二引数関数に、「command |」のように引数を渡すと"command"をコマンドとして扱い、コマンドの実行結果をパイプでファイルハンドルへ渡す) これを実行すると、pwdコマンドの実行結果であるカレントディレクトリ名が表示される。 外部からファイル名を指定できる場合、このopen関数の特徴を悪用してOSコマンド・インジェクション攻撃ができる場合がある。 攻撃例 4b-004.cgi 外部から受け取ったファイル名のファイルをPerlのopen関数を使ってオープンし、内容を表示するCGIプログラム 1. クエリ文字列fileに「ls+/sbin|」という値を渡す 2. /sbinディレクトリのファイル一覧が表示される 「脆弱性が生まれる原因のまとめ」 OSコマンド・インジェクション脆弱性が生まれる条件は、次の3つのすべてを満たすこと。 * シェルを呼び出す機能のある関数(system, openなど)を利用している * シェル呼び出し機能のある関数にパラメータを渡している * パラメータ内に含まれるシェルのメタ文字をエスケープしていない ###### 対策 (P.300) つぎの順で優先して対策すべき。 1. OSコマンド呼び出しを使わない実装方法を選択する 2. シェル呼び出し機能のある関数の利用を避ける 3. 外部から入力された文字列をコマンドラインのパラメータに渡さない 4. OSコマンドに渡すパラメータを安全な関数によりエスケープする 「設計フェーズで対策方針を決定する」 基本設計(外部設計)フェーズ * 主要な機能の実装方針を決定する際に、極力ライブラリを利用する 詳細設計(内部設計)フェーズ * シェルを呼び出せる関数の使用をできるだけ避ける * シェル経由の関数しか使えない場合は、パラメータを固定にするか、標準入力から指定することを避ける 「OSコマンド呼び出しを使わない実装方法を選択する」 OSコマンドを呼び出さない(シェルを呼び出せる機能を利用しない)ことで、OSコマンド・インジェクション脆弱性が混入すること可能性がなくなる。また、OSコマンド呼び出しのオーバーヘッド(余計な負荷)がなくなり、多くの場合性能も向上する。 4b-002a.php サンプルスクリプトのメール送信機能(4b-002.php)をPHPのライブラリを使って書き換えた例 sendmailコマンドの代わりにmb_send_mail関数を利用している。 ただし、メールヘッダ・インジェクション脆弱性が混入する可能性があるので注意。 「シェル呼び出し機能のある関数の利用を避ける」 (P.301) どうしてもOSコマンドコマンドを呼び出さないといけない場合の選択肢として、OSコマンドを呼び出す際にシェルを経由しない関数を使用するという方法がある。 ~~PHPには適当な関数がない(pcntl_exec関数を使うには、現在もCGI 版あるいは CLI 版の PHP をコンパイルする必要がある)のでこの方法は取れない。~~ > PHP 7.4では、proc_openの第1引数を配列として指定することにより、コマンドとパラメータを明確に分離するとともに、シェルを経由しないコマンド実行ができるようになりました > https://blog.tokumaru.org/2019/12/osphp74.html Perlでは、system関数でコマンド名とパラメータを個別に指定する呼び出し方をすることで、シェルを経由せずに実行できる。この場合OSコマンド・インジェクション脆弱性は混入する余地がない。 また、open関数の場合は次のいずれかの方法でシェル起動を避けることができる。 * open関数の代わりにsysopen関数を使う * open文の第二引数として、アクセスモードを指定する 4b-002b.cgi 4b-002.cgiをシェルを経由せずにsendmailコマンドをオープンする方法へ書き換えた例。 モード指定に「|-」を利用している。 コマンドとコマンドのパラメータをスペース区切りで指定すると、シェル経由での呼び出しとなりOSコマンド・インジェクション脆弱性の原因となるので注意。 「外部から入力された文字列をコマンドラインのパラメータに渡さない」 (P.303) シェル経由を確実には避けられない場合、コマンドラインにパラメータを渡さないことがOSコマンド・インジェクションの根本的対策になる。 4b-002c.php ### 第18回~ https://hackmd.io/CSprqWaVTgGEWUDwYqQmug

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully