log

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

  • 携帯電話向けwebアプリケーションについて。
    • 脆弱性ありすぎっていうか、docomo/au/softbank で仕様が違いすぎて、固有番号の仕様も違えばJavaScriptの仕様も違うし、🍪保存できないし、勝手な実装してたりするし、最悪すぎて対応めんどくさすぎるでしょ
    • かんたんログインがほんとに”ヤバイ
    • バイのに、提供している側が仕様/実装方法を公開せず、それを金銭などの絡むクリティカルなものに使っているのがやばい。
    • iPhone が普及して、ほんとに、ほんとによかったんだなって心から思った。こんな対策したくない。
    • たぶんこれから先使うことはないから、詳細とやばさを知りたいときはこの7章読むと良いと思う
    • 高木浩光さんがほんとうに面白かった。
    • http://takagi-hiromitsu.jp/diary/20100425.html
    • http://takagi-hiromitsu.jp/diary/20100221.html
    • http://takagi-hiromitsu.jp/diary/20100228.html
    • この記事がおすすめされてたんだけど、マジで「なくなるべき」って何度も書いていて、なくなってよかった。

  • webサイトの安全性を高める方法についてだった。
  • なんか読んでたら怖くなったので、途中からさくらVPSで借りてる自分のサーバの脆弱性を確認していた。
    • したこと:iptables 見る、全ユーザの最終ログイン時間とかを見る、sshログのFailを見る、nmap [ipアドレス] -p1-65535 してポート閉められてるか見る、/etc/ssh/sshd_config でパスワード認証オフにしてるかどうか見る、みたいなことをしていた。めっちゃ時間かかった。もたもたしたので慣れたい。
  • 使ってるサービスというか、言語の脆弱性JVN とかでちゃんと見て、その対処法をちゃんと考えるの、大事。でも見つかったばっかりのときは根本的な対処出来ないときもあるから、暫定的な回避策を実施する必要があるよ
    • ちゃんとテスト環境で検証して、サーバ再起動とか切り戻しとかちゃんと調べよう
    • バックアップもちゃんと取ろう
    • めっちゃ小さいときや多少のサイト停止を許容出来るときはテスト環境無視でそのままパッチ適用してもよさそう?←これわたしが個人的に運用してるサービスとかならこうするのが一番楽そう
  • webサーバの脆弱性/管理ソフトに対する不正ログイン/なりすまし/盗聴/改ざん/マルウェア対策、ざっと書いたけど、たぶんどれもちょっと考えると当たり前のことなんだよな
  • マルウェア対策の責任、全員に責任があると考えられるっぽい。運営者、ファイルの投稿者、ファイルの閲覧者。まあ感染する方も悪いよね
    • ポリシーを定めて、それについて利用者に告知するとよい◎

  • 開発マネジメントでのセキュリティ施策について
  • まず、開発標準をちゃんと定める!とよさそう。薄くてわかりやすくて簡潔で改善され続けているものがあると、コスパがよい
  • チームでも開発標準を守るようにする、書いてて思ったけど、この形式ってどこの会社にも適用されるんだろうか?最近のweb系のセキュリティって、専門のチームがいて自社サービスのセキュリティ関連を全部丸投げってイメージなんだけど、どうなんだろ
  • セキュリティチェックについて、ウェブ健康診断仕様( https://www.ipa.go.jp/files/000017319.pdf )がスゴイ。これ自動化してビルドするたびにチェックするとかありそう。
  • 最近の自社サービス持ってる会社のセキュリティチェックってどうやってるのかまったく想像がつかない………
  • 運用ではログ監視したり、新しい手法の攻撃とかへの対応してるか、とか、前診断したあとに追加した機能/ページに対する診断とかをやるとよさげ?
  • 最終的には、ちゃんとしたガイドラインの策定と、それを守る能力のあるチームメンバーの教育が必要って感じ

この本終わり!!!!!!!!!!!!お疲れ様でした!!!!!!!!!!!!!!

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

  • 文字コードについて。
    • 普段使う「文字コード」は、文字集合+文字エンコーディング
    • 文字集合:ASCII, JIS X 0201, Unicode.. などの”集合”
    • 文字エンコーディング文字集合をコンピュータで扱えるよう符号化したもの。Shift_JIS, EUC-JP, UTF-8などなど。
    • 色々あるんだけど、結論としてアプリケーション内で文字コードを統一すること!!!UTF-8使え!!!!
    • Shift_JISEUC-JPで起こる不正
      • 先行バイトの後にデータがないとき
      • 先行バイトに続くバイトが、後続バイトの範囲にないとき
    • UTF-8で起こる非最短形式の問題
      • たとえば、/(スラッシュ)は 0x2F, 0xC0 0xAF, 0xE0 0x80 0xAF, 0xF0 0x80 0x80 0xAF の 4 つで表現出来る。0x2Fが最短で、それ以外が非最短
      • 0xC0 0xAF はディレクトリトラバーサルのチェックとかのセキュリティチェックを通る→ファイル名として展開する→0xC0 0xAFが / スラッシュに展開される→親ディレクトリ☠
      • 最新規格では、非最短形式は不正で処理しちゃダメ!なので最新に沿ったものを使おう
    • まあ、アプリケーション全体をお押して文字集合/エンコーディングを統一するのが余計な問題を起こさずに済むのでよい◎
    • 文字集合の縮退処理
      • どうしても統一出来ない時、たとえば携帯電話向けwebアプリなどで起こるShift_JISしか対応してない問題
      • DBからデータを取ってきたあと、U+00A5とかいう、Unicode固有のものが入っているときはなんか処理かますまえにUTF-8Shift_JISUTF-8っていう変換(この本だと縮退処理って書いてある)をして、起こる文字化けを最初から起こした状態で処理することで変な問題を回避しようって感じ
      • これはエスケープ処理とかの前にやらないと脆弱性の原因になるよ
    • 文字コードチェック:不正な文字エンコーディングがエラーになるor代替文字になる/「表」「ソ」「能¥」が正しく登録表示される/尾骶骨テスト
    • 文字コード自動判定はやめろ!!!!!!!!!!!明示的に指定しよう!!!!!!!!

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

  • アカウント管理
    • ユーザ登録
      • SQLインジェクション、メールヘッダインジェクションが混入しやすい。
      • メアドの受信確認をちゃんとする!本人確認大事。
      • でも、トークンを発行してそれ付きのURLを踏ませてってのは、ユーザに「メールで来たURLを踏む」という経験を与えるのでフィッシングに引っかかりやすくなる?
      • 確認番号送って入力してもらうのが一番いいけど、メールでURL踏むのが一般的な気がするなぁ
      • ユーザIDの重複も防止したほうがよい(というか当たり前) 前パスワード違えば登録出来て、間違って他人のに入れたりするのがあった。あとは論理削除してるから一意制約つけられないとか
      • CAPTHAで自動登録防止しよう
    • パスワード変更
      • 変更と同時に現在のパスワードを確認→変更時にはメールでその旨を通知する。
      • こうすると少なくともCSRF脆弱性は防げる。SQLインジェクションはがんばる。
    • メアド変更
      • 新規メアドへの受信確認→再認証→新旧メアドへの通知
      • 乗っ取られてたらわかるのでちゃんと通知することが大事
    • パスワードリマインダ(パスワードリセット)
      • 管理者向けと利用者向けを分ける
      • 管理者向けはマスターってかadminだけど、結局脆弱性の温床??にもなるのでものによっては実装しなくてもよい。
      • 管理者:本人確認→「仮」パスワード発行→ユーザがパスワード変更
      • 「仮」パスワードのしくみを作っておく(このパスワードではパスワード変更しか行えない、とか)
      • 利用者:本人確認(メアド認証&&秘密の質問)→パスワード通知→変更
      • このパスワード通知、平文で送ったりしない!!!仮パスワードを発行するか、パスワード変更画面に直接遷移するリンクを送るかのどっちか。
      • 実装上では、登録されてないメアドでもエラーにせず、ログで知らせるとか、悪用可能なところをちゃんと潰す。
    • アカウント停止
      • まあそのまま
    • アカウント削除
      • 取り返しのつかない処理なので、意思確認とCSRF対策のためにパスワード再認証したほうがよい。

  • 認可制御
    • 認証された利用者のみに許可された機能/情報の閲覧/編集操作など、不備があるとぽろぽろ漏れるので気をつける。
    • 設計時にきちんとすると、テストもしやすい。
    • 権限マトリックスとか使って、ちゃんとユーザと権限を対応させておく!
    • ロールを持たせて、ある管理者に全部やらせる(複数人で1つのアカウントをいじる)とかはダメ
    • 認可不備が起こる原因はURL/hiddenパラメータ/クッキーを書き換えられないと思い込んでいることがおおい。これらが書き換えられても大丈夫なセッション変数に権限情報を格納すること!

  • ログ出力
    • (1) 攻撃や事故の予兆を把握、早期対策 (2) 攻撃や事故の事後調査 (3) アプリケーションの運用監査
    • ログ出力の要件とか、色々あるので p.366 参照。
    • ただ、後から突き合わせるのに大変だから、サーバーの時刻合わせは必要だよ。NTPとか使おう。
    • 実装はすでにライブラリ化されてるものがあるから、それ使ったほうが楽。log4j, log4php
    • 開発時にはdebugレベル、運用時にはinfoを指定すれば、コード変更することなくinfo以上の重要度ログのみ取得出来るし、危ない情報を残すこともない。

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

  • 認証
    • ログイン
      • SQLインジェクション脆弱性が存在すると迂回出来るからあぶない
      • →もとのパスワード知らないまま入れたりするけど、SQLインジェクション脆弱性あるとパスワードわかったりするから平文で保存するな
      • 色んな攻撃がここにされる:パスワード試行/ソーシャルorショルダーハック/フィッシング
      • 対策:SQLインジェクション脆弱性をなくす/パスワードを予測困難にする
        • パスワードについて。結局人間が打つものなんだから複雑なものにならなくて、だから辞書攻撃とかが成立するんだけど、でもサービスとしては複雑なパスワード設定してほしいやん。でも、パスワードって見えるとやばいから type=password にして入力時に見えないようにするんだけど、これって危険な(脆弱な)パスワードでもなんか入力しやすいからやばくない?みたいな話があったらしい。個人的には基本的に長いマスターパスワードだけ覚えれば覚えればいい1Passwordってサービスがおすすめで、こういうのがもっと普及してリテラシーの最前提みたいになるといいなと思う。無理だろうけど。
        • 結局人間の心理が絡むと攻撃しやすくなるし攻撃しにくくもなるしっていう話
    • 総当りへの対策 →アカウントロック
      • ログインIDを秘匿することで、総当たりのオーダー増やすことが出来るのでそれでもOK 一般に公開するNNとは別にメアドでログインするとか、そういうやつ。
    • パスワードの保存方法
      • 漏洩したときに、使いまわしてるユーザがいると甚大な被害が出るよね。
      • どのアルゴルズムを使うか、生成、保管、危殆化時の最暗号化とかの問題があって、アルゴリズムはまあ秘密の国のアリス読みましょう。保管が一番難しい。
      • ので、パスワードをまた暗号で保護するんじゃなくて、メッセージダイジェストで保護することが多い←メッセージダイジェストとかするの、暗号化じゃないの?
      • 暗号学的ハッシュ関数が満たすべき要件:計算困難性/弱衝突耐性/教衝突耐性→秘密の国のアリス
      • 攻撃するときの、レインボークラックがすごい!!!めっちゃすごいから→ p.342 簡単に言うとハッシュチェーンを何個も作っといて、適当なやつで一致するやつをDBから見つけたらそのチェーン内に欲しいパスワードがあるとかいうやつ
    • 自動ログイン
      • ほんとは好ましくないんだけど、ログイン状態を継続していることを前提としたサービスがおおい。はてなもわりとそうだし、ニコニコもTwitterGoogleもそんな感じだよね
      • 前もやったけど、🍪にid/pass残して自動ログインとかするのは危険だから、セッションの寿命を延ばしてセッションidでごにょるか、トークンを使う。チケットもよさそうだけど、よくわからない: 2010-05-02 - T.Teradaの日記http://itmcreate.com/wp/archives/2112 とか。ディズニーランドみたいなもんかなあ
    • ログインフォーム
      • パスワードはほんとうにマスク表示すべきかって話してる。さっき書いたやつ。
      • パスワード入力欄側とログイン処理する側で、両方HTTPSにするべき。→フォーム改ざん、DNSキャッシュポイズニングされてたりするかも。これは絶対やらないといけない。
    • エラーメッセージ
      • id/passのどちらが間違いかわかるだけで探索範囲が半減すると言っても過言ではないから、「id/passが違うか、アカウントロックされてるよ」って情報だけ渡すのがよい。ほんとうにロックされているときは正規ユーザにはメールを届ける。
    • ログアウト

この節、秘密の国のアリスで読んだ〜〜〜が多くて楽しかった、記憶がつながる感ね

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

  • evalインジェクション
    • eval:与えられた文字列をスクリプトのソースとして解釈実行する機能
    • ちゃんと使わないとOSコマンドインジェクション攻撃と同じ被害を受ける(それはそう(それはそう))
    • 対策:eval相当機能を使わない/引数に外部からのパラメータを含めない/英数字に限定する

      • 思ったんだけど、脆弱性への対策として (1) 外部からのパラメータを使わない (2) どうしても使うときは英数字だけに限定する、っての多くない?いや、考えたら当たり前なんだけど、この2つを対策するだけである程度防げるのはすごいし、それでも防げてなくてこういう本で繰り返し言われているのも(色んな意味で)すごい
      • サンプル攻撃でデータのやりとりするときにBase64エンコードしてて、なんで?って思ったらこういうことらしい、なるほどなぁ…
      • https://ja.wikipedia.org/wiki/Base64

        Base64は、データを64種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱うためのエンコード方式である。MIMEによって規定されていて、7ビットのデータしか扱うことの出来ない電子メールにて広く利用されている。

    • 対策のevalに与えるパラメータを英数字に限定するってのは、スクリプト仕込むのに区切り文字(; / , / などなど、& とかもかな)使えなくなるからいい感じになるよ

    • evalはたしかに便利で強いけど、便利で強いものはそれだけ副作用があるし、脆弱性が入ったときの影響も大きいから使わないようにしたほうがよい

  • 競合状態の脆弱性
    • 共有資源:復数のものから同時に参照されるデータ。排他制御が不十分だと脆弱性の原因になる。
    • 別人の個人情報が画面に表示される/DBの不整合/ファイル内容の破損が起こる
    • 対策:共有資源使わない/排他制御ちゃんとする
    • 攻撃じゃなくて、ただの事故が起こる可能性もある。
    • 排他制御するとき、たとえば1件のリクエストで0.1sec待つとかしても、1e9件のリクエスト来たらめちゃくちゃ待たされるし、DoS攻撃が簡単に出来るようになるから、やっぱり共有資源は使わないべき。
    • どうしても必要なときは並行処理とかマルチスレッドプログラミングについて学ぼう!

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

  • ファイルアップロードについて
    • でかいファイルを連続で大量に送る→DoS攻撃が出来る
      • 容量制限とかが有効
      • 小さくしすぎるとアレなので、要求を満たす範囲で可能な限り小さくする←見極め大変そう
      • そもそもDoS攻撃耐性高めるために、LimitRequestBodyを制限するとリクエストエラー出せていいかも?
      • DoS攻撃耐性高めるにはこれだけだと死で、メモリ量とかCPU負荷とか伸長後(これ解答後って意味だよね?)のサイズとか見るべき
    • サーバ上のファイルをスクリプトとして実行→全部ヤバイ
      • OSコマンドインジェクションと同じぐらいヤバイ
    • 罠を含むファイルをダウンロードさせる→ウイルスとか
      • ユーザのPC上でJS実行とか、マルウェア感染とか、色々起こる。
      • ファイルダウンロードしたのにJS実行される理由:ブラウザにファイルをHTMLだと誤認させられるから。
      • マルウェアとかは、こういう脆弱性を悪用した感じのやつ。
      • 直接的な責任は脆弱性をついた人間にあるんだけど、サイト運用してる側も怒られる場合があるから、web appの性質を元に対策実施するかどうか決定すべき!
    • ファイルの権限を超えたダウンロード→まあ明らかにヤバイ
      • ファイルに対するアクセス制限をかけるべき
      • 推測出来るURLにしない!

  • アップロードファイルによるサーバ側スクリプト実行
    • ものによっては利用者がアップロードしたファイルを公開ディレクトリに置いたりする。←やばすぎ
    • 拡張子としてphp, asp, aspx, jsp とかのスクリプト言語のが指定出来たりする←やばやばのやば
    • 対策:公開ディレクトリに置かない/拡張子を実行可能性のないものに制限する
      • 拡張子だけだと抜けがあるので、公開ディレクトリに置かないのをメインに対策する。→スクリプト経由でダウンロード、「ダウンロードスクリプト」って呼ぶことにするね
      • SSI(Server Side Include)という機能はHTMLからコマンド実行出来るとかいうヤバイものを持ってるので、ものによってはhtmlもダメになるから、white list 方式のほうがいいし、まずダウンロードスクリプトを使うべき。
      • ダウンロードスクリプトについては長いからp.266
      • これ、途中のコードに「IEだとXSSがあります」って書かれてたんだけど、全然わからなかった………;;
  • ファイルダウンロードによるXSS
    • pngを想定してるんだけど、攻撃者がアップロードしたpng内にHTMLタグが含まれてるとJSが実行されたりする→ファイルダウンロードによるXSS
    • ユーザのブラウザがHTMLやPDFだと誤認するようなファイルをアップロードして、ユーザに見させる(ダウンロードさせる)→ユーザのブラウザが誤認するとXSS攻撃成立
    • 対策:ファイルのContent-typeを正しく設定する/拡張子と中身(マジックバイト)が対応しているか確認する/ダウンロードを想定したファイルにContent-Disposition:attachmentを指定する
    • 画像によるXSSはIE8以降だと対策されてる…はずだけど、それ以前のブラウザ使ってる人間はまだ存在するので、ちゃんと対策しよう(アップデートしろ!!)
      • たとえば、<script>alert(‘XSS’);</script>って中身だけのファイルをa.pngって名前で保存して、IE7で表示するとalertが出る(やばすぎ)
      • IE8だとテキストとして表示されるらしい
    • PDFの偽装が?????って感じ
      • <script>alert(‘XSS’);</script>って中身だけのファイルをa.pdfって感じで保存して、ファイルへのリンクを取る、 http://example.com/a.php?file=aaaaaaだとする
      • http://example.com/a.php/b.html?file=aaaaaaというふうに、/b.htmlを追加すると「見かけ上ファイル名のような形でパラメータを埋め込む方法」らしい、PATHINFO?
      • PATH_INFOを使ってスマートなURLに - あじゃぱー あ〜〜〜〜
      • パラメータだと思わせて実行させてしまうから、XSSが起こるってことかあ
      • これは IE7, 8 でも起こるらしい。
      • PDFはapplication/pdfなんだけど、application/x-pdfっていうContent-typeを間違って指定してると起こるぽい。でもこれはIE特有なんだって
    • つまり、IE使うな!!!!!!!!!!!!!!
    • 対策は、アップロード時とダウンロード時にする
      • アップロード時:拡張子チェック/マジックバイトチェック
        • IEだとXSS出来ますってやつ、やっとわかった。マジックバイトチェックしてないからっぽい。
        • →拡張子とイメージ形式(マジックバイト)が一致してないとエラー出してるから、あってそう!
        • BMP形式、対策してもHTMLと認識される場合がある。アプデしたらOK。てかそもそもあんまりよくないからPNGで代替するべき、Webで使用するな
      • ダウンロード時:Content-Typeを正しくする/マジックバイトチェック/Content-Dispositionヘッダ設定
        • Content-TypeはIEにかぎらずすべてのブラウザで正しく書くべきチェックするべき。なんかマイナーなやつ使うときはユーザが正しく認識できるか確認してね。
        • Content-Disposition←なにこれ? HTTP :: Content-Disposition: inline / attachment Tipsというかメモ 画像を表示させようとしてるからXSSが起きてるわけで、絶対ダウンロードさせればいいよねって話で、そういうオプション
    • これまでの対策は最低限だから、仕様策定するときにちゃんと考える
    • サービス提供用のドメインと画像用ドメインわけるの、高速化的にもセキュリティ的にも良いから考慮するべき
    • !!!!! Content-type/拡張子/マジックバイ!!!!!
      • 最近は画像投稿出来るサイトが増えてるからちゃんとしようね

  • ファイルインクルード攻撃
    • 他のファイル読み込むやつ、include とか require とか、そういうところで外部ファイル読み込むと実行しちゃうから、やばい
    • 対策:パス名に外部からのパラメータを含めない/含めるときは英数字に限定する←これなんかと一緒だよね→ディレクトリトラバーサルの対策と一緒!!
    • 途中までは一緒だけど、この攻撃はスクリプト読み込んで実行出来るからディレクトリトラバーサルよりヤバイ
    • RFI(Remote File Inclusion):ファイル名としてURL指定すると取ってくるやつだけど、ヤバすぎてデフォルトで無効になった
    • セッション保存ファイルの悪用:セッション情報のファイル名、保存パスとセッションIDを元に決められるんだけど、OSによってデフォルトが決まってるから、それを変更せずに使ってるのは多い!ヤバイ!セッションIDは🍪からわかる!→→→セッション情報のファイル名が特定出来るので、それをURLに指定して%00で終わってやればスクリプト実行出来る
  • 対策:外部からファイル名指定できなくする/ファイル名にディレクトリ名を含めない/ファイル名を英数字に限定するディレクトリトラバーサルと一緒だね

今日で4章読み終わりたかったのに疲れて終わってしまった……………