简体   繁体   English

转义 Java 变量以将 SQL 语句序列化为字符串

[英]Escaping Java variables to serialise SQL statement to string

We have an event system producing database events for change data capture.我们有一个事件系统,为变更数据捕获生成数据库事件。

The system sends an event which contains the INSERT or UPDATE statement with ?系统发送一个包含 INSERT 或 UPDATE 语句的事件? placeholders and an array of the ordered values matching each question mark.占位符和与每个问号匹配的有序值数组。

I want to use this for per hour backup files so if I get a statement like:我想将它用于每小时备份文件,所以如果我得到如下语句:

insert into T0(a,b,c) VALUES(?,?,?)

with an array of values 1 , 2 and it's his then I write the a line to the backup file for that hour as具有值12的数组, it's his然后我将一行写入该小时的备份文件中

insert into T0(a,b,c) VALUES(1,2,'it\\'s his');

A few things:一些东西:

  1. Is it only strings that need escaping?只有字符串需要转义吗? We don't have or allow binary columns我们没有或允许使用二进制列
  2. Is there a Java library that can do this already (from the Spring eco-system, Apache or otherwise)?是否有一个 Java 库可以做到这一点(来自 Spring 生态系统、Apache 或其他)?
  3. I've seen the Postgres JDBC code for escaping https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/core/Utils.java - is that sufficient?我已经看到了用于转义https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/core/Utils.java的 Postgres JDBC 代码 - 这足够了吗?

I was also thinking of creating a SQLite database for each hour, writing to SQLite and then dumping it to the hr.sql text file.我还考虑每小时创建一个 SQLite 数据库,写入 SQLite,然后将其转储到hr.sql文本文件。 This has the advantage of capitalising on all the hardwork and thought already put into SQLite handling escaping but feels like overkill if there's a way to do the toString in Java then append a line to the file.这具有充分利用 SQLite 处理转义的所有辛勤工作和思想的优势,但如果有一种方法可以在 Java 中执行 toString 然后将一行附加到文件中,则感觉有点矫枉过正。

There's a performance consideration in using SQLite as well furthering my hesitation to that that route.使用 SQLite 有一个性能方面的考虑,也让我对那条路线犹豫不决。

Found some options.找到了一些选项。

Postgres JDBC driver is this https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/core/Utils.java and other impl. Postgres JDBC 驱动程序是这个https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/core/Utils.java和其他 impl。 is even more simple https://github.com/p6spy/p6spy/blob/master/src/main/java/com/p6spy/engine/common/Value.java#L172 literally doing更简单https://github.com/p6spy/p6spy/blob/master/src/main/java/com/p6spy/engine/common/Value.java#L172字面上做

ESPECIAL_CHARACTER_PATTERN.matcher(stringValue).replaceAll("''")

Where private static final Pattern ESPECIAL_CHARACTER_PATTERN = Pattern.compile("'");其中private static final Pattern ESPECIAL_CHARACTER_PATTERN = Pattern.compile("'");

In both cases, only strings need this as I thought and binary is handled separately but we don't have/need binary.在这两种情况下,只有字符串需要这个,因为我认为二进制是单独处理的,但我们没有/需要二进制。

Digging further I rediscovered ESAPI https://github.com/ESAPI/esapi-java-legacy They have a lib for escaping SQL https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html#defense-option-4-escaping-all-user-supplied-input进一步挖掘我重新发现了 ESAPI https://github.com/ESAPI/esapi-java-legacy他们有一个用于转义 SQL 的库https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html#defense-option-4-escaping -所有用户提供的输入

https://github.com/ESAPI/esapi-java-legacy/blob/develop/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java https://github.com/ESAPI/esapi-java-legacy/blob/develop/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM