Projects
Eulaceura:Factory
hibernate4
_service:obs_scm:CVE-2020-25638.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:CVE-2020-25638.patch of Package hibernate4
From 59fede7acaaa1579b561407aefa582311f7ebe78 Mon Sep 17 00:00:00 2001 From: Andrea Boriero <andrea@hibernate.org> Date: Tue, 29 Sep 2020 20:56:30 +0100 Subject: [PATCH] HHH-14225 CVE-2020-25638 Potential for SQL injection on use_sql_comments logging enabled --- .../java/org/hibernate/dialect/Dialect.java | 12 ++ .../internal/SelectStatementBuilder.java | 2 +- .../main/java/org/hibernate/sql/Delete.java | 4 +- .../main/java/org/hibernate/sql/Insert.java | 2 +- .../java/org/hibernate/sql/InsertSelect.java | 2 +- .../java/org/hibernate/sql/QuerySelect.java | 4 +- .../main/java/org/hibernate/sql/Select.java | 2 +- .../java/org/hibernate/sql/SimpleSelect.java | 2 +- .../main/java/org/hibernate/sql/Update.java | 2 +- .../hibernate/test/comments/TestEntity.java | 46 ++++++++ .../hibernate/test/comments/TestEntity2.java | 37 ++++++ .../test/comments/UseSqlCommentTest.java | 111 ++++++++++++++++++ 12 files changed, 218 insertions(+), 8 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/comments/TestEntity.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/comments/TestEntity2.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/comments/UseSqlCommentTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 77fced7..1d42347 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -94,6 +94,7 @@ import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.regex.Pattern; /** * Represents a dialect of SQL implemented by a particular RDBMS. Subclasses implement Hibernate compatibility @@ -129,6 +130,9 @@ public abstract class Dialect implements ConversionContext { */ public static final String CLOSED_QUOTE = "`\"]"; + private static final Pattern ESCAPE_CLOSING_COMMENT_PATTERN = Pattern.compile( "\\*/" ); + private static final Pattern ESCAPE_OPENING_COMMENT_PATTERN = Pattern.compile( "/\\*" ); + private final TypeNames typeNames = new TypeNames(); private final TypeNames hibernateTypeNames = new TypeNames(); @@ -2723,4 +2727,12 @@ public abstract class Dialect implements ConversionContext { return StandardCallableStatementSupport.NO_REF_CURSOR_INSTANCE; } + public static String escapeComment(String comment) { + if ( StringHelper.isNotEmpty( comment ) ) { + final String escaped = ESCAPE_CLOSING_COMMENT_PATTERN.matcher( comment ).replaceAll( "*\\\\/" ); + return ESCAPE_OPENING_COMMENT_PATTERN.matcher( escaped ).replaceAll( "/\\\\*" ); + } + return comment; + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/query/internal/SelectStatementBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/query/internal/SelectStatementBuilder.java index cbddf7c..b0c02bf 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/query/internal/SelectStatementBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/query/internal/SelectStatementBuilder.java @@ -204,7 +204,7 @@ public class SelectStatementBuilder { final StringBuilder buf = new StringBuilder( guesstimatedBufferSize ); if ( StringHelper.isNotEmpty( comment ) ) { - buf.append( "/* " ).append( comment ).append( " */ " ); + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); } buf.append( "select " ) diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Delete.java b/hibernate-core/src/main/java/org/hibernate/sql/Delete.java index faec336..f03ce52 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/Delete.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/Delete.java @@ -27,6 +27,8 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; +import org.hibernate.dialect.Dialect; + /** * An SQL <tt>DELETE</tt> statement * @@ -54,7 +56,7 @@ public class Delete { public String toStatementString() { StringBuilder buf = new StringBuilder( tableName.length() + 10 ); if ( comment!=null ) { - buf.append( "/* " ).append(comment).append( " */ " ); + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); } buf.append( "delete from " ).append(tableName); if ( where != null || !primaryKeyColumns.isEmpty() || versionColumnName != null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Insert.java b/hibernate-core/src/main/java/org/hibernate/sql/Insert.java index 90788e2..aef545f 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/Insert.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/Insert.java @@ -108,7 +108,7 @@ public class Insert { public String toStatementString() { StringBuilder buf = new StringBuilder( columns.size()*15 + tableName.length() + 10 ); if ( comment != null ) { - buf.append( "/* " ).append( comment ).append( " */ " ); + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); } buf.append("insert into ") .append(tableName); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/InsertSelect.java b/hibernate-core/src/main/java/org/hibernate/sql/InsertSelect.java index 37bda69..992595b 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/InsertSelect.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/InsertSelect.java @@ -80,7 +80,7 @@ public class InsertSelect { StringBuilder buf = new StringBuilder( (columnNames.size() * 15) + tableName.length() + 10 ); if ( comment!=null ) { - buf.append( "/* " ).append( comment ).append( " */ " ); + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); } buf.append( "insert into " ).append( tableName ); if ( !columnNames.isEmpty() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/QuerySelect.java b/hibernate-core/src/main/java/org/hibernate/sql/QuerySelect.java index 9e25025..8237329 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/QuerySelect.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/QuerySelect.java @@ -134,7 +134,9 @@ public class QuerySelect { public String toQueryString() { StringBuilder buf = new StringBuilder(50); - if (comment!=null) buf.append("/* ").append(comment).append(" */ "); + if (comment!=null) { + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); + } buf.append("select "); if (distinct) buf.append("distinct "); String from = joins.toFromFragmentString(); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Select.java b/hibernate-core/src/main/java/org/hibernate/sql/Select.java index 2b67c9b..88868ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/Select.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/Select.java @@ -58,7 +58,7 @@ public class Select { public String toStatementString() { StringBuilder buf = new StringBuilder(guesstimatedBufferSize); if ( StringHelper.isNotEmpty(comment) ) { - buf.append("/* ").append(comment).append(" */ "); + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); } buf.append("select ").append(selectClause) diff --git a/hibernate-core/src/main/java/org/hibernate/sql/SimpleSelect.java b/hibernate-core/src/main/java/org/hibernate/sql/SimpleSelect.java index d8d49aa..ab5dafa 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/SimpleSelect.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/SimpleSelect.java @@ -155,7 +155,7 @@ public class SimpleSelect { ); if ( comment!=null ) { - buf.append("/* ").append(comment).append(" */ "); + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); } buf.append("select "); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Update.java b/hibernate-core/src/main/java/org/hibernate/sql/Update.java index d49eb5e..8d6d159 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/Update.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/Update.java @@ -180,7 +180,7 @@ public class Update { public String toStatementString() { StringBuilder buf = new StringBuilder( (columns.size() * 15) + tableName.length() + 10 ); if ( comment!=null ) { - buf.append( "/* " ).append( comment ).append( " */ " ); + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); } buf.append( "update " ).append( tableName ).append( " set " ); boolean assignmentsAppended = false; diff --git a/hibernate-core/src/test/java/org/hibernate/test/comments/TestEntity.java b/hibernate-core/src/test/java/org/hibernate/test/comments/TestEntity.java new file mode 100644 index 0000000..7c425be --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/comments/TestEntity.java @@ -0,0 +1,46 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. + */ +package org.hibernate.test.comments; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Andrea Boriero + */ +@Entity +public class TestEntity { + @Id + private String id; + + private String value; + + public TestEntity() { + + } + + public TestEntity(String id, String value) { + this.id = id; + this.value = value; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/comments/TestEntity2.java b/hibernate-core/src/test/java/org/hibernate/test/comments/TestEntity2.java new file mode 100644 index 0000000..58b626d --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/comments/TestEntity2.java @@ -0,0 +1,37 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. + */ +package org.hibernate.test.comments; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Andrea Boriero + */ +@Entity +public class TestEntity2 { + @Id + private String id; + + private String value; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/comments/UseSqlCommentTest.java b/hibernate-core/src/test/java/org/hibernate/test/comments/UseSqlCommentTest.java new file mode 100644 index 0000000..2bd6adf --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/comments/UseSqlCommentTest.java @@ -0,0 +1,111 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. + */ +package org.hibernate.test.comments; + +import java.util.List; +import java.util.Map; +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CompoundSelection; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Path; +import javax.persistence.criteria.Root; + +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; +import static org.junit.Assert.assertThat; + +/** + * @author Andrea Boriero + */ +public class UseSqlCommentTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class<?>[] getAnnotatedClasses() { + return new Class[] { TestEntity.class, TestEntity2.class }; + } + + @Override + protected void addMappings(Map settings) { + settings.put( AvailableSettings.USE_SQL_COMMENTS, "true" ); + settings.put( AvailableSettings.FORMAT_SQL, "false" ); + } + + @Before + public void setUp() { + doInJPA( this::entityManagerFactory, entityManager -> { + TestEntity testEntity = new TestEntity(); + testEntity.setId( "test1" ); + testEntity.setValue( "value1" ); + entityManager.persist( testEntity ); + + TestEntity2 testEntity2 = new TestEntity2(); + testEntity2.setId( "test2" ); + testEntity2.setValue( "value2" ); + entityManager.persist( testEntity2 ); + } ); + } + + @Test + public void testIt() { + String appendLiteral = "*/select id as col_0_0_,value as col_1_0_ from testEntity2 where 1=1 or id=?--/*"; + doInJPA( this::entityManagerFactory, entityManager -> { + + List<TestEntity> result = findUsingQuery( "test1", appendLiteral, entityManager ); + + TestEntity test1 = result.get( 0 ); + assertThat( test1.getValue(), is( appendLiteral ) ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + + List<TestEntity> result = findUsingCriteria( "test1", appendLiteral, entityManager ); + + TestEntity test1 = result.get( 0 ); + assertThat( test1.getValue(), is( appendLiteral ) ); + } ); + } + + public List<TestEntity> findUsingCriteria(String id, String appendLiteral, EntityManager entityManager) { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery<TestEntity> criteria = builder.createQuery( TestEntity.class ); + Root<TestEntity> root = criteria.from( TestEntity.class ); + + Path<Object> idPath = root.get( "id" ); + CompoundSelection<TestEntity> selection = builder.construct( + TestEntity.class, + idPath, + builder.literal( appendLiteral ) + ); + criteria.select( selection ); + + criteria.where( builder.equal( idPath, builder.parameter( String.class, "where_id" ) ) ); + + TypedQuery<TestEntity> query = entityManager.createQuery( criteria ); + query.setParameter( "where_id", id ); + return query.getResultList(); + } + + public List<TestEntity> findUsingQuery(String id, String appendLiteral, EntityManager entityManager) { + TypedQuery<TestEntity> query = + entityManager.createQuery( + "select new org.hibernate.test.comments.TestEntity(id, '" + + appendLiteral.replace( "'", "''" ) + + "') from TestEntity where id=:where_id", + TestEntity.class + ); + query.setParameter( "where_id", id ); + return query.getResultList(); + } +} -- 2.23.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2