SlideShare a Scribd company logo
1 of 58
Download to read offline
徳丸先生に怒られない
動的SQLの
安全な組み立て方
Makoto Kuwata
http://www.kuwata-lab.com/
PHP Conference 2015
ver 1.1.0
copyright 2015 kuwata-lab.com all rights reserved.©
本発表の作成には徳丸先生は関わって

おりません。
内容の責任はすべて発表者にあるので、
ご意見がありましたら先生にではなく
発表者までお願いします。
!! CAUTION !!
copyright 2015 kuwata-lab.com all rights reserved.©
発表の背景:裁判と損害賠償
引用: http://blog.tokumaru.org/2015/01/sql.html
SQLインジェクション脆弱性が原因でクレジット
カード情報が漏洩した事件につき、ショップ側が

開発会社を相手取り損害賠償請求の裁判を起こし、
ショップ側が勝訴
結果、3131万9568円の損害を認定し、その3割を

控除して、2262万3697円の損害賠償をY社に

命じた
copyright 2015 kuwata-lab.com all rights reserved.©
発表の背景:ばく大な金額
引用: http://www.ipa.go.jp/files/000013778.pdf
(SQLiによる推計される被害額について)
推計すると、約 4,800 万円∼1 億円程度を要する
ものと考えられる。
copyright 2015 kuwata-lab.com all rights reserved.©
発表の目的
SQL Injection が起きる真の原因を考える
「プレースホルダを使ってないから」では考察不足
SQL Injection を起こさない方法を考える
「プレースホルダを使え」では対策不足
copyright 2015 kuwata-lab.com all rights reserved.©
アジェンダ
考察:なぜSQL Injectionが発生するのか?
対策:SQLテンプレート
対策:SQL構文木
まとめ
copyright 2015 kuwata-lab.com all rights reserved.©
前提知識
SQL Injection が何か、知ってること
(以降では SQL Injection を SQLi と省略)
プレースホルダやバインド変数について

知ってること
「:id」や「?」がプレースホルダ、渡す値がバインド変数
PHPのコードが読めること
PHPカンファレンスなので :)
なぜSQL Injection が
発生するのか?
copyright 2015 kuwata-lab.com all rights reserved.©
SQL Injection 対策
エスケープしろ!プレースホルダを使え!
http://www.ipa.go.jp/files/000017320.pdf
copyright 2015 kuwata-lab.com all rights reserved.©
なぜSQL Injectionが発生するのか?
プレースホルダを使ってないから?
copyright 2015 kuwata-lab.com all rights reserved.©
プレースホルダを使っててもSQLi
$sql	 =	 "select	 *	 from	 users"	 .

	 	 	 	 	 	 	 "	 where	 deleted_at	 is	 null";

$vars	 =	 [];

if	 ($max_age)	 {

	 	 $sql	 .=	 "	 and	 age	 <=	 :max_age";

	 	 $vars['max_age']	 =	 $max_age;

}

if	 ($min_age)	 {

	 	 $sql	 .=	 "	 and	 age	 >=	 ".$min_age;

	 	 $vars['min_age']	 =	 $min_age;

}
プレースホルダを
使っている
ただの文字列
連結! SQLi!
copyright 2015 kuwata-lab.com all rights reserved.©
なぜSQL Injectionが発生するのか?
プレースホルダを使ってないから?
実情は、プレースホルダつきの安全なSQLを組み立てて

いる最中に SQL Injection が入り込んでいる
 
これこそが真の原因
文字列連結でSQLを組み立ててるから
copyright 2015 kuwata-lab.com all rights reserved.©
変数の埋め込みも文字列連結と同じ
//	 これと

$sql	 .=	 "	 and	 age	 >=	 ".$min_age;

//	 これは同じ

$sql	 .=	 "	 and	 age	 >=	 $min_age";
変数の埋め込みも
文字列連結と同じ
copyright 2015 kuwata-lab.com all rights reserved.©
なぜ文字列結合でSQLを作るのか?
プレースホルダではできないことがあるから
要素数が動的に変わる in (....) 、order by でのカラム名指定
 
真の原因その2
//	 SQLを文字列で渡せてしまえるんだから、

//	 SQLを文字列結合で組み立ててしまうのは当然のこと

$st	 =	 pdo->prepare("select	 *	 from	 users");
SQLを文字列で指定できてしまうから
copyright 2015 kuwata-lab.com all rights reserved.©
SQL Injection を防ぐには?
文字列連結ではない方法で動的SQLを

組み立てればよい
方法:SQLテンプレート or SQL構文木 (詳細は後述)
SQL文字列ではない方法でSQLを

指定できるようにすればよい
方法:SQL ID or SQL構文木 (詳細は後述)
copyright 2015 kuwata-lab.com all rights reserved.©
SQL Injection が発生する本当の原因は、
ライブラリや API のインターフェースに
欠陥があるからである。
間違いを誘発するものを使い続ける限り、
SQL Injection がなくなることはない。
Let's Tweet!
copyright 2015 kuwata-lab.com all rights reserved.©
ここまでのまとめ
SQLを文字列連結で組み立てるから、

SQL Injection が発生する
対策:文字列連結ではない方法でSQLを組み立てる
生のSQLを文字列で渡せてしまうから、

文字列連結を使ってしまう
対策:生のSQLを渡すかわりに別の方法でSQLを指定する
本質的にはAPIやインターフェースの欠陥
結果はセキュリティ被害だけど、原因はセキュリティとは違う
SQLテンプレート
copyright 2015 kuwata-lab.com all rights reserved.©
SQLテンプレートとは?
SQLを生成するためのテンプレート
WebアプリでのHTMLテンプレートと同じ
SQL Injection が発生しない(原理上は)
文字列連結が不可、値のエスケープ or プレースホルダを強制
注:内部の実装では文字列連結を使うが、開発者が明示的に使うことはできない。
copyright 2015 kuwata-lab.com all rights reserved.©
サンプル:SQLテンプレート
/*	 年齢の上限/下限が指定されたら、検索条件を追加	 */

select	 *	 from	 users

where	 deleted_at	 is	 null

--	 #if	 :max_age

	 	 and	 age	 <=	 :max_age

--	 #end

--	 #if	 :min_age

	 	 and	 age	 >=	 :min_age

--	 #end
copyright 2015 kuwata-lab.com all rights reserved.©
サンプル:PHPコードへ変換
/*	 年齢の上限/下限が指定されたら、検索条件を追加	 */

select	 *	 from	 users

where	 deleted_at	 is	 null

<?php	 if	 ($vars['max_age'])	 {	 ?>

	 	 and	 age	 <=	 :max_age

<?php	 }	 ?>

<?php	 if	 ($vars['min_age'])	 {	 ?>

	 	 and	 age	 >=	 :min_age

<?php	 }	 ?>
注:実際はもう少し複雑なコードに変換される
copyright 2015 kuwata-lab.com all rights reserved.©
サンプル:生成されたSQL
//	 $var	 =	 array("min_age"=>20)	 なら

select	 *	 from	 users

where	 deleted_at	 is	 null

	 	 and	 age	 >=	 :min_age
copyright 2015 kuwata-lab.com all rights reserved.©
SQLTempl8
SQLを対象としたテンプレートエンジン
https://github.com/kwatch/sqltempl8/
まだコンセプト実装 (いろいろ足りない)
使い方は随時変わるので、最新のドキュメントを参照のこと
copyright 2015 kuwata-lab.com all rights reserved.©
SQLTempl8:SQLを生成
1:	 <?php

