这个简单的字符串转义可以防止任何 SQL 注入吗?
Can this simple String escaping prevent any SQL Injections?
我在一家公司工作,该公司负责数据库模块的人员严格反对使用准备好的语句。我担心他的实施不安全。
这是我们目前用来进行 SQL 查询的代码(Java 8 Application with JDBC/MySQL 5.5):
String value = "Raw user input over HTTP-Form";
String sql = "SELECT * FROM db1.articles WHERE title like '" +
replaceSingleQuotes(value) + "'";
executeSQL(sql);
public static String replaceSingleQuotes(String value) {
value = value.replaceAll("\\", "\\\\");
return value.replaceAll("'", "\\'");
}
我无法想出任何注射方法,但他的解决方案对我来说似乎很可疑。谁能指出如何规避这种转义?如果我无法提出任何建议,他不会更换他的代码,而且我们的应用程序(银行)中有成千上万客户的非常敏感的信息。
编辑:
不幸的是,我无法显示 executeSQL(),因为巨大的 class 层次结构一团糟,所有内容都分散了。但它归结为这样的事情:
String query = ... // query escaped with the above function
java.sql.Connection connection = ...
Statement stmt = connection.createStatement();
stmt.executeUpdate(query);
一种攻击方法是 "loading" 攻击。
首先,您将用户名、银行转账消息等注入其中
transfer 0.01
to: 02020.020202.200202
name: johnny tables';drop table foobar --
将转义为
johnny tables\';drop table foobar --
到目前为止一切顺利。保护有效。我们的附加失败。我们尝试加载攻击。
现在我们要做一个预定的付款订单。
这是假设犯了一个常见错误,一旦插入数据库,该值是 "safe" 因为它已经被检查过一次。
transfer 0.01
to: 02020.020202.200202
name: johnny tables';drop table foobar--
schedule: 1 day from now
在数据库中存储订单
'johnny tables\';drop table foobar--'
将存储为
johnny tables';drop table foobar--
现在午夜时分,调度程序启动并开始迭代预定的付款
select name from scheduled where time > x and < y
所以银行代码开始处理
String name = result['name'];
String acct = result['acct'];
String amt = result['amt'];
string query = "insert into payment_process (name,acct,amt) values('"+name+"','"+acct+"','"+amt+"');
砰的一声,你的 table 掉线了。 *
当你走手动路线时,你必须确保所有,每一个变量实例都被转义,所有 unicode 字符都被考虑在内,数据库引擎的所有特殊性都被考虑在内。
此外,使用准备好的语句可以显着提高速度,因为您不必重建查询。您可以只构建一次,将它们存储在缓存中,然后换出参数。
特别是在迭代大型列表时,它们是天赐之物。
根本问题是他可能不理解准备好的语句,不得到它们是如何工作的。触发的不安全感可以使某种方式具有攻击性和保护性,甚至狂热,只是为了防止承认你只是不知道它们是如何工作的。
试着和他谈谈,如果他不想听他的经理解释这个问题,如果 site/app 被黑了,这将由你的 co-worker 和你的经理,并告诉他风险是巨大的。指出最近的黑客攻击,其中大量资金被盗,例如 swift 黑客攻击。
*
可能实际上不起作用,取决于实际查询、连接、联合等。这是一个非常简化的示例
我在一家公司工作,该公司负责数据库模块的人员严格反对使用准备好的语句。我担心他的实施不安全。
这是我们目前用来进行 SQL 查询的代码(Java 8 Application with JDBC/MySQL 5.5):
String value = "Raw user input over HTTP-Form";
String sql = "SELECT * FROM db1.articles WHERE title like '" +
replaceSingleQuotes(value) + "'";
executeSQL(sql);
public static String replaceSingleQuotes(String value) {
value = value.replaceAll("\\", "\\\\");
return value.replaceAll("'", "\\'");
}
我无法想出任何注射方法,但他的解决方案对我来说似乎很可疑。谁能指出如何规避这种转义?如果我无法提出任何建议,他不会更换他的代码,而且我们的应用程序(银行)中有成千上万客户的非常敏感的信息。
编辑: 不幸的是,我无法显示 executeSQL(),因为巨大的 class 层次结构一团糟,所有内容都分散了。但它归结为这样的事情:
String query = ... // query escaped with the above function
java.sql.Connection connection = ...
Statement stmt = connection.createStatement();
stmt.executeUpdate(query);
一种攻击方法是 "loading" 攻击。
首先,您将用户名、银行转账消息等注入其中
transfer 0.01
to: 02020.020202.200202
name: johnny tables';drop table foobar --
将转义为
johnny tables\';drop table foobar --
到目前为止一切顺利。保护有效。我们的附加失败。我们尝试加载攻击。
现在我们要做一个预定的付款订单。
这是假设犯了一个常见错误,一旦插入数据库,该值是 "safe" 因为它已经被检查过一次。
transfer 0.01
to: 02020.020202.200202
name: johnny tables';drop table foobar--
schedule: 1 day from now
在数据库中存储订单
'johnny tables\';drop table foobar--'
将存储为
johnny tables';drop table foobar--
现在午夜时分,调度程序启动并开始迭代预定的付款
select name from scheduled where time > x and < y
所以银行代码开始处理
String name = result['name'];
String acct = result['acct'];
String amt = result['amt'];
string query = "insert into payment_process (name,acct,amt) values('"+name+"','"+acct+"','"+amt+"');
砰的一声,你的 table 掉线了。 *
当你走手动路线时,你必须确保所有,每一个变量实例都被转义,所有 unicode 字符都被考虑在内,数据库引擎的所有特殊性都被考虑在内。
此外,使用准备好的语句可以显着提高速度,因为您不必重建查询。您可以只构建一次,将它们存储在缓存中,然后换出参数。
特别是在迭代大型列表时,它们是天赐之物。
根本问题是他可能不理解准备好的语句,不得到它们是如何工作的。触发的不安全感可以使某种方式具有攻击性和保护性,甚至狂热,只是为了防止承认你只是不知道它们是如何工作的。
试着和他谈谈,如果他不想听他的经理解释这个问题,如果 site/app 被黑了,这将由你的 co-worker 和你的经理,并告诉他风险是巨大的。指出最近的黑客攻击,其中大量资金被盗,例如 swift 黑客攻击。
*
可能实际上不起作用,取决于实际查询、连接、联合等。这是一个非常简化的示例