徳丸本読書会sql csrf

21
SQLインジェクション & CSRF 原理とその対策(for Perl) 徳丸本勉強会 2013.11.17 @addsict github.com/addsict/TokumarubonDokusyokai

Upload: yuuki-furuyama

Post on 30-Jun-2015

682 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 徳丸本読書会Sql csrf

SQLインジェクション  &  CSRF  原理とその対策(for  Perl) 徳丸本勉強会  2013.11.17  @addsict

github.com/addsict/TokumarubonDokusyokai  

Page 2: 徳丸本読書会Sql csrf

hIps://github.com/addsict/TokumarubonDokusyokai

github.com/addsict/TokumarubonDokusyokai  

Page 3: 徳丸本読書会Sql csrf

SQLインジェクション

github.com/addsict/TokumarubonDokusyokai  

Page 4: 徳丸本読書会Sql csrf

SQLインジェクションとは

•  Webサイトの脆弱性攻撃の定番中の定番  •  SQL文の構文を「破壊」し悪意のあるSQLに変

え,  テーブルの削除やパスワードの漏洩などを導く攻撃  

•  今日は文字列連結ではない安全なSQLの組み立て方を見ていく  – あまり深堀りはしません…  

github.com/addsict/TokumarubonDokusyokai  

Page 5: 徳丸本読書会Sql csrf

どんな風にSQL文が壊されるの?

•  WebアプリケーションなどではSQL文のリテラル部分がパラメータされていることが一般的  – リテラル:  文字列リテラル,  数値リテラルなど  

•  パラメータに含めた変数が展開されると,  意図しないSQLに変わる危険性  – リテラル以外のものが注入される  

github.com/addsict/TokumarubonDokusyokai  

my  $sql  =  “SELECT  *  FROM  users  WHERE  userid=‘$userid’”;  

“SELECT  *  FROM  users  WHERE  userid=‘’;  DELETE  FROM  users;-­‐-­‐’”;  #  -­‐-­‐  以降はコメントアウト  

$userid  =  “’;DELETE  FROM  users;-­‐-­‐”;  を注入  ⇒  

Page 6: 徳丸本読書会Sql csrf

Exercise:  SQLインジェクション

•  SQLインジェクションを実際にやってみましょう  – レポジトリのsql-­‐injec`on/  内のREADME参照  

•  補足  – DBD::mysqlの場合,  複数SQL文を一度に実行するmysql_mul(_statementsがデフォルトではoffなので,  DBI-­‐>connect時にonにしてある

github.com/addsict/TokumarubonDokusyokai  

Page 7: 徳丸本読書会Sql csrf

SQLインジェクション対策

•  プレースホルダを使用するのが一番安全  – 静的プレースホルダ  – 動的プレースホルダ  

github.com/addsict/TokumarubonDokusyokai  

Page 8: 徳丸本読書会Sql csrf

静的プレースホルダとは?

•  SQLの実行方法に基づいた安全なSQLの組み立て方  –  SQLの実行の流れ:  SQLパース ⇒  構文解析  ⇒  …  ⇒  実行  

•  値が未定のパラメータを含んだSQLを構文解析まで済ませておき,  後にパラメータをバインド  –  構文解析が完了したことでバインド値によらず構文が「破壊」されるこ

とはない  ⇒  原理的に安全  –  DBIではprepareで構文解析を行い,  bind_paramでパラメータをバイン

ドし,  executeで実行  •  *execute時にパラメータをバインドできるが,    パラメータ値が常にVARCHAR型

とみなされSQLの実行時に文字列型から実際の型への変換が行われる  •  Prepared  Statementと呼ばれる  

github.com/addsict/TokumarubonDokusyokai  

my  $sth  =  $dbh-­‐>pepare(“SELECT  *  FROM  users  WHERE  userid  =  ?”);  #  ?がプレースホルダ  $sth-­‐>bind_param(1,  “addsict”,  SQL_VARCHAR);  #  パラメータをバインド  $sth-­‐>execute();

Page 9: 徳丸本読書会Sql csrf

動的プレースホルダはどう違うの?

•  やっていることは文字列連結と変わりない  – アプリケーション側で文字列連結するのではなく,  

ライブラリ・ドライバ側で文字列連結を行う  – DBに応じて適切なエスケープ処理やリテラルの

型をチェックし安全性を担保  

•  DBD::mysqlの場合動的プレースホルダがデフォルトの挙動  – 静的プレースホルダを使うにはDBI-­‐>connectでmysql_server_prepareオプションをONにする

github.com/addsict/TokumarubonDokusyokai  

Page 10: 徳丸本読書会Sql csrf

ORM内でのSQLの組み立て方

•  普段使用しているORMが実際にどのようにSQLを組み立てているか見てみましょう  – プレースホルダは使われていますか?  

•  Tengの場合  – SQL生成はSQL::Makerという別のモジュール  – SQL::Maker::_make_where_condi`on  ⇒  SQL::Maker::Condi`on::add  ⇒  SQL::Maker::Condi`on::_make_tern  

github.com/addsict/TokumarubonDokusyokai  

Page 11: 徳丸本読書会Sql csrf

Exercise:  SQLインジェクション対策

•  先ほどの脆弱性を含むサイトを,  SQLインジェクション対策するように改変してください  

github.com/addsict/TokumarubonDokusyokai  

Page 12: 徳丸本読書会Sql csrf

合わせて読みたい

•  「安全なSQLの呼び出し方」  IPA  – hIp://www.ipa.go.jp/files/000017320.pdf  

•  「SQLインジェクションゴルフ」 徳丸浩の日記  – hIp://blog.tokumaru.org/2013/06/sql-­‐injec`on-­‐golf.html  

•  「mysql  の server  side  prepared  statement  って速いの?」 tokuhirom’s  blog  – hIp://blog.64p.org/entry/20080807/1218080835  

github.com/addsict/TokumarubonDokusyokai  

Page 13: 徳丸本読書会Sql csrf

CSRF

github.com/addsict/TokumarubonDokusyokai  

Page 14: 徳丸本読書会Sql csrf

CSRFの概要

•  Cross  Site  Request  Forgeriesの略  –  Forgeryって?  →  (文書などの)偽造の意  

•  Webアプリケーションの「重要な処理」を行うリクエストを偽装して実行する(なりすまし)攻撃  –  重要な処理:  パスワード変更,  ブログ投稿など  

冪等性を持たない処理  •  できることはWebアプリにHTTPリクエストを送るだけな

ので,  サーバサイドのロジックのみ悪用できる  –  この点でXSSとは異なる  

•  有名な事例  –  mixiのはまちちゃん事件  

github.com/addsict/TokumarubonDokusyokai  

Page 15: 徳丸本読書会Sql csrf

CSRF攻撃成立までの流れ

•  ユーザがターゲットサイトAにログインする  •  ユーザが悪質なサイトBにアクセスする  – サイトBでは(非表示に設定された)iframe内で攻

撃用ページB’にアクセスする  •  iframeを使うのはユーザに攻撃がばれないようにする

ため  

– ページB’ではサイトAの「重要な処理」を行うリクエストを発行することで攻撃完了  

github.com/addsict/TokumarubonDokusyokai  

この2つの条件が満たされただけで攻撃されてしまう!!

Page 16: 徳丸本読書会Sql csrf

Exercise:  CSRF

•  CSRF攻撃を体験してみましょう  – レポジトリのcsrf/  内のREADME参照

github.com/addsict/TokumarubonDokusyokai  

Page 17: 徳丸本読書会Sql csrf

CSRF攻撃が生まれる原因

•  ブラウザ(の仕様)が悪い!  –  form要素のac`on属性にどのドメインのURLでも指定

可能  •  同一生成元ポリシーは適用されない  

– クッキーは自動的にリクエスト先のサイトに送信される  •  ログイン済みであればセッション情報がクッキー上に  

•  正規リクエストと偽造リクエストの違いはRefererの違いだけ  – ログを見てリクエストヘッダを確認してみよう

github.com/addsict/TokumarubonDokusyokai  

Page 18: 徳丸本読書会Sql csrf

CSRFの対策は?

•  まずCSRF対策が必要なページを区別  – 全てのページにCSRF対策が必要なわけではない  

•  CSRF対策されると困るケースもある(他のサイトからのリクエストが重要なページなど)  

•  対策手法  – Refererをチェックする  – 第三者が知りえないトークンを埋め込む  

github.com/addsict/TokumarubonDokusyokai  

Page 19: 徳丸本読書会Sql csrf

対策手法 -­‐  Refererのチェック -­‐  

•  正規リクエストと偽造リクエストはRefererが異なる  –  render_403  if  header-­‐>{referer}  ne  proper_referer;  

•  注意点  – Refererを送信しないように設定する利用者もいる  – Refererチェックの漏れが起こりうる

•  hIp://tokumaru.jp/  からのリクエストを許す場合以下の正規表現で大丈夫?  xxxxにURLを入れて試してみよう  

github.com/addsict/TokumarubonDokusyokai  

perl  -­‐e  ”$referer  =  xxxx;  if  ($referer  =~  m#^hIp://tokumaru.jp#)  {print  'ok';}"

Page 20: 徳丸本読書会Sql csrf

対策手法  -­‐  トークンの埋め込み  -­‐

•  攻撃者が事前に知りえない情報をリクエストに含めて渡す  –  POSTの場合,  リクエストbodyにトークンを含める  –  トークンとしてセッションIDを使うのが簡易な方法  

•  <input  type=“hidden”  name=“token”  value=“<:  $sid  :>”>  •  CSRFではターゲットサイトのCookieには触れないことに注意  

•  twiIerもこの対策を取っている  –  Chromeの開発者ツールを開いた状態でツイートしてみよう.  

ツイート内容と共に何がPOSTされてますか?  •  実装めんどい?  

–  それCPANにあるよ Plack::Middleware::CSRFBlock  •  POSTメソッドを使用するformタグを探し,  トークンを自動で埋め込む  •  既存アプリのコードに手を入れないでok  

github.com/addsict/TokumarubonDokusyokai  

Page 21: 徳丸本読書会Sql csrf

Exercise:  CSRF対策

•  先ほどの脆弱性を含むサイトを,  CSRF対策するように改変してください  – Refererチェックで対策する例  

•  csrf/refererブランチ  

– トークンで対策する例  •  csrf/tokenブランチ

github.com/addsict/TokumarubonDokusyokai