2:	 require_once	 'sqltempl8.php';

3:	 $t	 =	 new	 SQLTempl8("sql/users.sql");

4:	 $vars	 =	 array('min_age'=>20);

5:	 $sql	 =	 $t->render($vars);

6:	 echo	 $sql;

	 	 	 	 	 	 //=>	 select	 *	 from	 users

	 	 	 	 	 	 //	 	 	 where	 deleted_at	 is	 null

	 	 	 	 	 	 //	 	 	 	 	 and	 age	 >=	 :min_age
copyright 2015 kuwata-lab.com all rights reserved.©
SQLTempl8:SQLを実行
1:	 <?php

2:	 require_once	 'sqltempl8.php';

3:	 $t	 =	 new	 SQLTempl8("sql/users.sql");

4:	 $vars	 =	 array('min_age'=>20);

5:	 $pdo_conn	 =	 new	 PDO(".....");

6:	 $pdo_stmt	 =	 $t->execute($pdo_conn,	 $vars);

7:	 if	 ($pdo_stmt	 !==	 null)	 {

8:	 	 	 foreach	 ($pdo_stmt	 as	 $row)	 {	 ...	 }

9:	 }
copyright 2015 kuwata-lab.com all rights reserved.©
なぜSQL Injectionが発生しないの?
//	 SQLテンプレート

select	 *	 from	 users

where	 deleted_at	 is	 null

--	 #if	 :max_age

	 	 and	 age	 <=	 :max_age

--	 #end

--	 #if	 :min_age

	 	 and	 age	 >=	 :min_age

--	 #end
文字列連結が書けない
(文法が極めて限定的)
変数値が埋め込めない
(プレースホルダを強制)
copyright 2015 kuwata-lab.com all rights reserved.©
なぜSQL Injectionが発生しないの?
//	 メインプログラム

<?php

require_once	 'sqltempl8.php';

$t	 =	 new	 SQLTempl8("sql/users.sql");

$vars	 =	 array('min_age'=>20);

$pdo_conn	 =	 new	 PDO(".....");

$pdo_stmt	 =	 $t->execute($pdo_conn,	 $vars);

if	 ($pdo_stmt	 !==	 null)	 {

	 	 foreach	 ($pdo_stmt	 as	 $row)	 {	 ...	 }

}
SQL IDとしてテンプレートの
ファイル名を指定
(生のSQLを指定しない)
copyright 2015 kuwata-lab.com all rights reserved.©
Q:PHPコードが埋め込めるのでは?
セキュリティ上の大きな穴になりそう…
//	 SQL	 template

select	 <?=	 $_GET['param']	 ?>

from	 users

where	 true

	 	 --	 %	 if	 :max_age

	 	 and	 age	 <=	 :max_age

	 	 --	 %	 end

	 	 --	 %	 if	 :min_age

	 	 and	 age	 >=	 :min_age

	 	 --	 %	 end
copyright 2015 kuwata-lab.com all rights reserved.©
A:'<?' をエスケープします
ちゃんとSQL Syntax Errorになってくれます
//	 PHP	 code

select	 <<?php	 ?>?=	 $_GET['param']	 ?>

from	 users

where	 true

<?php	 if	 ($var['max_age'])	 {	 ?>

	 	 and	 age	 <=	 :max_age

<?php	 }	 ?>

<?php	 if	 ($var['min_age'])	 {	 ?>

	 	 and	 age	 >=	 :min_age

<?php	 }	 ?>
copyright 2015 kuwata-lab.com all rights reserved.©
Q:'=' と 'is null' との切り替えは?
値が null なら '=' を 'is null' にしてほしい
select	 *	 from	 users

where	 deleted_on	 =	 :deleted

//	 これ↓は面倒なのでいやだ

select	 *	 from	 users

--	 #if	 :deleted

where	 deleted_on	 =	 :deleted

--	 #else

where	 deleted_on	 is	 null

--	 #end
$vars['deleted'] がnullなら

'=' を 'is null' に自動的に変更
してほしい
copyright 2015 kuwata-lab.com all rights reserved.©
A:MySQLの '<=>' 演算子を使おう
ポスグレなら 'is not distinct from' 演算子
select	 *	 from	 users

where	 deleted_on	 <=>	 :deleted

値が null なら deleted_on is null と同じ、
それ以外なら deleted_on = :deleted と同じ
注:本当なら、SQL構文を解析して '=' 演算子を置換することが望ましい。
copyright 2015 kuwata-lab.com all rights reserved.©
Q:where句の追加が面倒では?
例:上下限値があるときだけwhere句を追加
select	 *	 from	 users

--	 #if	 :max_age	 or	 :min_age

where	 true

	 	 --	 #if	 :max_age

	 	 and	 age	 <=	 :max_age

	 	 --	 #end

	 	 --	 #if	 :min_age

	 	 and	 age	 >=	 :min_age

	 	 --	 #end

--	 #end
この条件分岐が面倒!!
copyright 2015 kuwata-lab.com all rights reserved.©
A:DBの最適化機能に任せよう
「where true」が残っても性能に影響はない
select	 *	 from	 users

--	 #if	 :max_age	 or	 :min_age

where	 true

	 	 --	 #if	 :max_age

	 	 and	 age	 <=	 :max_age

	 	 --	 #end

	 	 --	 #if	 :min_age

	 	 and	 age	 >=	 :min_age

	 	 --	 #end

--	 #end
余分な 'where true' は
DBのOptimizerが

取り除いてくれる
(実行計画を見れば確認可能)
copyright 2015 kuwata-lab.com all rights reserved.©
Q:やっぱり埋め込み式が欲しい!
placeholderでは表名やカラム名が指定できない
select	 *

from	 blog_entries_<?=	 $user	 ?>

where	 deleted_at	 is	 null

order	 by	 <?=	 $sortkey	 ?>
from :table とはできない
order by :sortkey とはできない
copyright 2015 kuwata-lab.com all rights reserved.©
A:制限つき埋め込み式を用意しました
値として、英数字と '_' と '.' だけを許可
//	 SQL	 template

select	 *	 from	 blog_entries

order	 by	 [=:sortkey=]

//	 PHP	 code

select	 *	 from	 blog_entries

order	 by	 <?php

