当前位置:网站首页>How MySQL's allowMultiQueries flag relates to JDBC and jOOQ
How MySQL's allowMultiQueries flag relates to JDBC and jOOQ
2022-07-31 11:17:00 【DebugUsery】
MySQL的JDBC连接器There is a security feature,叫做 [allowMultiQueries](https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-security.html)``false当关闭时,It prevent throughJDBC使用MySQLA useful but potentially dangerous in function.
try (Statement s = connection.createStatement()) {
try {
s.execute("create table t (i int);");
// This doesn't work, by default:
s.executeUpdate(""" insert into t values (1); insert into t values (2); """);
}
finally {
s.execute("drop table t");
}
}
复制代码在默认情况下,The above content will produce a grammar mistakes.
Exception in thread "main" java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insert into t values (2)' at line 2
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1333)
at com.mysql.cj.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2106)
at com.mysql.cj.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1243)
at org.jooq.testscripts.JDBC.main(JDBC.java:34)
复制代码除非我们在JDBC连接URL中打开allowMultiQueries=true ,Otherwise we can't chain statements like this.
jdbc:mysql://localhost/test?allowMultiQueries=true
而现在,突然间,Statement batch normal finished,Two records are inserted into the table.
Why has this function?
The security features help prevent一些SQL注入漏洞.Harder to additional statements now,One thousand do you have a series of bad idea,比如说,你的字符串.
// Terrible idea:
s.executeUpdate("insert into t values (" + value + ")");
复制代码因为,如果value 包含字符串"1); drop table t;" 呢?这在语法上是正确的,所以它将 "按预期 "执行. It is not very good.
Now don't have a false sense of security.Turn off this feature does not prevent allSQL注入漏洞.Just let this particular hole harder.There are still different ways,This lack of use of bind variables will cause the attacker to read your data,例如,通过Based on the time of attack.
SQLThe injection of risk needs to be taken seriously.The best solution is to always write with bind variables staticSQL(例如:
PreparedStatement、存储过程或jOOQ),或者用jOOQ这样的SQLThe generator to write dynamicSQL.
在jOOQ中使用allowMultiQueries
在使用jOOQ时,The above situation is difficult to happen.jOOQThe default usage is to use.
- The code generator toGenerate database metadata
- DSL生成SQL
只有在极少数情况下,You can use普通的SQL模板来解决jOOQThe specific function shortage problem,在这种情况下,Template language will help you avoid series string and metSQL注入漏洞.
If you are the kind of person who carefully,你可以In your building中添加一个注释处理器,防止在jOOQ中使用普通的SQL API(Any use will not be the default compiler,Unless you explicitly selection).
所以,MySQLLogo for youjOOQUse is not really useful.事实上,It is even a problem,因为jOOQInternal relies on the generated as described above statement batch.Here are some when you closeallowMultiQueries=false When not working function(Most of them can also be applied toMariaDB,btw).
GROUP_CONCAT
每当你在MySQL的jOOQ中使用GROUP_CONCAT ,jOOQWill assume that you haven't changeMySQL的默认值为 [@@group_concat_max_length](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_group_concat_max_len).The default value is very low,即1024 .And this value is not only to prevent large data sets string polymerization,And just silently fail,This leads to the value of the error!
当使用GROUP_CONCAT 在MySQL中模拟JSON_ARRAYAGG() ,在产生的JSONArrays are commonly have a detectable grammar mistakes,But when you just want to have some string value,For example, when a comma-separated list of,情况就不是这样了.(See the previous blog,Why don't we also use the localJSON_ARRAYAGG() 支持).
所以,Every time you useGROUP_CONCAT (或者jOOQIn the internal use it some simulation)时,jOOQWill do is preset and attach the following statement.
-- These are prepended
SET @t = @@group_concat_max_len;
SET @@group_concat_max_len = 4294967295;
-- Actual statement here:
SELECT group_concat(A SEPARATOR ',') FROM T;
-- These are appended
SET @@group_concat_max_len = @t;
复制代码If you have fixed the system or session variable,你可以通过改变Settings.renderGroupConcatMaxLenSessionVariable Sign to close the function.
Create or replace function
许多SQLDialects of the stored procedure、函数、The trigger and the other does not contain data storage object has aCREATE OR REPLACE 语法.This is a very useful syntactic sugar,Used to write this,而不是.
-- Much simpler
CREATE OR REPLACE FUNCTION f ...
-- Than this
DROP FUNCTION IF EXISTS f;
CREATE FUNCTION f ...
复制代码但同样的,如果你关闭了allowMultiQueries=false ,那么jOOQIn this simulation can't work,You will get a grammar mistakes.在这里,jOOQCan do nothing to help you.You must manually run the two statements,Instead of using the convenient syntax.
FOR UPDATE WAIT n
Many dialects are aFOR UPDATE WAIT n 语法,Allow for the pessimistic locks to specify aWAIT 超时,例如:
SELECT *
FROM t
FOR UPDATE WAIT n;
复制代码MySQL 8.0.26还不支持这个功能,但自从jOOQ 3.15和#11543以来,We are using this syntax to simulate the grammar.
SET @t = @@innodb_lock_wait_timeout;
SET @@innodb_lock_wait_timeout = 2;
SELECT *
FROM t
FOR UPDATE;
SET @@innodb_lock_wait_timeout = @t;
复制代码另一件事是,If you have the following situation will not be able to workallowMultiQueries=false
匿名块
Many procedural language supports procedural code of anonymous block,Is not stored in the procedural code in the process of.这是很有意义的.毕竟,We also do not have to keep all theSQLStored in the view,So why should we willPL/SQL、T-SQL、PL/pgSQLStored in the storage process such as?Especially when you want to dynamically generate the block,这可能非常有用,使用jOOQOn the server rather than on the client side run some logic,减少往返次数.
在Oracle中,你可以写.
BEGIN
INSERT INTO t VALUES (1);
IF TRUE THEN
INSERT INTO t VALUES (2);
END IF;
END;
复制代码jOOQ从3.12To support this anonymous block.看看关于IF Statement of the manual page.你可以写
// Assuming the usual static imports:
import static org.jooq.impl.DSL.*;
import static org.jooq.impl.SQLDataType;
// Then write:
Variable<Integer> i = var("i", INTEGER);
ctx.begin(
declare(i).set(1),
if_(i.eq(0)).then(
insertInto(A).columns(A.COL).values(1)
).elsif(i.eq(1)).then(
insertInto(B).columns(B.COL).values(2)
).else_(
insertInto(C).columns(C.COL).values(3)
)
).execute();
复制代码This in those in favor of the anonymous block dialect translation into and execute the correct process of anonymous block,但不幸的是,MySQL 8.0.26还不支持,那么我们该怎么做?我们生成一个 "匿名 "过程,调用它,And then again to give up.
CREATE PROCEDURE block_1629705082441_2328258()
BEGIN
DECLARE i INT;
SET i = 1;
IF i = 0 THEN
INSERT INTO a (col) VALUES (1);
ELSEIF i = 1 THEN
INSERT INTO b (col) VALUES (2);
ELSE
INSERT INTO c (col) VALUES (3);
END IF;
END;
CALL block_1629705082441_2328258();
DROP PROCEDURE block_1629705082441_2328258;
复制代码我的意思是,为什么不呢?但是,这又依赖于allowMultiQueries=true ,否则,JDBCThe driver will refuse this statement.
关于jOOQThe procedural languageAPI的更多信息,请参考: https://blog.jooq.org/vendor-agnostic-dynamic-procedural-logic-with-jooq/
结论
MySQL的JDBCDrivers have a very good security features,Designed to prevent someSQL注入的情况,Especially when the users useJDBCConnection manualSQL执行时.The team there is always a poor people don't knowSQL注入,So wrong,打开了潘多拉的盒子.For these purposes,allowMultiQueries=false 是一个合理的默认值.
当按照jOOQThe intent to usejOOQ时,SQLThe possibility of injection to小得多 .This does not include pureSQL模板的使用,But this article does not apply.另一方面,jOOQ内部依靠allowMultiQueries=true ,In order to realize some need to perform multiple statements in a roundtrip simulation.
未来的jOOQVersion will allow configuration more query execution model,To make the above situation can be used as many times perform.更多细节见#9645.
在此之前,如果你想从jOOQ和MySQLGet the most benefits,请确保在你的jOOQConnected to the openallowMultiQueries=true ,May remain closed elsewhere.
边栏推荐
- 分布式id解决方案
- Creation of doubly linked list
- 《JUC并发编程 - 高级篇》06 - 共享模型之不可变(不可变类的设计 | 不可变类的使用 | 享元模式)
- Use jOOQ to write vendor-agnostic SQL with JPA's native query or @Formula.
- If the value of the enum map does not exist, deserialization is not performed
- Deletion of the sequence table
- 掌握SSR
- In PLC communication error or timeout or download the prompt solution of the model
- IDEA configure method annotation automatic parameters
- Implement the popup component
猜你喜欢

AWS亚马逊云账号注册,免费申请12个月亚马逊云服务器详细教程

拥抱趋势!阿里这套微服务开源框架权威手册,实战到底层细致清晰

透过开发抽奖小程序,体会创新与迭代

【虚拟化生态平台】树莓派安装虚拟化平台操作流程

Initial JDBC programming

Master SSR

线程池 ThreadPoolExecutor 详解

5 个开源的 Rust Web 开发框架,你选择哪个?

IDEA configure method annotation automatic parameters

Android studio connects to MySQL and completes simple login and registration functions
随机推荐
Sql optimization summary!detailed!(Required for the latest interview in 2021)
Summary of several defragmentation schemes for MySQL (to solve the problem of not releasing space after deleting a large amount of data)
MySQL 行级锁(行锁、临键锁、间隙锁)
Experience innovation and iteration through the development of a lucky draw applet
Windows安装mysql详细步骤(通俗易懂,简单上手)
Three-tier architecture service, dao, controller layer
2022/7/30
Yarn安装配置(vsftpd安装配置)
pycharm汉化教程(碧蓝幻想汉化插件安装)
MySQL limit paging query and performance issues
deeplab implements its own remote sensing geological segmentation dataset
5 个开源的 Rust Web 开发框架,你选择哪个?
Threading(in thread main)
Acwing-考研机试题
【虚拟化生态平台】平台架构图&思路和实现细节
v-model的原理
内网渗透学习(四)域横向移动——SMB和WMI服务利用
502 bad gateway causes and solutions
Inversion problem - key point
IDEA 配置方法注释自动参数