在Java中转义SQL字符串

背景:

我目前正在为企业CMS数据库(Business Objects)开发Java前端。 目前,我正在构建一个function,允许用户构建自定义数据库查询。 我已经实施了一些措施来确保用户只能使用已批准用户访问的可用列和运算符的子集进行选择(例如,可以选择SI_EMAIL_ADDRESS,而不能使用更强大的字段,如SI_CUID)。 到目前为止,事情一直在流行,但现在是时候保护这个function免受潜在的SQL注入攻击。

问题:

我正在寻找一种方法来逃避用户输入字符串。 我已经看过PerparedStatement,但是我被迫使用第三方API来访问数据库。 这些API对我来说是不可变的,直接的数据库访问是不可能的。 各个方法使用表示要运行的查询的字符串,从而使PreparedStatement无效(据我所知,必须针对直接数据库连接运行)。

我考虑过使用String.replace(),但如果可能的话我不想重新发明轮子。 此外,我与开发PerparedStatement的安全专家相去甚远。

我还查看了PerparedStatement的Java API参考,希望找到某种toString()方法。 唉,我一直找不到那种东西。

任何帮助是极大的赞赏。 先谢谢你。

参考文献:

Java – 转义字符串以防止SQL注入

Java的等效PHP的mysql_real_escape_string()

当然,使用PreparedStatement会更容易,更安全。

ANSI SQL要求字符串文字以单引号开头和结尾,而单引号的唯一转义机制是使用两个单引号:

'Joe''s Caffee' 

因此理论上,您只需要用两个单引号替换单引号。 但是,存在一些问题。 首先,一些数据库(例如MySQL)也(或仅)支持反斜杠作为转义机制。 在这种情况下,您需要加倍反斜杠(以及)。

对于MySQL,我建议使用MySQLUtils 。 如果您不使用MySQL,那么您需要检查要使用的确切转义机制。

您仍然可以使用准备好的声明。 看到这篇文章: 从java sql preparedstatement获取查询 。 此外,根据该post,您可以使用Log4JDBC来处理此问题。

这两个选项中的任何一个都应该可以防止您担心转义字符串以防止SQL注入,因为准备好的语句会为您执行此操作。

虽然,在Java中没有标准的方法来处理PHP的mysql_real_escape_string()我所做的是链接replaceAll方法来处理可能需要避免任何exception的每个方面。 这是我的示例代码:

public void saveExtractedText(String group,String content) { try { content = content.replaceAll("\", "\\") .replaceAll("\n","\n") .replaceAll("\r", "\r") .replaceAll("\t", "\t") .replaceAll("\00", "\0") .replaceAll("'", "\'") .replaceAll("\"", "\\"");

  state.execute("insert into extractiontext(extractedtext,extractedgroup) values('"+content+"','"+group+"')"); } catch (Exception e) { e.printStackTrace(); }