if	 (!	 preg_match('/^w+(.w+)*$/',

	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 $vars['sortkey'])

	 	 throw	 new	 SQLTemplateError("error");

echo	 $vars['sortkey'];	 ?>
テーブル名やカラム名で
なければ例外を発生
copyright 2015 kuwata-lab.com all rights reserved.©
課題
xxx in (...) のサポートがまだ
プレースホルダではうまく扱うのが難しく、仕様を考え中

(できるならPDOのエスケープ機能 quote() を拡張したい)
foreach文の導入がまだ
これもプレースホルダでは扱いが難しいが、いわゆる

バルクインサートでは必須なので実装したい
PDOは全部文字列として扱ってしまう!
バインド変数にデータ型を指定するよう変更予定
copyright 2015 kuwata-lab.com all rights reserved.©
ここまでのまとめ
SQLテンプレートならSQLiが発生しない
文字列結合が書けない

プレースホルダやエスケープを強制

生SQLを指定できない
SQL構文木
copyright 2015 kuwata-lab.com all rights reserved.©
SQL構文木とは?
SQLを木構造で表したデータ
select
* where
=
id 123
from
books
copyright 2015 kuwata-lab.com all rights reserved.©
SQL構文木の組み立て方
通常は専用のライブラリを使うか、…
$q	 =	 new	 Query();

$q->select('*')

	 	 ->from('books')

	 	 ->where('id',	 '=',	 123);

$book	 =	 $q->query();
copyright 2015 kuwata-lab.com all rights reserved.©
SQL構文木の組み立て方
O/R Mapperを使う
class	 Book	 extends	 Entity	 {	 ...	 };

class	 Books	 extends	 Schema	 {	 ...	 };

$q	 =	 new	 Query(Books);

$q->where(Books::id->eq(123));

$book	 =	 $q->select('*');
copyright 2015 kuwata-lab.com all rights reserved.©
SQL構文木の組み立て方
演算子オーバーライドが使えると自然な記述に
//	 Ruby

book	 =	 Book.where(:id	 ==	 123).first()

//	 Python

book	 =	 db.query(Book)	 

	 	 	 	 	 	 	 	 	 .filter(Book.id	 ==	 123)	 

	 	 	 	 	 	 	 	 	 .first()
true/falseではなく
部分構文木を返す
参考:「演算子オーバーライドをDSLに活用する」でggr
copyright 2015 kuwata-lab.com all rights reserved.©
構文木 → SQL文字列
'=' と 'is null' も、値に応じて自動的に変換
where
==
id 123
where
==
id null
where id = 123 where id is null
copyright 2015 kuwata-lab.com all rights reserved.©
なぜSQL Injectionを防げるの?
文字列結合後にSQLをパースするからSQLiが発生
$id	 =	 $_GET['id'];

$sql	 =	 "select	 *	 from	 books

	 	 	 	 	 	 	 	 where	 id	 =	 '$id'";

//	 もし	 $id	 が	 "'	 or	 1<>'"	 なら…⋯

select	 *	 from	 books

where	 id	 =	 ''	 or	 1<>''

意図しない構造に
変わってしまった!
copyright 2015 kuwata-lab.com all rights reserved.©
なぜSQL Injectionを防げるの?
SQL構文木なら意図しない変更ができない
where
=
id ' or 1 <>'
$q->where(

	 	 	 	 	 	 Books::id,

	 	 	 	 	 	 '=',

	 	 	 	 	 	 $_GET['id']

	 	 	 	 );

悪意ある値を
受けとっても…
木構造は影響を
受けない
copyright 2015 kuwata-lab.com all rights reserved.©
本当は構文木のままDBに送信したい
SQL文字列は直列化形式として本当に妥当なのか?
where
=
id 123
送信
(注)直列化:構造のあるデータをバイト列に変換すること。

データを送信したりファイルに保存するときに必要。
データベース
変換
select	 ...

from	 ...

where	 ...

	 and	 ...
もっと改ざんされにくい
形式でもいいのでは?
SQL文字列構文木
copyright 2015 kuwata-lab.com all rights reserved.©
注意!それは木構造ではない!
//	 一見、木構造を作ってるように見えるが…⋯

$q->where('id	 =	 ?',	 $_GET['id']);

//	 実はそうではない

$q->where($_GET['col'].'	 =	 ?',	 $_GET['id']);
SQLを文字列で指定できて
しまうのでアウト
copyright 2015 kuwata-lab.com all rights reserved.©
課題
動作速度は遅い
木構造の構築も、SQLへの変換も、動作コストが大きい
昨今のCPUパワーをもっと
安全性のために使ってほしい
copyright 2015 kuwata-lab.com all rights reserved.©
ここまでのまとめ
SQL構文木を作るとSQLiが発生しない
悪意ある文字列を渡されてもSQL構造が変更されない
まとめ
copyright 2015 kuwata-lab.com all rights reserved.©
まとめ
動的SQLを作るのに文字列結合を避ける
かわりにSQLテンプレートやSQL構文木を使う
本質的にはAPIやインターフェースの欠陥
生のSQLを文字列で渡せてしまう

→ だからSQLを文字列で組み立ててしまう

→ だからSQL Injectionがなくならない
copyright 2015 kuwata-lab.com all rights reserved.©
補足
型はSQLiの防止に役立つか?
Yes。型はValidationに役立つ、そしてバインド変数の
ValidationはSQLi防止に有効、なので型はSQLi防止に役立つ
型安全であればSQLiは防げるか?
No。型安全でも文字列連結はできる、そして文字列連結を使
うとSQLiが起こり得る、なので型安全でもSQLiが起こり得る
参考:https://twitter.com/ockeghem/status/650171306428596224
https://twitter.com/tanakh/status/650214648382291968

https://twitter.com/tanakh/status/650215363943116800
型安全だけではSQLiは防げない、
もう一工夫必要
copyright 2015 kuwata-lab.com all rights reserved.©
参考資料 (SQLテンプレート)
SQLTempl8
https://github.com/kwatch/sqltempl8
Doma - SQLテンプレートの仕組み
http://www.slideshare.net/taedium/doma-sql
DBFlute入門 - 外だしSQLの基本
http://gihyo.jp/dev/feature/01/dbflute/0005
S2JDBC - SQLファイル
http://s2container.seasar.org/2.4/ja/s2jdbc_manager_sqlfile.html
copyright 2015 kuwata-lab.com all rights reserved.©
参考資料 (SQL構文木)
演算子オーバーライドをDSLに活用する
http://j.mp/slide_opdsl
O/R Mapperによるトラブルを未然に防ぐ
http://j.mp/slide_orm2
O/Rマッパーを支える技術
http://j.mp/slide_orm1
copyright 2015 kuwata-lab.com all rights reserved.©
お客さまにおすすめの新刊があります
徳丸浩のWebセキュリティ教室
2015-10-22 発売予定
日経BP社
1944円
Let's Tweet!
絶賛予約受付中!
One More Thing...
copyright 2015 kuwata-lab.com all rights reserved.©
私的反省会
今回の内容は、HTMLテンプレートでは

すでに知られていたことばかり
自動エスケープ機能や、木構造が安全なことなど
それをSQLへ応用するのが遅れたせいで

不幸な判決を生み出してしまった
HTMLテンプレートエンジン作者の一人としてお詫びします

ごめんなさい
copyright 2015 kuwata-lab.com all rights reserved.©
おしまい

More Related Content

What's hot

とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達zaki4649
 
Keycloak拡張入門
Keycloak拡張入門Keycloak拡張入門
Keycloak拡張入門Hiroyuki Wada
 
徳丸本に載っていないWebアプリケーションセキュリティ
徳丸本に載っていないWebアプリケーションセキュリティ徳丸本に載っていないWebアプリケーションセキュリティ
徳丸本に載っていないWebアプリケーションセキュリティHiroshi Tokumaru
 
今さら聞けないXSS
今さら聞けないXSS今さら聞けないXSS
今さら聞けないXSSSota Sugiura
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説murachue
 
猫でもわかるかもしれない SQLインジェクション
猫でもわかるかもしれない SQLインジェクション猫でもわかるかもしれない SQLインジェクション
猫でもわかるかもしれない SQLインジェクションkinme modoki
 
基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装Masatoshi Tada
 
アプリ開発で知っておきたい認証技術 - OAuth 1.0 + OAuth 2.0 + OpenID Connect -
アプリ開発で知っておきたい認証技術 - OAuth 1.0 + OAuth 2.0 + OpenID Connect -アプリ開発で知っておきたい認証技術 - OAuth 1.0 + OAuth 2.0 + OpenID Connect -
アプリ開発で知っておきたい認証技術 - OAuth 1.0 + OAuth 2.0 + OpenID Connect -Naoki Nagazumi
 
Easybuggy(バグ)の召し上がり方
Easybuggy(バグ)の召し上がり方Easybuggy(バグ)の召し上がり方
Easybuggy(バグ)の召し上がり方広平 田村
 
外部キー制約に伴うロックの小話
外部キー制約に伴うロックの小話外部キー制約に伴うロックの小話
外部キー制約に伴うロックの小話ichirin2501
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーyoku0825
 
文字コードに起因する脆弱性とその対策(増補版)
文字コードに起因する脆弱性とその対策(増補版)文字コードに起因する脆弱性とその対策(増補版)
文字コードに起因する脆弱性とその対策(増補版)Hiroshi Tokumaru
 
SQLインジェクション総”習”編
SQLインジェクション総”習”編SQLインジェクション総”習”編
SQLインジェクション総”習”編Yasuo Ohgaki
 

What's hot (20)

Phpcon2015
Phpcon2015Phpcon2015
Phpcon2015
 
とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達
 
Keycloak拡張入門
Keycloak拡張入門Keycloak拡張入門
Keycloak拡張入門
 
徳丸本に載っていないWebアプリケーションセキュリティ
徳丸本に載っていないWebアプリケーションセキュリティ徳丸本に載っていないWebアプリケーションセキュリティ
徳丸本に載っていないWebアプリケーションセキュリティ
 
今さら聞けないXSS
今さら聞けないXSS今さら聞けないXSS
今さら聞けないXSS
 
Docker Compose 徹底解説
Docker Compose 徹底解説Docker Compose 徹底解説
Docker Compose 徹底解説
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
Proxy War
Proxy WarProxy War
Proxy War
 
猫でもわかるかもしれない SQLインジェクション
猫でもわかるかもしれない SQLインジェクション猫でもわかるかもしれない SQLインジェクション
猫でもわかるかもしれない SQLインジェクション
 
基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装
 
アプリ開発で知っておきたい認証技術 - OAuth 1.0 + OAuth 2.0 + OpenID Connect -
アプリ開発で知っておきたい認証技術 - OAuth 1.0 + OAuth 2.0 + OpenID Connect -アプリ開発で知っておきたい認証技術 - OAuth 1.0 + OAuth 2.0 + OpenID Connect -
アプリ開発で知っておきたい認証技術 - OAuth 1.0 + OAuth 2.0 + OpenID Connect -
 
Easybuggy(バグ)の召し上がり方
Easybuggy(バグ)の召し上がり方Easybuggy(バグ)の召し上がり方
Easybuggy(バグ)の召し上がり方
 
外部キー制約に伴うロックの小話
外部キー制約に伴うロックの小話外部キー制約に伴うロックの小話
外部キー制約に伴うロックの小話
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
Vue.js で XSS
Vue.js で XSSVue.js で XSS
Vue.js で XSS
 
WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介
 
文字コードに起因する脆弱性とその対策(増補版)
文字コードに起因する脆弱性とその対策(増補版)文字コードに起因する脆弱性とその対策(増補版)
文字コードに起因する脆弱性とその対策(増補版)
 
KeycloakでAPI認可に入門する
KeycloakでAPI認可に入門するKeycloakでAPI認可に入門する
KeycloakでAPI認可に入門する
 
TLS, HTTP/2演習
TLS, HTTP/2演習TLS, HTTP/2演習
TLS, HTTP/2演習
 
SQLインジェクション総”習”編
SQLインジェクション総”習”編SQLインジェクション総”習”編
SQLインジェクション総”習”編
 

Viewers also liked

CODE BLUE 2014 : バグハンターの愉しみ by キヌガワマサト Masato Kinugawa
CODE BLUE 2014 : バグハンターの愉しみ by キヌガワマサト Masato KinugawaCODE BLUE 2014 : バグハンターの愉しみ by キヌガワマサト Masato Kinugawa
CODE BLUE 2014 : バグハンターの愉しみ by キヌガワマサト Masato KinugawaCODE BLUE
 
バグハンターの哀しみ
バグハンターの哀しみバグハンターの哀しみ
バグハンターの哀しみMasato Kinugawa
 
20120830 DBリファクタリング読書会第三回
20120830 DBリファクタリング読書会第三回20120830 DBリファクタリング読書会第三回
20120830 DBリファクタリング読書会第三回都元ダイスケ Miyamoto
 
Lars George HBase Seminar with O'REILLY Oct.12 2012
Lars George HBase Seminar with O'REILLY Oct.12 2012Lars George HBase Seminar with O'REILLY Oct.12 2012
Lars George HBase Seminar with O'REILLY Oct.12 2012Cloudera Japan
 
並列データベースシステムの概念と原理
並列データベースシステムの概念と原理並列データベースシステムの概念と原理
並列データベースシステムの概念と原理Makoto Yui
 
Writing Yarn Applications Hadoop Summit 2012
Writing Yarn Applications Hadoop Summit 2012Writing Yarn Applications Hadoop Summit 2012
Writing Yarn Applications Hadoop Summit 2012Hortonworks
 
Future of HCatalog - Hadoop Summit 2012
Future of HCatalog - Hadoop Summit 2012Future of HCatalog - Hadoop Summit 2012
Future of HCatalog - Hadoop Summit 2012Hortonworks
 
【17-E-3】 オンライン機械学習で実現する大規模データ処理
【17-E-3】 オンライン機械学習で実現する大規模データ処理【17-E-3】 オンライン機械学習で実現する大規模データ処理
【17-E-3】 オンライン機械学習で実現する大規模データ処理Developers Summit
 
Data analytics with hadoop hive on multiple data centers
Data analytics with hadoop hive on multiple data centersData analytics with hadoop hive on multiple data centers
Data analytics with hadoop hive on multiple data centersHirotaka Niisato
 
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)Satoshi Yamada
 
