Skip to content

Instantly share code, notes, and snippets.

@mala
Last active December 29, 2016 18:08
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mala/9bf56420da8841945ba69361dd086878 to your computer and use it in GitHub Desktop.
5分でわかる Perl and web security

5分でわかる Perl and web security

ma.la


CSRFとかXSSとか

  • CSRF: フレームワークの機能使って下さい
  • XSS: Xslateとか自動エスケープして下さい、jsの動的生成はするな
  • 終わり

本題

  • YAPCなのでPerl固有の問題について解説します。

Webアプリケーションの一般的な流れ

  • パラメータ受け取る(フォームとかJSONとか)
  • 何らかの処理をする
  • レスポンスを返す(HTMLとかJSONとか)

フォームやJSONを安全に受け取るには

  • paramはscalarで受け取りましょう

Why

$params = {
    name => $r->param("name"),
    value => $r->param("value"),
}

直し方

# || "default value" とか scalarをつける
$params = {
    name => $r->param("name") || "",
    value => scalar $r->param("value"),
}

JSON受け取るようなケース

  • JSON SQL injectionとかMass Assignmentでググれ
  • 雑に受け取ったオブジェクトそのままデータを更新するような処理を書くのはやめよう
  • validationしましょう

Why

  • http://developers.mobage.jp/blog/2014/7/3/jsonsql-injection
  • JSONで受け取ったパラメータをそのままSQLクエリビルダ―やORマッパーに入力
  • 文字列を想定したパラメータに、Hash refやArray refを入力されてしまう
  • 本来想定していないカラムを更新してしまう

ファイルを受け取る

  • File upload起因のコマンドインジェクションが多くある
  • ImageMagickバージョンアップしましょう
  • Plackのバージョンアップしましょう
  • 2引数openや使うな, etc

Why

  • 外部コマンド呼び出し時の問題
  • 2016年5月 ImageMagick で不正なファイル処理させるとコマンドインジェクションできる問題
  • 言語によらず多方面のウェブサービスに影響があった
  • 外部コマンドに依存する場合は外部コマンドの脆弱性情報に注意を払う

Perlの罠

  • ImageMagickに関係なく、ファイル入出力や外部コマンド呼び出しは危険が多い

HTTP::Body::Multipart の問題 (2013)

  • アップロードされたファイルを格納するtmpfileが拡張子を保持する
  • CVE-2013-4407
  • 保持する拡張子に "|" を含めることが出来る!!
  • そのまま `` や 2引数openに渡すとコマンドインジェクションが可能
  • test.test|sleep 10|.jpg みたいなファイルをアップロード

CVE-2013-4407

 ver 1.18      2013-12-06 10:05:33
 Added configurable basename regexp,
 test added with fixed regexp for next release

our $basename_regexp = qr/[^.]+(\.[^\\\/]+)$/;
#our $basename_regexp = qr/(\.\w+(?:\.\w+)*)$/;
  • 前者: . の後の / 以外の文字を拡張子とみなす
  • 後者: . の後の \w と . を拡張子と見なす
  • 安全な正規表現のほうがコメントアウト

結論としては修正されていない

  • あくまでカスタマイズできるようになっただけ
  • デフォルトの動作はそのままで、直ってない!
  • HTTP::Entity::Parserだとこの問題は無い
  • Plackのversion upでも直る

護身として: 2引数openを使わない

  • HTTP::Bodyは安全なデフォルトではないが、コマンドインジェクションを起こすのは元々ダメなコードである
  • ☓ open(FH, $filename)
  • ◯ open(FH, "<", $filename)
  • 自分の書いたコードで使ってなくてもライブラリ側でパイプをサポートしている場合があるので注意
Image::ExifTool::ImageInfo("sleep 1|")

護身として: `` や system 使わない

  • 文字列でコマンドと引数を組み立てるのはやめよう
  • ☓ system($cmd_and_args)
  • ◯ system($cmd, @args)
  • 書き捨てスクリプトならまあ良いが、どうせタイムアウトとか必要になる
  • IPC::Run とか IPC::Cmd とかを使うと良い

昨今の個人情報漏洩事件

  • 「今どきOSコマンドインジェクションなんて」 といった反応がちらほら
  • 実際にあるので、他人事だと思わないで。

Cookieを受け取る

  • session id以外は受け取らないほうがよい
  • 暗号化cookieを使ったセッションは使わない方がいい
    • cookie自体にセッションデータを持たせる方式のこと
    • 鍵が漏洩 or 弱い場合に危険 / 開発者向けバックドアになる
  • cookieが利用者から改変できる値であることを忘れがち

Cookieを使った攻撃

  • 例えば "lang" とか大丈夫?
  • テンプレートファイルのパスに使ったり → path traversalに。

Storable使った任意コード実行

  • オブジェクトデシリアライザを通じた任意コード実行、複数の言語で同様の問題あり
  • Perlでは信用出来ないStorableオブジェクトをデシリアライズすると危険
  • 多様な経路で任意コード実行の危険がある

実例 Plack::Middleware::Session::Cookie (2014)


データフォーマットとRPC

  • JSON: プリミティブなデータだけ
  • Storable: 言語固有のシリアライザ
    • 言語固有の内部フラグも保持。Perlにおいてはblessed Hashをシリアライズできる。
  • 信頼境界をまたいでStorableを使ってはいけない

実例 Event::RPC

  • dvd::rip で使われている
  • 標準のフォーマットがStorableだった
  • 認証機構があるが、認証メッセージ自体がStorable!!!
  • デフォルトのRPCのフォーマットが変更された

memcached injection

  • オブジェクトを格納する際の標準のシリアライザがStorable
  • memcached injection == 任意コード実行
  • Cache::Memcached::Fast::Safe 使うと良い

randomがさほどrandomではない問題

  • 例えば String::Random
    • ランダムな文字列を生成してくれる便利モジュール
  • tokenの生成には不向き

Why

  • rand "だけ"で鍵を作ると、たったの43億通りのパターンしか生成されない
  • オフラインで解析可能な用途であれば致命的
    • 暗号化cookieの暗号鍵や署名に使う鍵はオフラインで解析可能

secret/tokenの生成には暗号用の乱数生成を使う

  • srandに同じ引数を渡すと毎回同じ乱数が生成される
  • ☓ srand($value_from_dev_random); rand; rand; rand; rand;
  • これは元々Perlがやっていることで、、エントロピー増えない
  • ◯ /dev/urandom を直接使ったり、他の予測不可能な値を混ぜる
  • ◯ CryptとかSecureとかついたモジュールを使って生成する

実例 Amon2 (2014)

  • http://blog.64p.org/entry/2014/08/11/145422
  • HTTP::Session2::ClientStore Amon2::Plugin::Web::CSRFDefender
  • 雛形セットアップで生成される乱数の質が低く、ブルートフォースで解析可能だった。
  • Cookieの暗号鍵に使用 → Storableによる任意コード実行

終わり

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment