Bug #41730 SQL Injection when using U+00A5
| Submitted: | 24 Dec 2008 11:11 | Modified: | 26 May 2009 10:45 |
|---|---|---|---|
| Reporter: | Sadao Hiratsuka (Basic Quality Contributor) | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | Connector / J | Severity: | S1 (Critical) |
| Version: | 5.1.7 | OS: | Any |
| Assigned to: | Jess Balint | CPU Architecture: | Any |
| Tags: | Connector/J | ||
[26 Dec 2008 2:25]
Sadao Hiratsuka
After post, I learned that escaping U+00A5 thoughtlessly has side effects. Now suggested fix I think is: validate characters *after* converting them to 'characterEncoding'.
[26 Dec 2008 4:45]
Yoshinori Matsunobu
I wrote a prototype patch.
PreparedStatement#setString()
......
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');
......
default:
//add the following
String characterEncoding = this.connection.getEncoding();
try{
if(characterEncoding != null &&
String.valueOf(c).getBytes(characterEncoding)[0] == 0x5c){
buf.append('\\');
buf.append('\\');
}else {
buf.append(c);
}
}catch(UnsupportedEncodingException e){}
break;
......
or
case '\u00a5':
String characterEncoding = this.connection.getEncoding();
try{
if(characterEncoding != null &&
String.valueOf(c).getBytes(characterEncoding)[0] == 0x5c){
buf.append('\\');
buf.append('\\');
}
}catch(UnsupportedEncodingException e){}
break;
We need to care about not only U+00A5, but also U+20A9 and possibly others...
[19 Feb 2009 7:28]
Tonci Grgin
Sadao, Yoshinori, we are having internal discussion about this bug and it's not forgotten. Thanks.
[24 Feb 2009 3:14]
Jess Balint
fix + test
Attachment: bug41730.diff (text/x-diff), 3.98 KiB.
[15 May 2009 22:46]
Jess Balint
Pushed as rev 792. Will be released in 5.1.8.
[26 May 2009 10:45]
Tony Bedford
An entry has been added to the 5.1.8 changelog: SQL injection was possible when using a string containing U+00A5 in a client-side prepared statement, and the character set being used was SJIS/Windows-31J.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.056 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: SQL Injection occurs when - using Connector/J - client-side Prepared Statement - String has U+00A5 - characterEncoding is not UTF-8 How to repeat: MySQL Server 5.1.30 Connector/J 5.1.7 - sample data mysql> select empno, ename from emp; +-------+--------+ | empno | ename | +-------+--------+ | 7369 | smith | | 7499 | allen | | 7521 | ward | | 7566 | jones | | 7654 | martin | | 7698 | blake | | 7782 | clark | | 7788 | scott | | 7839 | king | | 7844 | turner | | 7876 | adams | | 7900 | james | | 7902 | ford | | 7934 | miller | +-------+--------+ 14 rows in set (0.00 sec) - sample code import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class InjectionTest { public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/scott?characterEncoding=Windows-31J", "scott", "tiger"); PreparedStatement pstmt = conn.prepareStatement("select empno from emp where ename = ?"); pstmt.setString(1, "\u00a5' or 1 = 1#"); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { System.out.println(rs.getInt(1)); } rs.close(); pstmt.close(); conn.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } - results 7369 7499 7521 7566 7654 7698 7782 7788 7839 7844 7876 7900 7902 7934 Suggested fix: escape U+00A5 suitably.