Cloudera Manager4.0とNameNode-HAセミナー資料
Cloudera Manager4.0とNameNode-HAセミナー資料Cloudera Manager4.0とNameNode-HAセミナー資料
Cloudera Manager4.0とNameNode-HAセミナー資料Cloudera Japan
 
あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界Yoshinori Nakanishi
 
Hadoop Summit 2012 - Hadoop and Vertica: The Data Analytics Platform at Twitter
Hadoop Summit 2012 - Hadoop and Vertica: The Data Analytics Platform at TwitterHadoop Summit 2012 - Hadoop and Vertica: The Data Analytics Platform at Twitter
Hadoop Summit 2012 - Hadoop and Vertica: The Data Analytics Platform at TwitterBill Graham
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編Miki Shimogai
 
Datalogからsqlへの トランスレータを書いた話
Datalogからsqlへの トランスレータを書いた話Datalogからsqlへの トランスレータを書いた話
Datalogからsqlへの トランスレータを書いた話Yuki Takeichi
 
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~Miki Shimogai
 

Viewers also liked (18)

CODE BLUE 2014 : バグハンターの愉しみ by キヌガワマサト Masato Kinugawa
CODE BLUE 2014 : バグハンターの愉しみ by キヌガワマサト Masato KinugawaCODE BLUE 2014 : バグハンターの愉しみ by キヌガワマサト Masato Kinugawa
CODE BLUE 2014 : バグハンターの愉しみ by キヌガワマサト Masato Kinugawa
 
