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やミドルウェアのパッチを適用する:最新版にしよう!