Skip to content

Commit

Permalink
Backpatch changes for 42.2.25 (#2581)
Browse files Browse the repository at this point in the history
* Backpatch changes for 42.2.25

* fixed test to compile for 42.2.x
  • Loading branch information
davecramer committed Aug 3, 2022
1 parent 01836f2 commit b5ee575
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
13 changes: 7 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ Notable changes since version 42.0.0, read the complete [History of Changes](htt
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [Unreleased]
### Changed

### Added

### Fixed

### Security
- fix: CVE-2022-31197 Fixes SQL generated in PgResultSet.refresh() to escape column identifiers so as to prevent SQL injection.
- Previously, the column names for both key and data columns in the table were copied as-is into the generated
SQL. This allowed a malicious table with column names that include statement terminator to be parsed and
executed as multiple separate commands.
- Also adds a new test class ResultSetRefreshTest to verify this change.
- Reported by [Sho Kato](https://github.com/kato-sho)

## [42.2.24] (2021-09-23)
### Fixed
Expand Down
5 changes: 3 additions & 2 deletions pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,7 @@ public void refreshRow() throws SQLException {
if (i > 1) {
selectSQL.append(", ");
}
selectSQL.append(pgmd.getBaseColumnName(i));
Utils.escapeIdentifier(selectSQL, pgmd.getBaseColumnName(i));
}
selectSQL.append(" from ").append(onlyTable).append(tableName).append(" where ");

Expand All @@ -1333,7 +1333,8 @@ public void refreshRow() throws SQLException {
for (int i = 0; i < numKeys; i++) {

PrimaryKey primaryKey = primaryKeys.get(i);
selectSQL.append(primaryKey.name).append(" = ?");
Utils.escapeIdentifier(selectSQL, primaryKey.name);
selectSQL.append(" = ?");

if (i < numKeys - 1) {
selectSQL.append(" and ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
ReplaceProcessingTest.class,
ResultSetMetaDataTest.class,
ResultSetTest.class,
ResultSetRefreshTest.class,
ReturningParserTest.class,
SearchPathLookupTest.class,
ServerCursorTest.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2022, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/

package org.postgresql.test.jdbc2;

import static org.junit.Assert.assertTrue;

import org.postgresql.test.TestUtil;

import org.junit.Test;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ResultSetRefreshTest extends BaseTest4 {
@Test
public void testWithDataColumnThatRequiresEscaping() throws Exception {
TestUtil.dropTable(con, "refresh_row_bad_ident");
TestUtil.execute("CREATE TABLE refresh_row_bad_ident (id int PRIMARY KEY, \"1 FROM refresh_row_bad_ident; SELECT 2; SELECT *\" int)", con);
TestUtil.execute( "INSERT INTO refresh_row_bad_ident (id) VALUES (1), (2), (3)", con);

Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT * FROM refresh_row_bad_ident");
assertTrue(rs.next());
try {
rs.refreshRow();
} catch (SQLException ex) {
throw new RuntimeException("ResultSet.refreshRow() did not handle escaping data column identifiers", ex);
}
rs.close();
stmt.close();
}

@Test
public void testWithKeyColumnThatRequiresEscaping() throws Exception {
TestUtil.dropTable(con, "refresh_row_bad_ident");
TestUtil.execute("CREATE TABLE refresh_row_bad_ident (\"my key\" int PRIMARY KEY)", con);
TestUtil.execute( "INSERT INTO refresh_row_bad_ident VALUES (1), (2), (3)", con);

Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT * FROM refresh_row_bad_ident");
assertTrue(rs.next());
try {
rs.refreshRow();
} catch (SQLException ex) {
throw new RuntimeException("ResultSet.refreshRow() did not handle escaping key column identifiers", ex);
}
rs.close();
stmt.close();
}
}

0 comments on commit b5ee575

Please sign in to comment.