バグハンターの哀しみ
バグハンターの哀しみバグハンターの哀しみ
バグハンターの哀しみ
 
20120830 DBリファクタリング読書会第三回
20120830 DBリファクタリング読書会第三回20120830 DBリファクタリング読書会第三回
20120830 DBリファクタリング読書会第三回
 
Lars George HBase Seminar with O'REILLY Oct.12 2012
Lars George HBase Seminar with O'REILLY Oct.12 2012Lars George HBase Seminar with O'REILLY Oct.12 2012
Lars George HBase Seminar with O'REILLY Oct.12 2012
 
並列データベースシステムの概念と原理
並列データベースシステムの概念と原理並列データベースシステムの概念と原理
並列データベースシステムの概念と原理
 
Writing Yarn Applications Hadoop Summit 2012
Writing Yarn Applications Hadoop Summit 2012Writing Yarn Applications Hadoop Summit 2012
Writing Yarn Applications Hadoop Summit 2012
 
Future of HCatalog - Hadoop Summit 2012
Future of HCatalog - Hadoop Summit 2012Future of HCatalog - Hadoop Summit 2012
Future of HCatalog - Hadoop Summit 2012
 
【17-E-3】 オンライン機械学習で実現する大規模データ処理
【17-E-3】 オンライン機械学習で実現する大規模データ処理【17-E-3】 オンライン機械学習で実現する大規模データ処理
【17-E-3】 オンライン機械学習で実現する大規模データ処理
 
Data analytics with hadoop hive on multiple data centers
Data analytics with hadoop hive on multiple data centersData analytics with hadoop hive on multiple data centers
Data analytics with hadoop hive on multiple data centers
 
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
 
Database smells
Database smellsDatabase smells
Database smells
 
Cloudera Manager4.0とNameNode-HAセミナー資料
Cloudera Manager4.0とNameNode-HAセミナー資料Cloudera Manager4.0とNameNode-HAセミナー資料
Cloudera Manager4.0とNameNode-HAセミナー資料
 
あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界
 
Hadoop Summit 2012 - Hadoop and Vertica: The Data Analytics Platform at Twitter
Hadoop Summit 2012 - Hadoop and Vertica: The Data Analytics Platform at TwitterHadoop Summit 2012 - Hadoop and Vertica: The Data Analytics Platform at Twitter
Hadoop Summit 2012 - Hadoop and Vertica: The Data Analytics Platform at Twitter
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編
 
ならば(その弐)
ならば(その弐)ならば(その弐)
ならば(その弐)
 
Datalogからsqlへの トランスレータを書いた話
Datalogからsqlへの トランスレータを書いた話Datalogからsqlへの トランスレータを書いた話
Datalogからsqlへの トランスレータを書いた話
 
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
 

Similar to 【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方

MT meets PHP - PHP conference Kansai 2013
MT meets PHP - PHP conference Kansai 2013MT meets PHP - PHP conference Kansai 2013
MT meets PHP - PHP conference Kansai 2013純生 野田
 
Zend Frameworkで始める携帯サイト
Zend Frameworkで始める携帯サイトZend Frameworkで始める携帯サイト
Zend Frameworkで始める携帯サイト清水樹
 
Phpcon tokyo 20120_bigginer
Phpcon tokyo 20120_bigginerPhpcon tokyo 20120_bigginer
Phpcon tokyo 20120_bigginerHideo Kashioka
 
開発エンジニアがChefで テスト駆動サーバー設定してみた #biglobetechtalk
開発エンジニアがChefで テスト駆動サーバー設定してみた #biglobetechtalk開発エンジニアがChefで テスト駆動サーバー設定してみた #biglobetechtalk
開発エンジニアがChefで テスト駆動サーバー設定してみた #biglobetechtalkBIGLOBE Tech Talk
 
Struts2を始めよう!
Struts2を始めよう!Struts2を始めよう!
Struts2を始めよう!Shinpei Ohtani
 
phpMyAdminにおけるスクリプト実行可能な脆弱性3種盛り合わせ
phpMyAdminにおけるスクリプト実行可能な脆弱性3種盛り合わせphpMyAdminにおけるスクリプト実行可能な脆弱性3種盛り合わせ
phpMyAdminにおけるスクリプト実行可能な脆弱性3種盛り合わせHiroshi Tokumaru
 
DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~
DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~
DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~decode2016
 
MySQL Technology Cafe #12 MDS HA検証 ~パラメータからパフォーマンスまで~
MySQL Technology Cafe #12 MDS HA検証 ~パラメータからパフォーマンスまで~MySQL Technology Cafe #12 MDS HA検証 ~パラメータからパフォーマンスまで~
MySQL Technology Cafe #12 MDS HA検証 ~パラメータからパフォーマンスまで~オラクルエンジニア通信
 
15分でCakePHPを始める方法(Nseg 2013-11-09 )
15分でCakePHPを始める方法(Nseg 2013-11-09 )15分でCakePHPを始める方法(Nseg 2013-11-09 )
15分でCakePHPを始める方法(Nseg 2013-11-09 )hiro345
 
July Tech Festa 2014発表資料
July Tech Festa 2014発表資料July Tech Festa 2014発表資料
July Tech Festa 2014発表資料Kenta Hattori
 
Hack/HHVM 入門
Hack/HHVM 入門Hack/HHVM 入門
Hack/HHVM 入門y-uti
 
Nashorn in the future (Japanese)
Nashorn in the future (Japanese)Nashorn in the future (Japanese)
Nashorn in the future (Japanese)Logico
 
関西Php勉強会のlimeの話
関西Php勉強会のlimeの話関西Php勉強会のlimeの話
関西Php勉強会のlimeの話Hisateru Tanaka
 
「さくらのクラウド」スタートアップスクリプトを作ってみよう! - concrete5を題材に -(オープンソースカンファレンス2014 Shimane)
「さくらのクラウド」スタートアップスクリプトを作ってみよう! - concrete5を題材に -(オープンソースカンファレンス2014 Shimane)「さくらのクラウド」スタートアップスクリプトを作ってみよう! - concrete5を題材に -(オープンソースカンファレンス2014 Shimane)
「さくらのクラウド」スタートアップスクリプトを作ってみよう! - concrete5を題材に -(オープンソースカンファレンス2014 Shimane)さくらインターネット株式会社
 
Jyoken 講習20150513
Jyoken 講習20150513Jyoken 講習20150513
Jyoken 講習20150513reew2n
 
Webサーバのチューニング
WebサーバのチューニングWebサーバのチューニング
WebサーバのチューニングYu Komiya
 
System4 comment
System4 commentSystem4 comment
System4 commentJun Chiba
 
コンテナで作れるFaaS
コンテナで作れるFaaSコンテナで作れるFaaS
コンテナで作れるFaaS真吾 吉田
 
System3 ajax
System3 ajaxSystem3 ajax
System3 ajaxJun Chiba
 

Similar to 【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方 (20)

MT meets PHP - PHP conference Kansai 2013
MT meets PHP - PHP conference Kansai 2013MT meets PHP - PHP conference Kansai 2013
MT meets PHP - PHP conference Kansai 2013
 
MT meets PHP
MT meets PHPMT meets PHP
MT meets PHP
 
