SlideShare una empresa de Scribd logo
1 de 36
Copyright©2013 JPCERT/CC All rights reserved.
「Javaアプリケーション脆弱性事例調査資料」について
この資料は、Javaプログラマである皆様に、脆弱性を身
近な問題として感じてもらい、セキュアコーディングの
重要性を認識していただくことを目指して作成していま
す。
「Javaセキュアコーディングスタンダード
CERT/Oracle版」と合わせて、セキュアコーディングに
関する理解を深めるためにご利用ください。
JPCERTコーディネーションセンター
セキュアコーディングプロジェクト
secure-coding@jpcert.or.jp
1
Japan Computer Emergency Response Team
Coordination Center
電子署名者 : Japan Computer Emergency Response Team Coordination Center
DN : c=JP, st=Tokyo, l=Chiyoda-ku, email=office@jpcert.or.jp, o=Japan
Computer Emergency Response Team Coordination Center, cn=Japan
Computer Emergency Response Team Coordination Center
日付 : 2013.06.26 11:01:16 +09'00'
MySQL Connector/J における
SQL インジェクションの脆弱性
JVN#59748723
JVNDB-2009-000050
2
Copyright©2013 JPCERT/CC All rights reserved.
MySQL Connectorとは
MySQLデータベースにアクセスするための Java アプリ
ケーション用ドライバソフトウェア
MySQLを利用するJavaアプリケーションを簡単に作成
できる
3
MySQL Connector
Copyright©2013 JPCERT/CC All rights reserved.
脆弱性の概要
MySQL Connector/J にはSQLクエリ文字列の処
理に不備があり、SQLインジェクションが可能
となる脆弱性が存在する。
Javaアプリケーションがプリペアードステート
メント等の適切な処理を実装している場合でも
SQLインジェクションが可能。
4
Copyright©2013 JPCERT/CC All rights reserved.
SQLインジェクションとは
入力値を元にSQL文を動的に生成しているアプリケーションに
対し、細工した入力を与えることで(アプリケーションの意図
しないような) 任意のSQL文を挿入/実行すること。
5
① SQL文を含む不正なリクエストの送信
‘ or ‘a’=‘a
データベース上のデータの漏えいや改ざん、
破壊などの被害を受ける可能性がある。
Copyright©2013 JPCERT/CC All rights reserved.
プリペアードステートメントとは
事前に定義したSQL文のプレースホルダ(予約場
所)に入力データを割り当てる機能。
プリペアドステートメントを利用すると、入力
データは数値定数や文字列定数として組み込ま
れ、文字列として扱われることになる。
一般的にSQLインジェクション対策として使用
される。
6
Copyright©2013 JPCERT/CC All rights reserved.
プリペアードステートメントとは: サンプルコード
7
1: Connection conn = DriverManager.getConnection(
"jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password");
2: String input = request.getParameter("name");
3: String sql = "SELECT * FROM user WHERE name=?";
4: PreparedStatement ps = conn.prepareStatement(sql);
5: ps.setString(1, input); // 1は1番目のプレースホルダを表す
6: ResultSet resultSet = ps.executeQuery();
 1行目:データベースと接続する
 2行目:リクエスト中のパラメータnameの値を取得して変数inputに格納する
 3行目:「?」文字がプレースホルダ
 4行目:SQL文のプリコンパイルを行う。
 5行目:プレースホルダと変数の関連付けを行う。この例では、1番目のプレースホル
ダに変数inputを設定する。
 6行目:SQL文を実行し結果を得る。
解説
Copyright©2013 JPCERT/CC All rights reserved.
MySQL Connector の処理内容
8
1: Connection conn = DriverManager.getConnection(
"jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password");
2: String input = request.getParameter("name");
3: String sql = "SELECT * FROM user WHERE name=?";
4: PreparedStatement ps = conn.prepareStatement(sql);
5: ps.setString(1, input);
6: ResultSet resultSet = ps.executeQuery();
前述のサンプルコードを使用して処理を解説する。
MySQL Connector側で処理が行われる箇所
•com.mysql.jdbc.Connectionクラス
•com.mysql.jdbc.PreparedStatementクラス
Copyright©2013 JPCERT/CC All rights reserved.9
1: Connection conn = DriverManager.getConnection(
"jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password");
2: String input = request.getParameter("name");
3: String sql = "SELECT * FROM user WHERE name=?";
4: PreparedStatement ps = conn.prepareStatement(sql);
5: ps.setString(1, input);
6: ResultSet resultSet = ps.executeQuery();
サンプルコードが実行された場合のMy SQL Connecter側の処理フロー
① 1行目でデータベースに接続する。
② 5行目のPreparedStatement::setStringメソッド内で第2引数inputの文字
列のエスケープが実行される。
③ 同じくPreparedStatement:: setStringメソッド内で文字列がByte列に変
換され、プレースホルダに値が設定される。
④ 6行目でSQLクエリが実行される。
Point!!
MySQL Connector の処理内容
Copyright©2013 JPCERT/CC All rights reserved.10
1: Connection conn = DriverManager.getConnection(
"jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password");
2: String input = request.getParameter("name");
3: String sql = "SELECT * FROM user WHERE name=?";
4: PreparedStatement ps = conn.prepareStatement(sql);
5: ps.setString(1, input);
6: ResultSet resultSet = ps.executeQuery();
MySQL Connector の処理
①データベースへの接続
データベースに接続する。パラメータcharacterEncoding で
アプリケーションで使用する文字エンコーディングを指定する。
Copyright©2013 JPCERT/CC All rights reserved.11
1: Connection conn = DriverManager.getConnection(
"jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password");
2: String input = request.getParameter("name");
3: String sql = "SELECT * FROM user WHERE name=?";
4: PreparedStatement ps = conn.prepareStatement(sql);
5: ps.setString(1, input);
6: ResultSet resultSet = ps.executeQuery();
MySQL Connector の処理
②PreparedStatement::setStringで第2引数のエスケープ
変数inputをリクエストから受け取り、
PreparedStatement::setString メソッドの
第2引数として渡す。
Copyright©2013 JPCERT/CC All rights reserved.12
public class PreparedStatement extends ・・・・・・・ {
public void setString(int parameterIndex, String x) throws SQLException {
:
StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));
for (int i = 0; i < stringLength; ++i) {
char c = x.charAt(i);
switch (c) {
case 0: /* Must be escaped for 'mysql' */
buf.append('¥¥');
buf.append('0');
break;
:
case '¥¥':
:
case '¥'':
:
default:
buf.append(c);
}
setStringメソッドの第2引数
のxがプレースホルダにセッ
トされる文字列。
Xから1文字ずつ取り出して、
特殊文字に対してエスケー
プ処理を行う。
MySQL Connector の処理
②PreparedStatement::setStringで第2引数のエスケープ
Copyright©2013 JPCERT/CC All rights reserved.
エスケープ処理のまとめ
13
入力文字列 エスケープ処理後の文字列
NULL ¥0
¥n ¥n
¥r ¥r
¥ (スラッシュ) ¥¥
‘ (シングルクオート) ¥’
“ (ダブルクオート) ¥”
¥032 ¥Z
上記以外 特に処理なし
setStringメソッドに渡される値が「’ or 1=1」の場合は
上記のエスケープ処理によって「 ¥’ or 1=1 」となる。
MySQL Connector の処理
②PreparedStatement::setStringで第2引数のエスケープ
Copyright©2013 JPCERT/CC All rights reserved.
MySQL Connector の処理
③PreparedStatement::setStringでByte列への変換
14
public class PreparedStatement extends com.mysql.jdbc.StatementImpl
implements java.sql.PreparedStatement {
public void setString(int parameterIndex, String x) throws SQLException {
:
parameterAsString = buf.toString();
byte[] parameterAsBytes = null;
parameterAsBytes = StringUtils.getBytes(parameterAsString,
this.charConverter, this.charEncoding, this.connection
.getServerCharacterEncoding(), this.connection
.parserKnowsUnicode());
:
setInternal(parameterIndex, parameterAsBytes);
エスケープ処理後の文字列が
String型変数parameterAsString
に保存される。
StringUtils::parameterAsStringメソッドで文字列をByte列に変換する。
その際に指定されるcharEncodingは接続時に指定した文字コード
(Windows-31J)が設定される。
Windows-31J
Copyright©2013 JPCERT/CC All rights reserved.15
■StringUtils.getBytesメソッドによるByte列への変換
StringUtils.getBytesメソッドでは内部的にString.getBytesメソッドが呼び出
されている。
¥ ’ space o r space 1 = 1
public static final byte[] getBytes(String s,
SingleByteCharsetConverter converter, String encoding,
String serverEncoding, boolean parserKnowsUnicode)
throws SQLException {
:
b = s.getBytes(encoding);
:
return b;
StringUtils.java
■変換対象の文字列(第1引数s)が「 ¥’ or 1=1 」の場合
⇒ [92,39, 32, 111,114, 32, 49,61,49] というByte列に変換される。
Windows-31J
setStringメソッドの
第2引数
MySQL Connector の処理
③PreparedStatement::setStringでByte列への変換
Copyright©2013 JPCERT/CC All rights reserved.16
public class PreparedStatement extends com.mysql.jdbc.StatementImpl
implements java.sql.PreparedStatement {
public void setString(int parameterIndex, String x) throws SQLException {
:
parameterAsString = buf.toString();
byte[] parameterAsBytes = null;
parameterAsBytes = StringUtils.getBytes(parameterAsString,
this.charConverter, this.charEncoding, this.connection
.getServerCharacterEncoding(), this.connection
.parserKnowsUnicode());
:
setInternal(parameterIndex, parameterAsBytes);
com.mysql.jdbc.PreparedStatement.setInternal メソッドで、
先ほど変換したByte列をプリペアードステートメントにセットする。
MySQL Connector の処理
③PreparedStatement::setStringでByte列への変換
Copyright©2013 JPCERT/CC All rights reserved.
MySQL Connector の処理
④SQLクエリの実行
17
SQLが実行される。結果として実行されるSQLは・・・
■変数inputが「test」の場合
実行されるSQLは
「 SELECT * FROM user WHERE name=‘test’」
となる。
■変数inputが「’ or 1=1」の場合
実行されるSQLは
「 SELECT * FROM user WHERE name=‘¥’ or 1=1’」
となり、変数inputに含まれるシングルクオートがエスケープ
される。
Copyright©2013 JPCERT/CC All rights reserved.
MySQL Connector の処理のまとめ
18
¥ ’ space o r space 1 = 1
SELECT * FROM user WHERE name=‘ ? ‘
[92,39,32,111,114, 32, 49,61,49]
¥ ’ space o r space 1 = 1
SELECT * FROM user WHERE name=‘¥’ or 1=1’
‘ or 1=1 ¥‘ or 1=1 [92,39,・・・]¥‘ or 1=1
プレースホルダへのセット
「’ or 1=1」 → 「¥’ or 1=1」
③PreparedStatement:: setStringメソッド内で文字列をByte列に変換
「 ¥’ or 1=1 」 → [92,39,32,111,114,32,49,61,49]
①データベースへの接続
②PreparedStatement::setStringメソッド内で引数の文字列のエスケープ
データベース
エスケープ
処理
データベース
① ② ③ ④
④SQLの実行
String Byte[]
Select * from user …
getBytes()
Copyright©2013 JPCERT/CC All rights reserved.
攻撃コード
19
1: Connection conn = DriverManager.getConnection(
"jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password");
2: String sql = "SELECT * FROM user WHERE name=?";
3: PreparedStatement ps = conn.prepareStatement(sql);
4: ps.setString(1, "¥u00a5' or 1 = 1#");
5: ResultSet resultSet = ps.executeQuery();
■攻撃コードのポイント
• 4行目のsetStringメソッドの引数(プレースホルダに入れる値)に
UNICODEで‘¥’ (YEN SIGN) に該当するU+00A5を挿入し、その
後に「’ or 1=1#」という値を渡している。
• 1行目のデータベース接続時の文字エンコーディングとして
「Windows-31J」を指定しており、異なる文字エンコーディン
グを使用した文字列が含まれていることになる。
Copyright©2013 JPCERT/CC All rights reserved.
攻撃コード
20
サンプルコードが実行された場合のMy SQL Connecter側の処理フロー
① 1行目でデータベースに接続する。
② 5行目のPreparedStatement::setStringメソッド内で第2引数inputの文字
列のエスケープが実行される。
③ 同じくPreparedStatement::setStringメソッド内でgetBytesメソッドに
より文字列がByte列に変換され、プレースホルダに値が設定される。
④ 6行目でSQLクエリが実行される。
②と③で脆弱性の原因となる処理が実行される
Copyright©2013 JPCERT/CC All rights reserved.
攻撃コードが実行された際の処理
②PreparedStatement::setStringで第2引数のエスケープ
21
public class PreparedStatement extends ・・・・・・・ {
public void setString(int parameterIndex, String x) throws SQLException {
:
StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));
for (int i = 0; i < stringLength; ++i) {
char c = x.charAt(i);
switch (c) {
case 0: /* Must be escaped for 'mysql' */
buf.append('¥¥');
buf.append('0');
break;
:
case '¥¥':
:
:
default:
buf.append(c);
}
setStringメソッドの第2引数
のxがプレースホルダにセッ
トされる。
Xから1文字ずつ取り出して、
特殊文字に対してエスケー
プ処理を行う。
しかし、 UNICODEの’¥’である¥u00a5はエスケープされない。
そのため、エスケープ処理の結果は
「¥’ or 1 = 1#」→ 「¥¥’ or 1 = 1#」
となる!!
¥’ or 1 = 1#
※¥はUNICODEの’¥’である¥u00a5
※¥はUNICODEの’¥’である¥u00a5
Copyright©2013 JPCERT/CC All rights reserved.
攻撃コードが実行された際の処理
③PreparedStatement::setStringでgetBytesメソッドによるByte列への変換
22
public class PreparedStatement extends com.mysql.jdbc.StatementImpl
implements
java.sql.PreparedStatement {
public void setString(int parameterIndex, String x) throws SQLException {
:
parameterAsString = buf.toString();
byte[] parameterAsBytes = null;
parameterAsBytes = StringUtils.getBytes(parameterAsString,
this.charConverter, this.charEncoding, this.connection
.getServerCharacterEncoding(), this.connection
.parserKnowsUnicode());
:
setInternal(parameterIndex, parameterAsBytes);
エスケープ処理後の文字列がString型
変数parameterAsStringに保存される。
StringUtils::parameterAsStringメソッドで文字列をByte列に変換する。
その際に指定されるcharEncodingは接続時に指定したエンコーディング
(Windows-31J)が設定される。
¥¥’ or 1 = 1#
※¥はUNICODEの’¥’である¥u00a5
Windows-31J
Copyright©2013 JPCERT/CC All rights reserved.23
public static final byte[] getBytes(String s,
SingleByteCharsetConverter converter, String encoding,
String serverEncoding, boolean parserKnowsUnicode)
throws SQLException {
:
b = s.getBytes(encoding);
:
return b;
StringUtils.java
■攻撃コードが実行された場合
getBytesメソッドでU+00A5はShift JISの’¥’として変換されてしまう!!
Windows-31J
¥¥’ or 1 = 1#
※¥はUNICODEの’¥’である¥u00a5
「¥¥’ or 1 = 1#」→ [92,92,39, 32,111,114, 32,49,61,49,35]
本来のバイト列は[165,92,39,32,111,114,32,49,61,49,35]
※¥はUNICODEの’¥’である¥u00a5
¥ ¥ ’ space o r space 1 = 1 #
攻撃コードが実行された際の処理
③PreparedStatement::setStringでgetBytesメソッドによるByte列への変換
■StringUtils.getBytesメソッドによるByte列への変換
StringUtils.getBytesの内部ではString.getBytesメソッドを使っている。
Copyright©2013 JPCERT/CC All rights reserved.24
public class PreparedStatement extends com.mysql.jdbc.StatementImpl
implements java.sql.PreparedStatement {
public void setString(int parameterIndex, String x) throws SQLException {
:
parameterAsString = buf.toString();
byte[] parameterAsBytes = null;
parameterAsBytes = StringUtils.getBytes(parameterAsString,
this.charConverter, this.charEncoding, this.connection
.getServerCharacterEncoding(), this.connection
.parserKnowsUnicode());
:
setInternal(parameterIndex, parameterAsBytes);
com.mysql.jdbc.PreparedStatement.setInternalメソッドで、
先ほど変換したByte列をプリペアードステートメントにセットする。
[92,92,39, 32,111,114,32,49,61,49,35]
¥ ¥ ’ space o r space 1 = 1 #
攻撃コードが実行された際の処理
③PreparedStatement::setStringでgetBytesメソッドによるByte列への変換
Copyright©2013 JPCERT/CC All rights reserved.
攻撃コードが実行された際の処理
25
SELECT * FROM user WHERE name=‘ ? ‘
[92,92,39,32,111,114,32,49,61,49,35]
SELECT * FROM user WHERE name=‘¥¥’ or 1=1#’
¥ ¥ ’ space o r space 1 = 1 #
SQL文のWhere句は、
「nameが¥(バックスラッシュ)と等しい、あるいは、1が1と等しい」
という条件になり、本来実行されるべきクエリから内容が変更されてし
まった!! (#はMySQLでのコメント文字であり、これ以降は無視される.)
■プレースホルダへのセット
変換されたByte列がプレースホルダにセットされる。
Copyright©2013 JPCERT/CC All rights reserved.
攻撃コードが実行された際の処理
26
¥ ¥ ’ space o r space 1 = 1
SELECT * FROM user WHERE name=‘ ? ‘
SELECT * FROM user WHERE name=‘¥¥’ or 1=1#’
¥‘ or 1=1 ¥¥‘ or 1=1 [92,92,39,・・・]¥¥‘ or 1=1
プレースホルダへのセット
「¥’ or 1=1」 → 「¥¥’ or 1=1」
③PreparedStatement:: setStringメソッド内で文字列→Byte列に変換
「 ¥¥’ or 1=1 」 → [92,92,39, 32,111,114,32,49,61,49]
①データベースへの接続
②PreparedStatement::setStringメソッド内で引数の文字列のエスケープ
データベース データベース
① ② ③ ④
④SQLの実行
String Byte[]
※¥はUNICODEの’¥’である¥u00a5
ここでは
「Windows-31Jを使います!!」
と宣言
しかし処理する文字列には
UNICODE文字が含まれている
最初に指定した文字エンコーディン
グでバイト列に変更した結果、処理
の過程で異なる文字エンコーディン
グが混在することになる。
Windows-31J
Windows-31J
UNICODE UNICODE
Windows-31J
UNICODE Windows-31J
Select * from user …
Copyright©2013 JPCERT/CC All rights reserved.
問題点
 今回のアプリケーションにおける具体的な問題点
指定されたエンコーディングへの変換の前にエスケープ処理
を行っており、適切なエスケープ処理ができていなかった。
27
以下のコーディングガイドに違反している!!
「IDS01-J. 文字列は検査するまえに標準化する」
「IDS13-J. ファイル入出力やネットワーク入出力の両端で互換性
のある文字エンコーディングを使う」
⇒その結果、エスケープ処理をバイパスしてSQLインジェクショ
ンが成立する形になっていた。
Copyright©2013 JPCERT/CC All rights reserved.
問題点
 問題点に対してどうすべきだったか。
文字エンコーディングの変換をした後で文字列のエ
スケープ処理を実施すべきであった。
28
Copyright©2013 JPCERT/CC All rights reserved.
修正版コード
29
サンプルコードが実行された場合のMy SQL Connecter側の処理フロー
① 1行目でデータベースに接続する。
② 5行目のPreparedStatement::setStringメソッド内で第2引数inputの文字
列のエスケープが実行される。
③ 同じくPreparedStatement:: setStringメソッド内でgetBytesメソッドに
より文字列がByte列に変換され、プレースホルダに値が設定される。
④ 6行目でSQLクエリが実行される。
②の処理に修正が加えられている。
この脆弱性対応はバージョン5.1.8で行われている。
Copyright©2013 JPCERT/CC All rights reserved.
修正版コード
②PreparedStatement::setStringメソッド内で第2引数のエスケープ
30
public class PreparedStatement extends com.mysql.jdbc.StatementImpl
implements java.sql.PreparedStatement {
public void setString(int parameterIndex, String x) throws SQLException {
switch (c) {
:
case '¥u00a5':
case '¥u20a9':
// escape characters interpreted as backslash by mysql
if(charsetEncoder != null) {
CharBuffer cbuf = CharBuffer.allocate(1);
ByteBuffer bbuf = ByteBuffer.allocate(1);
cbuf.put(c);
cbuf.position(0);
charsetEncoder.encode(cbuf, bbuf, true);
if(bbuf.get(0) == '¥¥') {
buf.append('¥¥');
:
buf.append(c);
setStringメソッドにて¥u00a5に対する
エスケープ処理が追加されている。
Copyright©2013 JPCERT/CC All rights reserved.
修正の内容
U+00A5に対するエスケープ処理が追加されている。
⇒指定された文字エンコーディングに変換し、変換結果が
¥(バックスラッシュ)だった場合はもうひとつ ¥(バックスラッシュ)
を追加してエスケープする。
U+20a9(ウォンマーク)についても同様の脆弱性が発生
するため、エスケープ処理が追加されている。
31
Copyright©2013 JPCERT/CC All rights reserved.
修正版コードに対する考察
問題となる文字にだけ処理を行う「ブラックリスト」的
なアプローチ。同様の問題が発生するケースが他に存在
するかも
32
U+00A5やU+20a9だけでなく、文字列全体に同様の処理
を行うべきでは?
case句の前に入力文字列全体を指定された文字エンコー
ディングに変換する。(次ページにサンプルを記載)
Copyright©2013 JPCERT/CC All rights reserved.
public class PreparedStatement extends ・・・・・・・ {
public void setString(int parameterIndex, String x) throws SQLException {
:
StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));
byte[] bytex = x.getBytes(common_encoding);
for (int i = 0; i < stringLength; ++i) {
byte c = bytex[i];
switch (c) {
case 0: /* Must be escaped for 'mysql' */
:
case 92:
:
case 39:
:
default:
buf.append(c);
}
もう一つの修正案
エスケープ処理の前に文字エンコーディング変換
33
エスケープ処理の前に文字
エンコーディングを指定し
てバイト列に変換する。
変数common_encoding
はアプリ内で使用する文字
エンコーディングを指定。
その後 byte型で比較を行い、エスケープ処理を行う。
これにより、文字エンコーディングの不整合を悪用し
たエスケープ処理のバイパスはできなくなる。
Copyright©2013 JPCERT/CC All rights reserved.34
JVN ID タイトル
JVNDB-2006-
000306
PostgreSQL における特定のマルチバイト文字コードに
よる SQL インジェクションの脆弱性
JVNDB-2012-
001321
複数の Siemens 製品の HMI Web サーバにおける任意
のメモリロケーションからデータを読まれる脆弱性
JVNDB-2007-
000398
SquirrelMail におけるクロスサイトスクリプティングの
脆弱性
JVN ipedia の検索結果より抜粋
JVN ipediaで「文字コード」で検索をかけると複数の脆弱
性がヒットする。(2012年11月時点で24件)
文字エンコーディング不整合による処理の不備
文字エンコーディングに関連する処理の不備で発生した脆
弱性は他にも見つかっている。
Copyright©2013 JPCERT/CC All rights reserved.
まとめ
35
■この脆弱性から学べるプログラミングの注意点
•文字列に対して複数の処理を行う場合、処理の順序に
よっては目的とする効果が得られない場合がある
•今回のケースでは、SQLのメタ文字に対するエスケープ処
理と文字エンコーディング変換処理
■上記への対策
• アプリ内部の文字列処理では、まず最初に文字エンコー
ディングを統一するための前処理を入れる
• 可能であれば、文字列に異なる文字エンコーディングの
データが含まれていた場合はエラーとする
Copyright©2013 JPCERT/CC All rights reserved.
著作権・引用や二次利用について
本資料の著作権はJPCERT/CCに帰属します。
本資料あるいはその一部を引用・転載・再配布する際は、引用元名、資料名および URL の明示をお
願いします。
記載例
引用元:一般社団法人JPCERTコーディネーションセンター
Java アプリケーション脆弱性事例解説資料
MySQL Connector/J における SQL インジェクションの脆弱性
https://www.jpcert.or.jp/research/materials-java-casestudies/No.4_MySQL_Connector.pdf
本資料を引用・転載・再配布をする際は、引用先文書、時期、内容等の情報を、JPCERT コーディ
ネーションセンター広報(office@jpcert.or.jp)までメールにてお知らせください。なお、この連絡に
より取得した個人情報は、別途定めるJPCERT コーディネーションセンターの「プライバシーポリ
シー」に則って取り扱います。
本資料の利用方法等に関するお問い合わせ
JPCERTコーディネーションセンター
広報担当
E-mail:office@jpcert.or.jp
36
本資料の技術的な内容に関するお問い合わせ
JPCERTコーディネーションセンター
セキュアコーディング担当
E-mail:secure-coding@jpcert.or.jp

Más contenido relacionado

La actualidad más candente

Apache Sling におけるサービス運用妨害(無限ループ)の脆弱性
Apache Sling におけるサービス運用妨害(無限ループ)の脆弱性Apache Sling におけるサービス運用妨害(無限ループ)の脆弱性
Apache Sling におけるサービス運用妨害(無限ループ)の脆弱性JPCERT Coordination Center
 
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)JPCERT Coordination Center
 
デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」
デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」
デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」JPCERT Coordination Center
 
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)JPCERT Coordination Center
 
クロスサイトリクエストフォージェリ(CSRF)とその対策
クロスサイトリクエストフォージェリ(CSRF)とその対策クロスサイトリクエストフォージェリ(CSRF)とその対策
クロスサイトリクエストフォージェリ(CSRF)とその対策JPCERT Coordination Center
 
Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性
Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性
Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性JPCERT Coordination Center
 
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetupこれで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線MeetupMasatoshi Tada
 
Spring fest2020 spring-security
Spring fest2020 spring-securitySpring fest2020 spring-security
Spring fest2020 spring-security土岐 孝平
 
Lt agetsuma 拡大するcdi
Lt agetsuma 拡大するcdiLt agetsuma 拡大するcdi
Lt agetsuma 拡大するcdiNorito Agetsuma
 
Use JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUse JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUehara Junji
 
[デブサミ2012]趣味と実益の脆弱性発見
[デブサミ2012]趣味と実益の脆弱性発見[デブサミ2012]趣味と実益の脆弱性発見
[デブサミ2012]趣味と実益の脆弱性発見Yosuke HASEGAWA
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)Masatoshi Tada
 
JBoss Application Server におけるディレクトリトラバーサルの脆弱性
JBoss Application Server におけるディレクトリトラバーサルの脆弱性JBoss Application Server におけるディレクトリトラバーサルの脆弱性
JBoss Application Server におけるディレクトリトラバーサルの脆弱性JPCERT Coordination Center
 
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012Hiroshi Tokumaru
 
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_cccPivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_cccMasatoshi Tada
 
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4cCDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4cNorito Agetsuma
 
Synthesijer jjug 201504_01
Synthesijer jjug 201504_01Synthesijer jjug 201504_01
Synthesijer jjug 201504_01Takefumi MIYOSHI
 
Java SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にJava SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にTaku Miyakawa
 
Lessons (to be) Learned from Handling OpenSSL Vulnerabilities
Lessons (to be) Learned from Handling OpenSSL VulnerabilitiesLessons (to be) Learned from Handling OpenSSL Vulnerabilities
Lessons (to be) Learned from Handling OpenSSL VulnerabilitiesJPCERT Coordination Center
 
CERT コーディングスタンダードご紹介 (OSC2017@Osaka)
CERT コーディングスタンダードご紹介 (OSC2017@Osaka)CERT コーディングスタンダードご紹介 (OSC2017@Osaka)
CERT コーディングスタンダードご紹介 (OSC2017@Osaka)JPCERT Coordination Center
 

La actualidad más candente (20)

Apache Sling におけるサービス運用妨害(無限ループ)の脆弱性
Apache Sling におけるサービス運用妨害(無限ループ)の脆弱性Apache Sling におけるサービス運用妨害(無限ループ)の脆弱性
Apache Sling におけるサービス運用妨害(無限ループ)の脆弱性
 
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
 
デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」
デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」
デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」
 
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
 
クロスサイトリクエストフォージェリ(CSRF)とその対策
クロスサイトリクエストフォージェリ(CSRF)とその対策クロスサイトリクエストフォージェリ(CSRF)とその対策
クロスサイトリクエストフォージェリ(CSRF)とその対策
 
Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性
Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性
Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性
 
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetupこれで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
 
Spring fest2020 spring-security
Spring fest2020 spring-securitySpring fest2020 spring-security
Spring fest2020 spring-security
 
Lt agetsuma 拡大するcdi
Lt agetsuma 拡大するcdiLt agetsuma 拡大するcdi
Lt agetsuma 拡大するcdi
 
Use JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUse JWT access-token on Grails REST API
Use JWT access-token on Grails REST API
 
[デブサミ2012]趣味と実益の脆弱性発見
[デブサミ2012]趣味と実益の脆弱性発見[デブサミ2012]趣味と実益の脆弱性発見
[デブサミ2012]趣味と実益の脆弱性発見
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)
 
JBoss Application Server におけるディレクトリトラバーサルの脆弱性
JBoss Application Server におけるディレクトリトラバーサルの脆弱性JBoss Application Server におけるディレクトリトラバーサルの脆弱性
JBoss Application Server におけるディレクトリトラバーサルの脆弱性
 
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2012
 
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_cccPivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
 
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4cCDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
 
Synthesijer jjug 201504_01
Synthesijer jjug 201504_01Synthesijer jjug 201504_01
Synthesijer jjug 201504_01
 
Java SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にJava SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心に
 
Lessons (to be) Learned from Handling OpenSSL Vulnerabilities
Lessons (to be) Learned from Handling OpenSSL VulnerabilitiesLessons (to be) Learned from Handling OpenSSL Vulnerabilities
Lessons (to be) Learned from Handling OpenSSL Vulnerabilities
 
CERT コーディングスタンダードご紹介 (OSC2017@Osaka)
CERT コーディングスタンダードご紹介 (OSC2017@Osaka)CERT コーディングスタンダードご紹介 (OSC2017@Osaka)
CERT コーディングスタンダードご紹介 (OSC2017@Osaka)
 

Destacado

Blojsom におけるクロスサイトスクリプティングの脆弱性
Blojsom におけるクロスサイトスクリプティングの脆弱性Blojsom におけるクロスサイトスクリプティングの脆弱性
Blojsom におけるクロスサイトスクリプティングの脆弱性JPCERT Coordination Center
 
Advanced SQL Injection Attack & Defenses
Advanced SQL Injection Attack & DefensesAdvanced SQL Injection Attack & Defenses
Advanced SQL Injection Attack & DefensesTiago Mendo
 
Advanced sql injection
Advanced sql injectionAdvanced sql injection
Advanced sql injectionbadhanbd
 
OWASP ZAP(など)で挑む SECCON
OWASP ZAP(など)で挑む SECCONOWASP ZAP(など)で挑む SECCON
OWASP ZAP(など)で挑む SECCONJun Matsumoto
 
It all starts with the ' (SQL injection from attacker's point of view)
It all starts with the ' (SQL injection from attacker's point of view)It all starts with the ' (SQL injection from attacker's point of view)
It all starts with the ' (SQL injection from attacker's point of view)Miroslav Stampar
 
Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...
Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...
Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...JPCERT Coordination Center
 
OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)
OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)
OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)JPCERT Coordination Center
 
自分よりも技術力の高い会社に入社して感じたこと
自分よりも技術力の高い会社に入社して感じたこと自分よりも技術力の高い会社に入社して感じたこと
自分よりも技術力の高い会社に入社して感じたことSuzuki Masayuki
 
Devsumi2015_20E1 エンジニアが知っておきたいお金の話
Devsumi2015_20E1 エンジニアが知っておきたいお金の話Devsumi2015_20E1 エンジニアが知っておきたいお金の話
Devsumi2015_20E1 エンジニアが知っておきたいお金の話Akio Doi
 
とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達zaki4649
 
ツイッター調査:約173万ツイートを調査して分かったTwitterの利用動向 #twtr_hack
ツイッター調査:約173万ツイートを調査して分かったTwitterの利用動向 #twtr_hackツイッター調査:約173万ツイートを調査して分かったTwitterの利用動向 #twtr_hack
ツイッター調査:約173万ツイートを調査して分かったTwitterの利用動向 #twtr_hackteapipin
 

Destacado (13)

Blojsom におけるクロスサイトスクリプティングの脆弱性
Blojsom におけるクロスサイトスクリプティングの脆弱性Blojsom におけるクロスサイトスクリプティングの脆弱性
Blojsom におけるクロスサイトスクリプティングの脆弱性
 
Advanced SQL Injection Attack & Defenses
Advanced SQL Injection Attack & DefensesAdvanced SQL Injection Attack & Defenses
Advanced SQL Injection Attack & Defenses
 
Advanced sql injection
Advanced sql injectionAdvanced sql injection
Advanced sql injection
 
OWASP ZAP(など)で挑む SECCON
OWASP ZAP(など)で挑む SECCONOWASP ZAP(など)で挑む SECCON
OWASP ZAP(など)で挑む SECCON
 
It all starts with the ' (SQL injection from attacker's point of view)
It all starts with the ' (SQL injection from attacker's point of view)It all starts with the ' (SQL injection from attacker's point of view)
It all starts with the ' (SQL injection from attacker's point of view)
 
Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...
Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...
Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...
 
脆弱性情報はこうしてやってくる
脆弱性情報はこうしてやってくる脆弱性情報はこうしてやってくる
脆弱性情報はこうしてやってくる
 
OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)
OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)
OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)
 
自分よりも技術力の高い会社に入社して感じたこと
自分よりも技術力の高い会社に入社して感じたこと自分よりも技術力の高い会社に入社して感じたこと
自分よりも技術力の高い会社に入社して感じたこと
 
Devsumi2015_20E1 エンジニアが知っておきたいお金の話
Devsumi2015_20E1 エンジニアが知っておきたいお金の話Devsumi2015_20E1 エンジニアが知っておきたいお金の話
Devsumi2015_20E1 エンジニアが知っておきたいお金の話
 
SQL injection: Not only AND 1=1
SQL injection: Not only AND 1=1SQL injection: Not only AND 1=1
SQL injection: Not only AND 1=1
 
とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達
 
ツイッター調査:約173万ツイートを調査して分かったTwitterの利用動向 #twtr_hack
ツイッター調査:約173万ツイートを調査して分かったTwitterの利用動向 #twtr_hackツイッター調査:約173万ツイートを調査して分かったTwitterの利用動向 #twtr_hack
ツイッター調査:約173万ツイートを調査して分かったTwitterの利用動向 #twtr_hack
 

Similar a MySQL Connector/J における SQL インジェクションの脆弱性

Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Shotaro Suzuki
 
[db tech showcase Tokyo 2017] D15: ビッグデータ x 機械学習の高速分析をVerticaで実現!by ヒューレット・パッ...
[db tech showcase Tokyo 2017] D15: ビッグデータ x 機械学習の高速分析をVerticaで実現!by ヒューレット・パッ...[db tech showcase Tokyo 2017] D15: ビッグデータ x 機械学習の高速分析をVerticaで実現!by ヒューレット・パッ...
[db tech showcase Tokyo 2017] D15: ビッグデータ x 機械学習の高速分析をVerticaで実現!by ヒューレット・パッ...Insight Technology, Inc.
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理土岐 孝平
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/AndroidセキュアコーディングMasaki Kubo
 
Share pointを支えるsql server2014最新情報 tokyo_公開用
Share pointを支えるsql server2014最新情報 tokyo_公開用Share pointを支えるsql server2014最新情報 tokyo_公開用
Share pointを支えるsql server2014最新情報 tokyo_公開用Yukio Kumazawa
 
Statically detecting vulnerability under memory pressure using exhaustive search
Statically detecting vulnerability under memory pressure usingexhaustive searchStatically detecting vulnerability under memory pressure usingexhaustive search
Statically detecting vulnerability under memory pressure using exhaustive searchRuo Ando
 
Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Shotaro Suzuki
 
SAStruts Seminar In Tripodworks
SAStruts Seminar In TripodworksSAStruts Seminar In Tripodworks
SAStruts Seminar In Tripodworkstripodworks
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionYoshitaka Seo
 
Osc2017 tokyo spring_soss_sig
Osc2017 tokyo spring_soss_sigOsc2017 tokyo spring_soss_sig
Osc2017 tokyo spring_soss_sigKazuki Omo
 
Node.js勉強会 Framework Koa
Node.js勉強会 Framework KoaNode.js勉強会 Framework Koa
Node.js勉強会 Framework Koakamiyam .
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
Share pointを支えるsql server2014最新情報
Share pointを支えるsql server2014最新情報Share pointを支えるsql server2014最新情報
Share pointを支えるsql server2014最新情報Atsuo Yamasaki
 
Handlersocket 20110517
Handlersocket 20110517Handlersocket 20110517
Handlersocket 20110517akirahiguchi
 
WebRTC meetup Tokyo 1
WebRTC meetup  Tokyo 1WebRTC meetup  Tokyo 1
WebRTC meetup Tokyo 1mganeko
 
文字コードの脆弱性はこの3年間でどの程度対策されたか?
文字コードの脆弱性はこの3年間でどの程度対策されたか?文字コードの脆弱性はこの3年間でどの程度対策されたか?
文字コードの脆弱性はこの3年間でどの程度対策されたか?Hiroshi Tokumaru
 
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」Hiroyuki Ohnaka
 
jjugccc2018 app review postmortem
jjugccc2018 app review postmortemjjugccc2018 app review postmortem
jjugccc2018 app review postmortemtamtam180
 

Similar a MySQL Connector/J における SQL インジェクションの脆弱性 (20)

Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
 
[db tech showcase Tokyo 2017] D15: ビッグデータ x 機械学習の高速分析をVerticaで実現!by ヒューレット・パッ...
[db tech showcase Tokyo 2017] D15: ビッグデータ x 機械学習の高速分析をVerticaで実現!by ヒューレット・パッ...[db tech showcase Tokyo 2017] D15: ビッグデータ x 機械学習の高速分析をVerticaで実現!by ヒューレット・パッ...
[db tech showcase Tokyo 2017] D15: ビッグデータ x 機械学習の高速分析をVerticaで実現!by ヒューレット・パッ...
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/Androidセキュアコーディング
 
ScalaMatsuri 2016
ScalaMatsuri 2016ScalaMatsuri 2016
ScalaMatsuri 2016
 
Java EE8 Report
Java EE8 ReportJava EE8 Report
Java EE8 Report
 
Share pointを支えるsql server2014最新情報 tokyo_公開用
Share pointを支えるsql server2014最新情報 tokyo_公開用Share pointを支えるsql server2014最新情報 tokyo_公開用
Share pointを支えるsql server2014最新情報 tokyo_公開用
 
Statically detecting vulnerability under memory pressure using exhaustive search
Statically detecting vulnerability under memory pressure usingexhaustive searchStatically detecting vulnerability under memory pressure usingexhaustive search
Statically detecting vulnerability under memory pressure using exhaustive search
 
Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...
 
SAStruts Seminar In Tripodworks
SAStruts Seminar In TripodworksSAStruts Seminar In Tripodworks
SAStruts Seminar In Tripodworks
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom Vision
 
Osc2017 tokyo spring_soss_sig
Osc2017 tokyo spring_soss_sigOsc2017 tokyo spring_soss_sig
Osc2017 tokyo spring_soss_sig
 
Node.js勉強会 Framework Koa
Node.js勉強会 Framework KoaNode.js勉強会 Framework Koa
Node.js勉強会 Framework Koa
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
Share pointを支えるsql server2014最新情報
Share pointを支えるsql server2014最新情報Share pointを支えるsql server2014最新情報
Share pointを支えるsql server2014最新情報
 
Handlersocket 20110517
Handlersocket 20110517Handlersocket 20110517
Handlersocket 20110517
 
WebRTC meetup Tokyo 1
WebRTC meetup  Tokyo 1WebRTC meetup  Tokyo 1
WebRTC meetup Tokyo 1
 
文字コードの脆弱性はこの3年間でどの程度対策されたか?
文字コードの脆弱性はこの3年間でどの程度対策されたか?文字コードの脆弱性はこの3年間でどの程度対策されたか?
文字コードの脆弱性はこの3年間でどの程度対策されたか?
 
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
 
jjugccc2018 app review postmortem
jjugccc2018 app review postmortemjjugccc2018 app review postmortem
jjugccc2018 app review postmortem
 

Más de JPCERT Coordination Center

いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~
いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~
いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~JPCERT Coordination Center
 
安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)
安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)
安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)JPCERT Coordination Center
 
WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』
WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』
WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』JPCERT Coordination Center
 
ソフトウェアセキュリティ保証成熟度モデル
ソフトウェアセキュリティ保証成熟度モデルソフトウェアセキュリティ保証成熟度モデル
ソフトウェアセキュリティ保証成熟度モデルJPCERT Coordination Center
 
Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説JPCERT Coordination Center
 
Javaセキュアコーディングセミナー東京第4回演習の解説
Javaセキュアコーディングセミナー東京第4回演習の解説Javaセキュアコーディングセミナー東京第4回演習の解説
Javaセキュアコーディングセミナー東京第4回演習の解説JPCERT Coordination Center
 
Javaセキュアコーディングセミナー東京第4回講義
Javaセキュアコーディングセミナー東京第4回講義Javaセキュアコーディングセミナー東京第4回講義
Javaセキュアコーディングセミナー東京第4回講義JPCERT Coordination Center
 
Javaセキュアコーディングセミナー東京第3回演習
Javaセキュアコーディングセミナー東京第3回演習Javaセキュアコーディングセミナー東京第3回演習
Javaセキュアコーディングセミナー東京第3回演習JPCERT Coordination Center
 

Más de JPCERT Coordination Center (10)

いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~
いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~
いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~
 
安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)
安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)
安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)
 
