ma.la
- CSRF: フレームワークの機能使って下さい
- XSS: Xslateとか自動エスケープして下さい、jsの動的生成はするな
- 終わり
- YAPCなのでPerl固有の問題について解説します。
- パラメータ受け取る(フォームとかJSONとか)
- 何らかの処理をする
- レスポンスを返す(HTMLとかJSONとか)
- paramはscalarで受け取りましょう
$params = {
name => $r->param("name"),
value => $r->param("value"),
}
- これをやると ?name=hoge&name=fuga で壊せる。
- list contextとして評価されるため
- 本来formから受け取らないはずだったキーを受け取ってしまう
- Perl固有の罠で、危険だと察知するのが難しいコード
- http://bulknews.typepad.com/blog/2009/12/perl-why-parameters-sucks-and-what-we-can-do.html
# || "default value" とか scalarをつける
$params = {
name => $r->param("name") || "",
value => scalar $r->param("value"),
}
- JSON SQL injectionとかMass Assignmentでググれ
- 雑に受け取ったオブジェクトそのままデータを更新するような処理を書くのはやめよう
- validationしましょう
- http://developers.mobage.jp/blog/2014/7/3/jsonsql-injection
- JSONで受け取ったパラメータをそのままSQLクエリビルダ―やORマッパーに入力
- 文字列を想定したパラメータに、Hash refやArray refを入力されてしまう
- 本来想定していないカラムを更新してしまう
- File upload起因のコマンドインジェクションが多くある
- ImageMagickバージョンアップしましょう
- Plackのバージョンアップしましょう
- 2引数openや使うな, etc
- 外部コマンド呼び出し時の問題
- 2016年5月 ImageMagick で不正なファイル処理させるとコマンドインジェクションできる問題
- 言語によらず多方面のウェブサービスに影響があった
- 外部コマンドに依存する場合は外部コマンドの脆弱性情報に注意を払う
- ImageMagickに関係なく、ファイル入出力や外部コマンド呼び出しは危険が多い
- アップロードされたファイルを格納するtmpfileが拡張子を保持する
- CVE-2013-4407
- 保持する拡張子に "|" を含めることが出来る!!
- そのまま `` や 2引数openに渡すとコマンドインジェクションが可能
- test.test|sleep 10|.jpg みたいなファイルをアップロード
- この問題はどう修正されたか? http://cpansearch.perl.org/src/GETTY/HTTP-Body-1.22/Changes
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でも直る
- HTTP::Bodyは安全なデフォルトではないが、コマンドインジェクションを起こすのは元々ダメなコードである
- ☓ open(FH, $filename)
- ◯ open(FH, "<", $filename)
- 自分の書いたコードで使ってなくてもライブラリ側でパイプをサポートしている場合があるので注意
Image::ExifTool::ImageInfo("sleep 1|")
- 文字列でコマンドと引数を組み立てるのはやめよう
- ☓ system($cmd_and_args)
- ◯ system($cmd, @args)
- 書き捨てスクリプトならまあ良いが、どうせタイムアウトとか必要になる
- IPC::Run とか IPC::Cmd とかを使うと良い
- 「今どきOSコマンドインジェクションなんて」 といった反応がちらほら
- 実際にあるので、他人事だと思わないで。
- session id以外は受け取らないほうがよい
- 暗号化cookieを使ったセッションは使わない方がいい
- cookie自体にセッションデータを持たせる方式のこと
- 鍵が漏洩 or 弱い場合に危険 / 開発者向けバックドアになる
- cookieが利用者から改変できる値であることを忘れがち
- 例えば "lang" とか大丈夫?
- テンプレートファイルのパスに使ったり → path traversalに。
- オブジェクトデシリアライザを通じた任意コード実行、複数の言語で同様の問題あり
- Perlでは信用出来ないStorableオブジェクトをデシリアライズすると危険
- 多様な経路で任意コード実行の危険がある
- Plack::Middleware::Session::Cookie で secret未指定の場合のremote code executionについて
- https://gist.github.com/mala/804559abc0cc639b84e8
- metacpan.org ってサイトで脆弱性があった
- JSON: プリミティブなデータだけ
- Storable: 言語固有のシリアライザ
- 言語固有の内部フラグも保持。Perlにおいてはblessed Hashをシリアライズできる。
- 信頼境界をまたいでStorableを使ってはいけない
- dvd::rip で使われている
- 標準のフォーマットがStorableだった
- 認証機構があるが、認証メッセージ自体がStorable!!!
- デフォルトのRPCのフォーマットが変更された
- オブジェクトを格納する際の標準のシリアライザがStorable
- memcached injection == 任意コード実行
- Cache::Memcached::Fast::Safe 使うと良い
- 例えば String::Random
- ランダムな文字列を生成してくれる便利モジュール
- tokenの生成には不向き
- rand "だけ"で鍵を作ると、たったの43億通りのパターンしか生成されない
- オフラインで解析可能な用途であれば致命的
- 暗号化cookieの暗号鍵や署名に使う鍵はオフラインで解析可能
- srandに同じ引数を渡すと毎回同じ乱数が生成される
- ☓ srand($value_from_dev_random); rand; rand; rand; rand;
- これは元々Perlがやっていることで、、エントロピー増えない
- ◯ /dev/urandom を直接使ったり、他の予測不可能な値を混ぜる
- ◯ CryptとかSecureとかついたモジュールを使って生成する
- http://blog.64p.org/entry/2014/08/11/145422
- HTTP::Session2::ClientStore Amon2::Plugin::Web::CSRFDefender
- 雛形セットアップで生成される乱数の質が低く、ブルートフォースで解析可能だった。
- Cookieの暗号鍵に使用 → Storableによる任意コード実行