Zend Frameworkで始める携帯サイト
Zend Frameworkで始める携帯サイトZend Frameworkで始める携帯サイト
Zend Frameworkで始める携帯サイト
 
Phpcon tokyo 20120_bigginer
Phpcon tokyo 20120_bigginerPhpcon tokyo 20120_bigginer
Phpcon tokyo 20120_bigginer
 
開発エンジニアがChefで テスト駆動サーバー設定してみた #biglobetechtalk
開発エンジニアがChefで テスト駆動サーバー設定してみた #biglobetechtalk開発エンジニアがChefで テスト駆動サーバー設定してみた #biglobetechtalk
開発エンジニアがChefで テスト駆動サーバー設定してみた #biglobetechtalk
 
Struts2を始めよう!
Struts2を始めよう!Struts2を始めよう!
Struts2を始めよう!
 
phpMyAdminにおけるスクリプト実行可能な脆弱性3種盛り合わせ
phpMyAdminにおけるスクリプト実行可能な脆弱性3種盛り合わせphpMyAdminにおけるスクリプト実行可能な脆弱性3種盛り合わせ
phpMyAdminにおけるスクリプト実行可能な脆弱性3種盛り合わせ
 
DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~
DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~
DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~
 
MySQL Technology Cafe #12 MDS HA検証 ~パラメータからパフォーマンスまで~
MySQL Technology Cafe #12 MDS HA検証 ~パラメータからパフォーマンスまで~MySQL Technology Cafe #12 MDS HA検証 ~パラメータからパフォーマンスまで~
MySQL Technology Cafe #12 MDS HA検証 ~パラメータからパフォーマンスまで~
 
15分でCakePHPを始める方法(Nseg 2013-11-09 )
15分でCakePHPを始める方法(Nseg 2013-11-09 )15分でCakePHPを始める方法(Nseg 2013-11-09 )
15分でCakePHPを始める方法(Nseg 2013-11-09 )
 
July Tech Festa 2014発表資料
July Tech Festa 2014発表資料July Tech Festa 2014発表資料
July Tech Festa 2014発表資料
 
Hack/HHVM 入門
Hack/HHVM 入門Hack/HHVM 入門
Hack/HHVM 入門
 
Nashorn in the future (Japanese)
Nashorn in the future (Japanese)Nashorn in the future (Japanese)
Nashorn in the future (Japanese)
 
関西Php勉強会のlimeの話
関西Php勉強会のlimeの話関西Php勉強会のlimeの話
関西Php勉強会のlimeの話
 
「さくらのクラウド」スタートアップスクリプトを作ってみよう! - concrete5を題材に -(オープンソースカンファレンス2014 Shimane)
「さくらのクラウド」スタートアップスクリプトを作ってみよう! - concrete5を題材に -(オープンソースカンファレンス2014 Shimane)「さくらのクラウド」スタートアップスクリプトを作ってみよう! - concrete5を題材に -(オープンソースカンファレンス2014 Shimane)
「さくらのクラウド」スタートアップスクリプトを作ってみよう! - concrete5を題材に -(オープンソースカンファレンス2014 Shimane)
 
Jyoken 講習20150513
Jyoken 講習20150513Jyoken 講習20150513
Jyoken 講習20150513
 
Webサーバのチューニング
WebサーバのチューニングWebサーバのチューニング
Webサーバのチューニング
 
System4 comment
System4 commentSystem4 comment
System4 comment
 
コンテナで作れるFaaS
コンテナで作れるFaaSコンテナで作れるFaaS
コンテナで作れるFaaS
 
System3 ajax
System3 ajaxSystem3 ajax
System3 ajax
 

More from kwatch

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Pythonkwatch
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
なんでもID
なんでもIDなんでもID
なんでもIDkwatch
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方kwatch
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?kwatch
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)kwatch
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するkwatch
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策kwatch
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門kwatch
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurialkwatch
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -kwatch
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみたkwatch
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"kwatch
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラムkwatch
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンkwatch
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapperkwatch
 

More from kwatch (20)

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Python
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
なんでもID
なんでもIDなんでもID
なんでもID
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較する
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurial
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジン
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapper
 

Recently uploaded

TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 

Recently uploaded (8)

TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 