DLL読み込みの問題を読み解く
DLL読み込みの問題を読み解くDLL読み込みの問題を読み解く
DLL読み込みの問題を読み解く
 
WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』
WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』
WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』
 
ソフトウェアセキュリティ保証成熟度モデル
ソフトウェアセキュリティ保証成熟度モデルソフトウェアセキュリティ保証成熟度モデル
ソフトウェアセキュリティ保証成熟度モデル
 
Android Secure Coding
Android Secure CodingAndroid Secure Coding
Android Secure Coding
 
Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説
 
Javaセキュアコーディングセミナー東京第4回演習の解説
Javaセキュアコーディングセミナー東京第4回演習の解説Javaセキュアコーディングセミナー東京第4回演習の解説
Javaセキュアコーディングセミナー東京第4回演習の解説
 
Javaセキュアコーディングセミナー東京第4回講義
Javaセキュアコーディングセミナー東京第4回講義Javaセキュアコーディングセミナー東京第4回講義
Javaセキュアコーディングセミナー東京第4回講義
 
Javaセキュアコーディングセミナー東京第3回演習
Javaセキュアコーディングセミナー東京第3回演習Javaセキュアコーディングセミナー東京第3回演習
Javaセキュアコーディングセミナー東京第3回演習
 

Último

新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価sugiuralab
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールsugiuralab
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 