【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方

  • 2. copyright 2015 kuwata-lab.com all rights reserved.© 本発表の作成には徳丸先生は関わって
 おりません。 内容の責任はすべて発表者にあるので、 ご意見がありましたら先生にではなく 発表者までお願いします。 !! CAUTION !!
  • 3. copyright 2015 kuwata-lab.com all rights reserved.© 発表の背景:裁判と損害賠償 引用: http://blog.tokumaru.org/2015/01/sql.html SQLインジェクション脆弱性が原因でクレジット カード情報が漏洩した事件につき、ショップ側が
 開発会社を相手取り損害賠償請求の裁判を起こし、 ショップ側が勝訴 結果、3131万9568円の損害を認定し、その3割を
 控除して、2262万3697円の損害賠償をY社に
 命じた
  • 4. copyright 2015 kuwata-lab.com all rights reserved.© 発表の背景:ばく大な金額 引用: http://www.ipa.go.jp/files/000013778.pdf (SQLiによる推計される被害額について) 推計すると、約 4,800 万円∼1 億円程度を要する ものと考えられる。
  • 5. copyright 2015 kuwata-lab.com all rights reserved.© 発表の目的 SQL Injection が起きる真の原因を考える 「プレースホルダを使ってないから」では考察不足 SQL Injection を起こさない方法を考える 「プレースホルダを使え」では対策不足
  • 6. copyright 2015 kuwata-lab.com all rights reserved.© アジェンダ 考察:なぜSQL Injectionが発生するのか? 対策:SQLテンプレート 対策:SQL構文木 まとめ
  • 7. copyright 2015 kuwata-lab.com all rights reserved.© 前提知識 SQL Injection が何か、知ってること (以降では SQL Injection を SQLi と省略) プレースホルダやバインド変数について
 知ってること 「:id」や「?」がプレースホルダ、渡す値がバインド変数 PHPのコードが読めること PHPカンファレンスなので :)
  • 9. copyright 2015 kuwata-lab.com all rights reserved.© SQL Injection 対策 エスケープしろ!プレースホルダを使え! http://www.ipa.go.jp/files/000017320.pdf
  • 10. copyright 2015 kuwata-lab.com all rights reserved.© なぜSQL Injectionが発生するのか? プレースホルダを使ってないから?
  • 11. copyright 2015 kuwata-lab.com all rights reserved.© プレースホルダを使っててもSQLi $sql = "select * from users" . " where deleted_at is null"; $vars = []; if ($max_age) { $sql .= " and age <= :max_age"; $vars['max_age'] = $max_age; } if ($min_age) { $sql .= " and age >= ".$min_age; $vars['min_age'] = $min_age; } プレースホルダを 使っている ただの文字列 連結! SQLi!
  • 12. copyright 2015 kuwata-lab.com all rights reserved.© なぜSQL Injectionが発生するのか? プレースホルダを使ってないから? 実情は、プレースホルダつきの安全なSQLを組み立てて
 いる最中に SQL Injection が入り込んでいる   これこそが真の原因 文字列連結でSQLを組み立ててるから
  • 13. copyright 2015 kuwata-lab.com all rights reserved.© 変数の埋め込みも文字列連結と同じ // これと $sql .= " and age >= ".$min_age; // これは同じ $sql .= " and age >= $min_age"; 変数の埋め込みも 文字列連結と同じ
  • 14. copyright 2015 kuwata-lab.com all rights reserved.© なぜ文字列結合でSQLを作るのか? プレースホルダではできないことがあるから 要素数が動的に変わる in (....) 、order by でのカラム名指定   真の原因その2 // SQLを文字列で渡せてしまえるんだから、 // SQLを文字列結合で組み立ててしまうのは当然のこと $st = pdo->prepare("select * from users"); SQLを文字列で指定できてしまうから
  • 15. copyright 2015 kuwata-lab.com all rights reserved.© SQL Injection を防ぐには? 文字列連結ではない方法で動的SQLを
 組み立てればよい 方法:SQLテンプレート or SQL構文木 (詳細は後述) SQL文字列ではない方法でSQLを
 指定できるようにすればよい 方法:SQL ID or SQL構文木 (詳細は後述)
  • 16. copyright 2015 kuwata-lab.com all rights reserved.© SQL Injection が発生する本当の原因は、 ライブラリや API のインターフェースに 欠陥があるからである。 間違いを誘発するものを使い続ける限り、 SQL Injection がなくなることはない。 Let's Tweet!
  • 17. copyright 2015 kuwata-lab.com all rights reserved.© ここまでのまとめ SQLを文字列連結で組み立てるから、
 SQL Injection が発生する 対策:文字列連結ではない方法でSQLを組み立てる 生のSQLを文字列で渡せてしまうから、
 文字列連結を使ってしまう 対策:生のSQLを渡すかわりに別の方法でSQLを指定する 本質的にはAPIやインターフェースの欠陥 結果はセキュリティ被害だけど、原因はセキュリティとは違う
  • 19. copyright 2015 kuwata-lab.com all rights reserved.© SQLテンプレートとは? SQLを生成するためのテンプレート WebアプリでのHTMLテンプレートと同じ SQL Injection が発生しない(原理上は) 文字列連結が不可、値のエスケープ or プレースホルダを強制 注:内部の実装では文字列連結を使うが、開発者が明示的に使うことはできない。
  • 20. copyright 2015 kuwata-lab.com all rights reserved.© サンプル:SQLテンプレート /* 年齢の上限/下限が指定されたら、検索条件を追加 */ select * from users where deleted_at is null -- #if :max_age and age <= :max_age -- #end -- #if :min_age and age >= :min_age -- #end
  • 21. copyright 2015 kuwata-lab.com all rights reserved.© サンプル:PHPコードへ変換 /* 年齢の上限/下限が指定されたら、検索条件を追加 */ select * from users where deleted_at is null <?php if ($vars['max_age']) { ?> and age <= :max_age <?php } ?> <?php if ($vars['min_age']) { ?> and age >= :min_age <?php } ?> 注:実際はもう少し複雑なコードに変換される
  • 22. copyright 2015 kuwata-lab.com all rights reserved.© サンプル:生成されたSQL // $var = array("min_age"=>20) なら select * from users where deleted_at is null and age >= :min_age
  • 23. copyright 2015 kuwata-lab.com all rights reserved.© SQLTempl8 SQLを対象としたテンプレートエンジン https://github.com/kwatch/sqltempl8/ まだコンセプト実装 (いろいろ足りない) 使い方は随時変わるので、最新のドキュメントを参照のこと
  • 24. copyright 2015 kuwata-lab.com all rights reserved.© SQLTempl8:SQLを生成 1: <?php 2: require_once 'sqltempl8.php'; 3: $t = new SQLTempl8("sql/users.sql"); 4: $vars = array('min_age'=>20); 5: $sql = $t->render($vars); 6: echo $sql; //=> select * from users // where deleted_at is null // and age >= :min_age
  • 25. copyright 2015 kuwata-lab.com all rights reserved.© SQLTempl8:SQLを実行 1: <?php 2: require_once 'sqltempl8.php'; 3: $t = new SQLTempl8("sql/users.sql"); 4: $vars = array('min_age'=>20); 5: $pdo_conn = new PDO("....."); 6: $pdo_stmt = $t->execute($pdo_conn, $vars); 7: if ($pdo_stmt !== null) { 8: foreach ($pdo_stmt as $row) { ... } 9: }
  • 26. copyright 2015 kuwata-lab.com all rights reserved.© なぜSQL Injectionが発生しないの? // SQLテンプレート select * from users where deleted_at is null -- #if :max_age and age <= :max_age -- #end -- #if :min_age and age >= :min_age -- #end 文字列連結が書けない (文法が極めて限定的) 変数値が埋め込めない (プレースホルダを強制)
  • 27. copyright 2015 kuwata-lab.com all rights reserved.© なぜSQL Injectionが発生しないの? // メインプログラム <?php require_once 'sqltempl8.php'; $t = new SQLTempl8("sql/users.sql"); $vars = array('min_age'=>20); $pdo_conn = new PDO("....."); $pdo_stmt = $t->execute($pdo_conn, $vars); if ($pdo_stmt !== null) { foreach ($pdo_stmt as $row) { ... } } SQL IDとしてテンプレートの ファイル名を指定 (生のSQLを指定しない)
  • 28. copyright 2015 kuwata-lab.com all rights reserved.© Q:PHPコードが埋め込めるのでは? セキュリティ上の大きな穴になりそう… // SQL template select <?= $_GET['param'] ?> from users where true -- % if :max_age and age <= :max_age -- % end -- % if :min_age and age >= :min_age -- % end
  • 29. copyright 2015 kuwata-lab.com all rights reserved.© A:'<?' をエスケープします ちゃんとSQL Syntax Errorになってくれます // PHP code select <<?php ?>?= $_GET['param'] ?> from users where true <?php if ($var['max_age']) { ?> and age <= :max_age <?php } ?> <?php if ($var['min_age']) { ?> and age >= :min_age <?php } ?>
  • 30. copyright 2015 kuwata-lab.com all rights reserved.© Q:'=' と 'is null' との切り替えは? 値が null なら '=' を 'is null' にしてほしい select * from users where deleted_on = :deleted // これ↓は面倒なのでいやだ select * from users -- #if :deleted where deleted_on = :deleted -- #else where deleted_on is null -- #end $vars['deleted'] がnullなら
 '=' を 'is null' に自動的に変更 してほしい
  • 31. copyright 2015 kuwata-lab.com all rights reserved.© A:MySQLの '<=>' 演算子を使おう ポスグレなら 'is not distinct from' 演算子 select * from users where deleted_on <=> :deleted 値が null なら deleted_on is null と同じ、 それ以外なら deleted_on = :deleted と同じ 注:本当なら、SQL構文を解析して '=' 演算子を置換することが望ましい。
  • 32. copyright 2015 kuwata-lab.com all rights reserved.© Q:where句の追加が面倒では? 例:上下限値があるときだけwhere句を追加 select * from users -- #if :max_age or :min_age where true -- #if :max_age and age <= :max_age -- #end -- #if :min_age and age >= :min_age -- #end -- #end この条件分岐が面倒!!
  • 33. copyright 2015 kuwata-lab.com all rights reserved.© A:DBの最適化機能に任せよう 「where true」が残っても性能に影響はない select * from users -- #if :max_age or :min_age where true -- #if :max_age and age <= :max_age -- #end -- #if :min_age and age >= :min_age -- #end -- #end 余分な 'where true' は DBのOptimizerが
 取り除いてくれる (実行計画を見れば確認可能)
  • 34. copyright 2015 kuwata-lab.com all rights reserved.© Q:やっぱり埋め込み式が欲しい! placeholderでは表名やカラム名が指定できない select * from blog_entries_<?= $user ?> where deleted_at is null order by <?= $sortkey ?> from :table とはできない order by :sortkey とはできない
  • 35. copyright 2015 kuwata-lab.com all rights reserved.© A:制限つき埋め込み式を用意しました 値として、英数字と '_' と '.' だけを許可 // SQL template select * from blog_entries order by [=:sortkey=] // PHP code select * from blog_entries order by <?php if (! preg_match('/^w+(.w+)*$/', $vars['sortkey']) throw new SQLTemplateError("error"); echo $vars['sortkey']; ?> テーブル名やカラム名で なければ例外を発生
  • 36. copyright 2015 kuwata-lab.com all rights reserved.© 課題 xxx in (...) のサポートがまだ プレースホルダではうまく扱うのが難しく、仕様を考え中
 (できるならPDOのエスケープ機能 quote() を拡張したい) foreach文の導入がまだ これもプレースホルダでは扱いが難しいが、いわゆる
 バルクインサートでは必須なので実装したい PDOは全部文字列として扱ってしまう! バインド変数にデータ型を指定するよう変更予定
  • 37. copyright 2015 kuwata-lab.com all rights reserved.© ここまでのまとめ SQLテンプレートならSQLiが発生しない 文字列結合が書けない
 プレースホルダやエスケープを強制
 生SQLを指定できない
  • 39. copyright 2015 kuwata-lab.com all rights reserved.© SQL構文木とは? SQLを木構造で表したデータ select * where = id 123 from books
  • 40. copyright 2015 kuwata-lab.com all rights reserved.© SQL構文木の組み立て方 通常は専用のライブラリを使うか、… $q = new Query(); $q->select('*') ->from('books') ->where('id', '=', 123); $book = $q->query();
  • 41. copyright 2015 kuwata-lab.com all rights reserved.© SQL構文木の組み立て方 O/R Mapperを使う class Book extends Entity { ... }; class Books extends Schema { ... }; $q = new Query(Books); $q->where(Books::id->eq(123)); $book = $q->select('*');
  • 42. copyright 2015 kuwata-lab.com all rights reserved.© SQL構文木の組み立て方 演算子オーバーライドが使えると自然な記述に // Ruby book = Book.where(:id == 123).first() // Python book = db.query(Book) .filter(Book.id == 123) .first() true/falseではなく 部分構文木を返す 参考:「演算子オーバーライドをDSLに活用する」でggr
  • 43. copyright 2015 kuwata-lab.com all rights reserved.© 構文木 → SQL文字列 '=' と 'is null' も、値に応じて自動的に変換 where == id 123 where == id null where id = 123 where id is null
  • 44. copyright 2015 kuwata-lab.com all rights reserved.© なぜSQL Injectionを防げるの? 文字列結合後にSQLをパースするからSQLiが発生 $id = $_GET['id']; $sql = "select * from books where id = '$id'"; // もし $id が "' or 1<>'" なら…⋯ select * from books where id = '' or 1<>'' 意図しない構造に 変わってしまった!
  • 45. copyright 2015 kuwata-lab.com all rights reserved.© なぜSQL Injectionを防げるの? SQL構文木なら意図しない変更ができない where = id ' or 1 <>' $q->where( Books::id, '=', $_GET['id'] ); 悪意ある値を 受けとっても… 木構造は影響を 受けない
  • 46. copyright 2015 kuwata-lab.com all rights reserved.© 本当は構文木のままDBに送信したい SQL文字列は直列化形式として本当に妥当なのか? where = id 123 送信 (注)直列化:構造のあるデータをバイト列に変換すること。
 データを送信したりファイルに保存するときに必要。 データベース 変換 select ... from ... where ... and ... もっと改ざんされにくい 形式でもいいのでは? SQL文字列構文木
  • 47. copyright 2015 kuwata-lab.com all rights reserved.© 注意!それは木構造ではない! // 一見、木構造を作ってるように見えるが…⋯ $q->where('id = ?', $_GET['id']); // 実はそうではない $q->where($_GET['col'].' = ?', $_GET['id']); SQLを文字列で指定できて しまうのでアウト
  • 48. copyright 2015 kuwata-lab.com all rights reserved.© 課題 動作速度は遅い 木構造の構築も、SQLへの変換も、動作コストが大きい 昨今のCPUパワーをもっと 安全性のために使ってほしい
  • 49. copyright 2015 kuwata-lab.com all rights reserved.© ここまでのまとめ SQL構文木を作るとSQLiが発生しない 悪意ある文字列を渡されてもSQL構造が変更されない
  • 51. copyright 2015 kuwata-lab.com all rights reserved.© まとめ 動的SQLを作るのに文字列結合を避ける かわりにSQLテンプレートやSQL構文木を使う 本質的にはAPIやインターフェースの欠陥 生のSQLを文字列で渡せてしまう
 → だからSQLを文字列で組み立ててしまう
 → だからSQL Injectionがなくならない
  • 52. copyright 2015 kuwata-lab.com all rights reserved.© 補足 型はSQLiの防止に役立つか? Yes。型はValidationに役立つ、そしてバインド変数の ValidationはSQLi防止に有効、なので型はSQLi防止に役立つ 型安全であればSQLiは防げるか? No。型安全でも文字列連結はできる、そして文字列連結を使 うとSQLiが起こり得る、なので型安全でもSQLiが起こり得る 参考:https://twitter.com/ockeghem/status/650171306428596224 https://twitter.com/tanakh/status/650214648382291968
 https://twitter.com/tanakh/status/650215363943116800 型安全だけではSQLiは防げない、 もう一工夫必要
  • 53. copyright 2015 kuwata-lab.com all rights reserved.© 参考資料 (SQLテンプレート) SQLTempl8 https://github.com/kwatch/sqltempl8 Doma - SQLテンプレートの仕組み http://www.slideshare.net/taedium/doma-sql DBFlute入門 - 外だしSQLの基本 http://gihyo.jp/dev/feature/01/dbflute/0005 S2JDBC - SQLファイル http://s2container.seasar.org/2.4/ja/s2jdbc_manager_sqlfile.html
  • 54. copyright 2015 kuwata-lab.com all rights reserved.© 参考資料 (SQL構文木) 演算子オーバーライドをDSLに活用する http://j.mp/slide_opdsl O/R Mapperによるトラブルを未然に防ぐ http://j.mp/slide_orm2 O/Rマッパーを支える技術 http://j.mp/slide_orm1
  • 55. copyright 2015 kuwata-lab.com all rights reserved.© お客さまにおすすめの新刊があります 徳丸浩のWebセキュリティ教室 2015-10-22 発売予定 日経BP社 1944円 Let's Tweet! 絶賛予約受付中!
  • 57. copyright 2015 kuwata-lab.com all rights reserved.© 私的反省会 今回の内容は、HTMLテンプレートでは
 すでに知られていたことばかり 自動エスケープ機能や、木構造が安全なことなど それをSQLへ応用するのが遅れたせいで
 不幸な判決を生み出してしまった HTMLテンプレートエンジン作者の一人としてお詫びします
 ごめんなさい
  • 58. copyright 2015 kuwata-lab.com all rights reserved.© おしまい