Último (7)

新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 

MySQL Connector/J における SQL インジェクションの脆弱性

  • 1. Copyright©2013 JPCERT/CC All rights reserved. 「Javaアプリケーション脆弱性事例調査資料」について この資料は、Javaプログラマである皆様に、脆弱性を身 近な問題として感じてもらい、セキュアコーディングの 重要性を認識していただくことを目指して作成していま す。 「Javaセキュアコーディングスタンダード CERT/Oracle版」と合わせて、セキュアコーディングに 関する理解を深めるためにご利用ください。 JPCERTコーディネーションセンター セキュアコーディングプロジェクト secure-coding@jpcert.or.jp 1 Japan Computer Emergency Response Team Coordination Center 電子署名者 : Japan Computer Emergency Response Team Coordination Center DN : c=JP, st=Tokyo, l=Chiyoda-ku, email=office@jpcert.or.jp, o=Japan Computer Emergency Response Team Coordination Center, cn=Japan Computer Emergency Response Team Coordination Center 日付 : 2013.06.26 11:01:16 +09'00'
  • 2. MySQL Connector/J における SQL インジェクションの脆弱性 JVN#59748723 JVNDB-2009-000050 2
  • 3. Copyright©2013 JPCERT/CC All rights reserved. MySQL Connectorとは MySQLデータベースにアクセスするための Java アプリ ケーション用ドライバソフトウェア MySQLを利用するJavaアプリケーションを簡単に作成 できる 3 MySQL Connector
  • 4. Copyright©2013 JPCERT/CC All rights reserved. 脆弱性の概要 MySQL Connector/J にはSQLクエリ文字列の処 理に不備があり、SQLインジェクションが可能 となる脆弱性が存在する。 Javaアプリケーションがプリペアードステート メント等の適切な処理を実装している場合でも SQLインジェクションが可能。 4
  • 5. Copyright©2013 JPCERT/CC All rights reserved. SQLインジェクションとは 入力値を元にSQL文を動的に生成しているアプリケーションに 対し、細工した入力を与えることで(アプリケーションの意図 しないような) 任意のSQL文を挿入/実行すること。 5 ① SQL文を含む不正なリクエストの送信 ‘ or ‘a’=‘a データベース上のデータの漏えいや改ざん、 破壊などの被害を受ける可能性がある。
  • 6. Copyright©2013 JPCERT/CC All rights reserved. プリペアードステートメントとは 事前に定義したSQL文のプレースホルダ(予約場 所)に入力データを割り当てる機能。 プリペアドステートメントを利用すると、入力 データは数値定数や文字列定数として組み込ま れ、文字列として扱われることになる。 一般的にSQLインジェクション対策として使用 される。 6
  • 7. Copyright©2013 JPCERT/CC All rights reserved. プリペアードステートメントとは: サンプルコード 7 1: Connection conn = DriverManager.getConnection( "jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password"); 2: String input = request.getParameter("name"); 3: String sql = "SELECT * FROM user WHERE name=?"; 4: PreparedStatement ps = conn.prepareStatement(sql); 5: ps.setString(1, input); // 1は1番目のプレースホルダを表す 6: ResultSet resultSet = ps.executeQuery();  1行目:データベースと接続する  2行目:リクエスト中のパラメータnameの値を取得して変数inputに格納する  3行目:「?」文字がプレースホルダ  4行目:SQL文のプリコンパイルを行う。  5行目:プレースホルダと変数の関連付けを行う。この例では、1番目のプレースホル ダに変数inputを設定する。  6行目:SQL文を実行し結果を得る。 解説
  • 8. Copyright©2013 JPCERT/CC All rights reserved. MySQL Connector の処理内容 8 1: Connection conn = DriverManager.getConnection( "jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password"); 2: String input = request.getParameter("name"); 3: String sql = "SELECT * FROM user WHERE name=?"; 4: PreparedStatement ps = conn.prepareStatement(sql); 5: ps.setString(1, input); 6: ResultSet resultSet = ps.executeQuery(); 前述のサンプルコードを使用して処理を解説する。 MySQL Connector側で処理が行われる箇所 •com.mysql.jdbc.Connectionクラス •com.mysql.jdbc.PreparedStatementクラス
  • 9. Copyright©2013 JPCERT/CC All rights reserved.9 1: Connection conn = DriverManager.getConnection( "jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password"); 2: String input = request.getParameter("name"); 3: String sql = "SELECT * FROM user WHERE name=?"; 4: PreparedStatement ps = conn.prepareStatement(sql); 5: ps.setString(1, input); 6: ResultSet resultSet = ps.executeQuery(); サンプルコードが実行された場合のMy SQL Connecter側の処理フロー ① 1行目でデータベースに接続する。 ② 5行目のPreparedStatement::setStringメソッド内で第2引数inputの文字 列のエスケープが実行される。 ③ 同じくPreparedStatement:: setStringメソッド内で文字列がByte列に変 換され、プレースホルダに値が設定される。 ④ 6行目でSQLクエリが実行される。 Point!! MySQL Connector の処理内容
  • 10. Copyright©2013 JPCERT/CC All rights reserved.10 1: Connection conn = DriverManager.getConnection( "jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password"); 2: String input = request.getParameter("name"); 3: String sql = "SELECT * FROM user WHERE name=?"; 4: PreparedStatement ps = conn.prepareStatement(sql); 5: ps.setString(1, input); 6: ResultSet resultSet = ps.executeQuery(); MySQL Connector の処理 ①データベースへの接続 データベースに接続する。パラメータcharacterEncoding で アプリケーションで使用する文字エンコーディングを指定する。
  • 11. Copyright©2013 JPCERT/CC All rights reserved.11 1: Connection conn = DriverManager.getConnection( "jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password"); 2: String input = request.getParameter("name"); 3: String sql = "SELECT * FROM user WHERE name=?"; 4: PreparedStatement ps = conn.prepareStatement(sql); 5: ps.setString(1, input); 6: ResultSet resultSet = ps.executeQuery(); MySQL Connector の処理 ②PreparedStatement::setStringで第2引数のエスケープ 変数inputをリクエストから受け取り、 PreparedStatement::setString メソッドの 第2引数として渡す。
  • 12. Copyright©2013 JPCERT/CC All rights reserved.12 public class PreparedStatement extends ・・・・・・・ { public void setString(int parameterIndex, String x) throws SQLException { : StringBuffer buf = new StringBuffer((int) (x.length() * 1.1)); for (int i = 0; i < stringLength; ++i) { char c = x.charAt(i); switch (c) { case 0: /* Must be escaped for 'mysql' */ buf.append('¥¥'); buf.append('0'); break; : case '¥¥': : case '¥'': : default: buf.append(c); } setStringメソッドの第2引数 のxがプレースホルダにセッ トされる文字列。 Xから1文字ずつ取り出して、 特殊文字に対してエスケー プ処理を行う。 MySQL Connector の処理 ②PreparedStatement::setStringで第2引数のエスケープ
  • 13. Copyright©2013 JPCERT/CC All rights reserved. エスケープ処理のまとめ 13 入力文字列 エスケープ処理後の文字列 NULL ¥0 ¥n ¥n ¥r ¥r ¥ (スラッシュ) ¥¥ ‘ (シングルクオート) ¥’ “ (ダブルクオート) ¥” ¥032 ¥Z 上記以外 特に処理なし setStringメソッドに渡される値が「’ or 1=1」の場合は 上記のエスケープ処理によって「 ¥’ or 1=1 」となる。 MySQL Connector の処理 ②PreparedStatement::setStringで第2引数のエスケープ
  • 14. Copyright©2013 JPCERT/CC All rights reserved. MySQL Connector の処理 ③PreparedStatement::setStringでByte列への変換 14 public class PreparedStatement extends com.mysql.jdbc.StatementImpl implements java.sql.PreparedStatement { public void setString(int parameterIndex, String x) throws SQLException { : parameterAsString = buf.toString(); byte[] parameterAsBytes = null; parameterAsBytes = StringUtils.getBytes(parameterAsString, this.charConverter, this.charEncoding, this.connection .getServerCharacterEncoding(), this.connection .parserKnowsUnicode()); : setInternal(parameterIndex, parameterAsBytes); エスケープ処理後の文字列が String型変数parameterAsString に保存される。 StringUtils::parameterAsStringメソッドで文字列をByte列に変換する。 その際に指定されるcharEncodingは接続時に指定した文字コード (Windows-31J)が設定される。 Windows-31J
  • 15. Copyright©2013 JPCERT/CC All rights reserved.15 ■StringUtils.getBytesメソッドによるByte列への変換 StringUtils.getBytesメソッドでは内部的にString.getBytesメソッドが呼び出 されている。 ¥ ’ space o r space 1 = 1 public static final byte[] getBytes(String s, SingleByteCharsetConverter converter, String encoding, String serverEncoding, boolean parserKnowsUnicode) throws SQLException { : b = s.getBytes(encoding); : return b; StringUtils.java ■変換対象の文字列(第1引数s)が「 ¥’ or 1=1 」の場合 ⇒ [92,39, 32, 111,114, 32, 49,61,49] というByte列に変換される。 Windows-31J setStringメソッドの 第2引数 MySQL Connector の処理 ③PreparedStatement::setStringでByte列への変換
  • 16. Copyright©2013 JPCERT/CC All rights reserved.16 public class PreparedStatement extends com.mysql.jdbc.StatementImpl implements java.sql.PreparedStatement { public void setString(int parameterIndex, String x) throws SQLException { : parameterAsString = buf.toString(); byte[] parameterAsBytes = null; parameterAsBytes = StringUtils.getBytes(parameterAsString, this.charConverter, this.charEncoding, this.connection .getServerCharacterEncoding(), this.connection .parserKnowsUnicode()); : setInternal(parameterIndex, parameterAsBytes); com.mysql.jdbc.PreparedStatement.setInternal メソッドで、 先ほど変換したByte列をプリペアードステートメントにセットする。 MySQL Connector の処理 ③PreparedStatement::setStringでByte列への変換
  • 17. Copyright©2013 JPCERT/CC All rights reserved. MySQL Connector の処理 ④SQLクエリの実行 17 SQLが実行される。結果として実行されるSQLは・・・ ■変数inputが「test」の場合 実行されるSQLは 「 SELECT * FROM user WHERE name=‘test’」 となる。 ■変数inputが「’ or 1=1」の場合 実行されるSQLは 「 SELECT * FROM user WHERE name=‘¥’ or 1=1’」 となり、変数inputに含まれるシングルクオートがエスケープ される。
  • 18. Copyright©2013 JPCERT/CC All rights reserved. MySQL Connector の処理のまとめ 18 ¥ ’ space o r space 1 = 1 SELECT * FROM user WHERE name=‘ ? ‘ [92,39,32,111,114, 32, 49,61,49] ¥ ’ space o r space 1 = 1 SELECT * FROM user WHERE name=‘¥’ or 1=1’ ‘ or 1=1 ¥‘ or 1=1 [92,39,・・・]¥‘ or 1=1 プレースホルダへのセット 「’ or 1=1」 → 「¥’ or 1=1」 ③PreparedStatement:: setStringメソッド内で文字列をByte列に変換 「 ¥’ or 1=1 」 → [92,39,32,111,114,32,49,61,49] ①データベースへの接続 ②PreparedStatement::setStringメソッド内で引数の文字列のエスケープ データベース エスケープ 処理 データベース ① ② ③ ④ ④SQLの実行 String Byte[] Select * from user … getBytes()
  • 19. Copyright©2013 JPCERT/CC All rights reserved. 攻撃コード 19 1: Connection conn = DriverManager.getConnection( "jdbc:mysql://192.168.xxx.xxx/?characterEncoding=Windows-31J",“id", "password"); 2: String sql = "SELECT * FROM user WHERE name=?"; 3: PreparedStatement ps = conn.prepareStatement(sql); 4: ps.setString(1, "¥u00a5' or 1 = 1#"); 5: ResultSet resultSet = ps.executeQuery(); ■攻撃コードのポイント • 4行目のsetStringメソッドの引数(プレースホルダに入れる値)に UNICODEで‘¥’ (YEN SIGN) に該当するU+00A5を挿入し、その 後に「’ or 1=1#」という値を渡している。 • 1行目のデータベース接続時の文字エンコーディングとして 「Windows-31J」を指定しており、異なる文字エンコーディン グを使用した文字列が含まれていることになる。
  • 20. Copyright©2013 JPCERT/CC All rights reserved. 攻撃コード 20 サンプルコードが実行された場合のMy SQL Connecter側の処理フロー ① 1行目でデータベースに接続する。 ② 5行目のPreparedStatement::setStringメソッド内で第2引数inputの文字 列のエスケープが実行される。 ③ 同じくPreparedStatement::setStringメソッド内でgetBytesメソッドに より文字列がByte列に変換され、プレースホルダに値が設定される。 ④ 6行目でSQLクエリが実行される。 ②と③で脆弱性の原因となる処理が実行される
  • 21. Copyright©2013 JPCERT/CC All rights reserved. 攻撃コードが実行された際の処理 ②PreparedStatement::setStringで第2引数のエスケープ 21 public class PreparedStatement extends ・・・・・・・ { public void setString(int parameterIndex, String x) throws SQLException { : StringBuffer buf = new StringBuffer((int) (x.length() * 1.1)); for (int i = 0; i < stringLength; ++i) { char c = x.charAt(i); switch (c) { case 0: /* Must be escaped for 'mysql' */ buf.append('¥¥'); buf.append('0'); break; : case '¥¥': : : default: buf.append(c); } setStringメソッドの第2引数 のxがプレースホルダにセッ トされる。 Xから1文字ずつ取り出して、 特殊文字に対してエスケー プ処理を行う。 しかし、 UNICODEの’¥’である¥u00a5はエスケープされない。 そのため、エスケープ処理の結果は 「¥’ or 1 = 1#」→ 「¥¥’ or 1 = 1#」 となる!! ¥’ or 1 = 1# ※¥はUNICODEの’¥’である¥u00a5 ※¥はUNICODEの’¥’である¥u00a5
  • 22. Copyright©2013 JPCERT/CC All rights reserved. 攻撃コードが実行された際の処理 ③PreparedStatement::setStringでgetBytesメソッドによるByte列への変換 22 public class PreparedStatement extends com.mysql.jdbc.StatementImpl implements java.sql.PreparedStatement { public void setString(int parameterIndex, String x) throws SQLException { : parameterAsString = buf.toString(); byte[] parameterAsBytes = null; parameterAsBytes = StringUtils.getBytes(parameterAsString, this.charConverter, this.charEncoding, this.connection .getServerCharacterEncoding(), this.connection .parserKnowsUnicode()); : setInternal(parameterIndex, parameterAsBytes); エスケープ処理後の文字列がString型 変数parameterAsStringに保存される。 StringUtils::parameterAsStringメソッドで文字列をByte列に変換する。 その際に指定されるcharEncodingは接続時に指定したエンコーディング (Windows-31J)が設定される。 ¥¥’ or 1 = 1# ※¥はUNICODEの’¥’である¥u00a5 Windows-31J
  • 23. Copyright©2013 JPCERT/CC All rights reserved.23 public static final byte[] getBytes(String s, SingleByteCharsetConverter converter, String encoding, String serverEncoding, boolean parserKnowsUnicode) throws SQLException { : b = s.getBytes(encoding); : return b; StringUtils.java ■攻撃コードが実行された場合 getBytesメソッドでU+00A5はShift JISの’¥’として変換されてしまう!! Windows-31J ¥¥’ or 1 = 1# ※¥はUNICODEの’¥’である¥u00a5 「¥¥’ or 1 = 1#」→ [92,92,39, 32,111,114, 32,49,61,49,35] 本来のバイト列は[165,92,39,32,111,114,32,49,61,49,35] ※¥はUNICODEの’¥’である¥u00a5 ¥ ¥ ’ space o r space 1 = 1 # 攻撃コードが実行された際の処理 ③PreparedStatement::setStringでgetBytesメソッドによるByte列への変換 ■StringUtils.getBytesメソッドによるByte列への変換 StringUtils.getBytesの内部ではString.getBytesメソッドを使っている。
  • 24. Copyright©2013 JPCERT/CC All rights reserved.24 public class PreparedStatement extends com.mysql.jdbc.StatementImpl implements java.sql.PreparedStatement { public void setString(int parameterIndex, String x) throws SQLException { : parameterAsString = buf.toString(); byte[] parameterAsBytes = null; parameterAsBytes = StringUtils.getBytes(parameterAsString, this.charConverter, this.charEncoding, this.connection .getServerCharacterEncoding(), this.connection .parserKnowsUnicode()); : setInternal(parameterIndex, parameterAsBytes); com.mysql.jdbc.PreparedStatement.setInternalメソッドで、 先ほど変換したByte列をプリペアードステートメントにセットする。 [92,92,39, 32,111,114,32,49,61,49,35] ¥ ¥ ’ space o r space 1 = 1 # 攻撃コードが実行された際の処理 ③PreparedStatement::setStringでgetBytesメソッドによるByte列への変換
  • 25. Copyright©2013 JPCERT/CC All rights reserved. 攻撃コードが実行された際の処理 25 SELECT * FROM user WHERE name=‘ ? ‘ [92,92,39,32,111,114,32,49,61,49,35] SELECT * FROM user WHERE name=‘¥¥’ or 1=1#’ ¥ ¥ ’ space o r space 1 = 1 # SQL文のWhere句は、 「nameが¥(バックスラッシュ)と等しい、あるいは、1が1と等しい」 という条件になり、本来実行されるべきクエリから内容が変更されてし まった!! (#はMySQLでのコメント文字であり、これ以降は無視される.) ■プレースホルダへのセット 変換されたByte列がプレースホルダにセットされる。
  • 26. Copyright©2013 JPCERT/CC All rights reserved. 攻撃コードが実行された際の処理 26 ¥ ¥ ’ space o r space 1 = 1 SELECT * FROM user WHERE name=‘ ? ‘ SELECT * FROM user WHERE name=‘¥¥’ or 1=1#’ ¥‘ or 1=1 ¥¥‘ or 1=1 [92,92,39,・・・]¥¥‘ or 1=1 プレースホルダへのセット 「¥’ or 1=1」 → 「¥¥’ or 1=1」 ③PreparedStatement:: setStringメソッド内で文字列→Byte列に変換 「 ¥¥’ or 1=1 」 → [92,92,39, 32,111,114,32,49,61,49] ①データベースへの接続 ②PreparedStatement::setStringメソッド内で引数の文字列のエスケープ データベース データベース ① ② ③ ④ ④SQLの実行 String Byte[] ※¥はUNICODEの’¥’である¥u00a5 ここでは 「Windows-31Jを使います!!」 と宣言 しかし処理する文字列には UNICODE文字が含まれている 最初に指定した文字エンコーディン グでバイト列に変更した結果、処理 の過程で異なる文字エンコーディン グが混在することになる。 Windows-31J Windows-31J UNICODE UNICODE Windows-31J UNICODE Windows-31J Select * from user …
  • 27. Copyright©2013 JPCERT/CC All rights reserved. 問題点  今回のアプリケーションにおける具体的な問題点 指定されたエンコーディングへの変換の前にエスケープ処理 を行っており、適切なエスケープ処理ができていなかった。 27 以下のコーディングガイドに違反している!! 「IDS01-J. 文字列は検査するまえに標準化する」 「IDS13-J. ファイル入出力やネットワーク入出力の両端で互換性 のある文字エンコーディングを使う」 ⇒その結果、エスケープ処理をバイパスしてSQLインジェクショ ンが成立する形になっていた。
  • 28. Copyright©2013 JPCERT/CC All rights reserved. 問題点  問題点に対してどうすべきだったか。 文字エンコーディングの変換をした後で文字列のエ スケープ処理を実施すべきであった。 28
  • 29. Copyright©2013 JPCERT/CC All rights reserved. 修正版コード 29 サンプルコードが実行された場合のMy SQL Connecter側の処理フロー ① 1行目でデータベースに接続する。 ② 5行目のPreparedStatement::setStringメソッド内で第2引数inputの文字 列のエスケープが実行される。 ③ 同じくPreparedStatement:: setStringメソッド内でgetBytesメソッドに より文字列がByte列に変換され、プレースホルダに値が設定される。 ④ 6行目でSQLクエリが実行される。 ②の処理に修正が加えられている。 この脆弱性対応はバージョン5.1.8で行われている。
  • 30. Copyright©2013 JPCERT/CC All rights reserved. 修正版コード ②PreparedStatement::setStringメソッド内で第2引数のエスケープ 30 public class PreparedStatement extends com.mysql.jdbc.StatementImpl implements java.sql.PreparedStatement { public void setString(int parameterIndex, String x) throws SQLException { switch (c) { : case '¥u00a5': case '¥u20a9': // escape characters interpreted as backslash by mysql if(charsetEncoder != null) { CharBuffer cbuf = CharBuffer.allocate(1); ByteBuffer bbuf = ByteBuffer.allocate(1); cbuf.put(c); cbuf.position(0); charsetEncoder.encode(cbuf, bbuf, true); if(bbuf.get(0) == '¥¥') { buf.append('¥¥'); : buf.append(c); setStringメソッドにて¥u00a5に対する エスケープ処理が追加されている。
  • 31. Copyright©2013 JPCERT/CC All rights reserved. 修正の内容 U+00A5に対するエスケープ処理が追加されている。 ⇒指定された文字エンコーディングに変換し、変換結果が ¥(バックスラッシュ)だった場合はもうひとつ ¥(バックスラッシュ) を追加してエスケープする。 U+20a9(ウォンマーク)についても同様の脆弱性が発生 するため、エスケープ処理が追加されている。 31
  • 32. Copyright©2013 JPCERT/CC All rights reserved. 修正版コードに対する考察 問題となる文字にだけ処理を行う「ブラックリスト」的 なアプローチ。同様の問題が発生するケースが他に存在 するかも 32 U+00A5やU+20a9だけでなく、文字列全体に同様の処理 を行うべきでは? case句の前に入力文字列全体を指定された文字エンコー ディングに変換する。(次ページにサンプルを記載)
  • 33. Copyright©2013 JPCERT/CC All rights reserved. public class PreparedStatement extends ・・・・・・・ { public void setString(int parameterIndex, String x) throws SQLException { : StringBuffer buf = new StringBuffer((int) (x.length() * 1.1)); byte[] bytex = x.getBytes(common_encoding); for (int i = 0; i < stringLength; ++i) { byte c = bytex[i]; switch (c) { case 0: /* Must be escaped for 'mysql' */ : case 92: : case 39: : default: buf.append(c); } もう一つの修正案 エスケープ処理の前に文字エンコーディング変換 33 エスケープ処理の前に文字 エンコーディングを指定し てバイト列に変換する。 変数common_encoding はアプリ内で使用する文字 エンコーディングを指定。 その後 byte型で比較を行い、エスケープ処理を行う。 これにより、文字エンコーディングの不整合を悪用し たエスケープ処理のバイパスはできなくなる。
  • 34. Copyright©2013 JPCERT/CC All rights reserved.34 JVN ID タイトル JVNDB-2006- 000306 PostgreSQL における特定のマルチバイト文字コードに よる SQL インジェクションの脆弱性 JVNDB-2012- 001321 複数の Siemens 製品の HMI Web サーバにおける任意 のメモリロケーションからデータを読まれる脆弱性 JVNDB-2007- 000398 SquirrelMail におけるクロスサイトスクリプティングの 脆弱性 JVN ipedia の検索結果より抜粋 JVN ipediaで「文字コード」で検索をかけると複数の脆弱 性がヒットする。(2012年11月時点で24件) 文字エンコーディング不整合による処理の不備 文字エンコーディングに関連する処理の不備で発生した脆 弱性は他にも見つかっている。
  • 35. Copyright©2013 JPCERT/CC All rights reserved. まとめ 35 ■この脆弱性から学べるプログラミングの注意点 •文字列に対して複数の処理を行う場合、処理の順序に よっては目的とする効果が得られない場合がある •今回のケースでは、SQLのメタ文字に対するエスケープ処 理と文字エンコーディング変換処理 ■上記への対策 • アプリ内部の文字列処理では、まず最初に文字エンコー ディングを統一するための前処理を入れる • 可能であれば、文字列に異なる文字エンコーディングの データが含まれていた場合はエラーとする
  • 36. Copyright©2013 JPCERT/CC All rights reserved. 著作権・引用や二次利用について 本資料の著作権はJPCERT/CCに帰属します。 本資料あるいはその一部を引用・転載・再配布する際は、引用元名、資料名および URL の明示をお 願いします。 記載例 引用元:一般社団法人JPCERTコーディネーションセンター Java アプリケーション脆弱性事例解説資料 MySQL Connector/J における SQL インジェクションの脆弱性 https://www.jpcert.or.jp/research/materials-java-casestudies/No.4_MySQL_Connector.pdf 本資料を引用・転載・再配布をする際は、引用先文書、時期、内容等の情報を、JPCERT コーディ ネーションセンター広報(office@jpcert.or.jp)までメールにてお知らせください。なお、この連絡に より取得した個人情報は、別途定めるJPCERT コーディネーションセンターの「プライバシーポリ シー」に則って取り扱います。 本資料の利用方法等に関するお問い合わせ JPCERTコーディネーションセンター 広報担当 E-mail:office@jpcert.or.jp 36 本資料の技術的な内容に関するお問い合わせ JPCERTコーディネーションセンター セキュアコーディング担当 E-mail:secure-coding@jpcert.or.jp