[opensuse-security] SQL injection attack possible when connecting to PostgreSQL 9.1 with version 8.1 JDBC driver
Hi, when using PostgreSQL JDBC driver version 8.1 to connect to a PostgreSQL version 9.1 database, escaping of JDBC statement parameters does not work and SQL injection attacks are possible. The problem can be reproduced for example with version 8.1-415 (released 2010-05-11), which still can be downloaded from the official download location (although in `Archived Section'), however this version is included in Linux distributions that are still supported (for example SuSE Linux Enterprise Edition with long-term support). Connecting Java applications from such a server to a recent PostgreSQL database, SQL injection attacks are possible. Java Web Applications using JDBC running on such Linux versions could allow to exploit this remotely, for example through a web app. Vendor reponse (from <security@postgresql.org>):
Anything not identified there as current or supported is, by reasonable inference, neither. Reporting a security bug against anything that's not current or supported is pointless.
However, such unsupported driver versions are included in supported Linux distributions. Since I think it is possible to accidentally use older (but still supported) Linux application servers against recent databases, I think a public information could be of interest. Possible fix or workaround: Do not use PostgreSQL JDBC driver version 8.1 but upgrade to most recent version. If the distribution offers no suited package (RPM), driver should be downloaded from jdbc.postgresql.org and installed manually. This breaks package management consitency but seems to be the smaller issue. How to reproduce: When the small code Postgres.java (attached) is compiled and runned with Java 1.7 and the Postgres 8.1 JDBC3 driver against a Postgres 9.1 database: $ java -cp postgresql-8.1-415.jdbc3.jar:. Postgres the following Exception occures: Exception in thread "main" org.postgresql.util.PSQLException: ERROR: syntax error at or near "(" at character 134 The driver can be downloaded under http://jdbc.postgresql.org/download/postgresql-8.1-415.jdbc3.jar In the "Archived Versions"-section of http://jdbc.postgresql.org/download.html. (They are supported anymore, but there is no hint that downloading and using them in our point of view opens a security treat, so we think this is not good) When the application is run with the Postgres 9.1 JDBC3 driver, it behaves correctly. We think it is likely that JDBC drivers with 8.1-x are still used productively, for example SuSE Linux Enterprise Edition with long-term support and we are not aware of some security bulletin telling that an upgrade is recommended for security reasons, since there might be not much interest in changing running systems without need. Regards, Steffen Dettmer ------------------------------------------------------------------->8======= * Steffen Dettmer wrote on Mon, Feb 27, 2012 at 17:36 +0100:
Hi,
we think we have found an escaping problem in JDBC driver 8.1 allowing SQL injection attacks when connecting to PostgreSQL 9.1 . According to http://jdbc.postgresql.org/changes.html#version_8.1-415, this issue is not known (not fixed). [...] Our software relys on correct parameter escaping when using a java.sql.PreparedStatement for "SELECT stored_procedure(?, ?) AS result" used with "statement.setString()" etc., which according to our understanding should be the usual and safe way to call stored procedures on PostgreSQL.
We found that it fails with at least postgresql-8.1-407.jdbc3.jar from http://jdbc.postgresql.org/download.html and Postgres 9.1 database.
The exact case where it occured in production was the query:
SELECT appendJobEvent(?, ?, ?, ?) AS result
with parameters set via "setString(pos, value)". Parameter number 4 contained single quote characters, but they should be escaped and end up in the database literally.
Instead, we get:
ERROR: syntax error at or near "(" at character 163 (ERROR: syntax error at or near "(" at character 163)'
we tested and got exactly the same error message when using the string directly (i.e. not via "?" and setString), which is expected.
Connecting to an older database version (7.1) or updating the driver to postgresql-9.1-901.jdbc3.jar from http://jdbc.postgresql.org/download.html both make the same query with the same parameters work.
Since our development environment unit tests check for a similar issue, it seems that when using the same version of JDBC driver and database (the normal configuration when having a test database on localhost), escaping probably works well in a probably wide range of versions, but not in at least this combination (8.1-407 JDBC driver to 9.1 DBMS).
--[ Postgres.java ]------------------------------------------------>8======= // "Sascha BAER" <Sascha.BAER@ingenico.com> -- SFR-1315206 // SQL injection when connecting to PostgreSQL 9.1 with version 8.1 JDBC driver import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; public class Postgres { public static void main(String[] args) throws Exception { Properties connectionProps = new Properties(); // Load postgres Driver: this is needed for 8.1 Drivers. Class jdbcDriver = Class.forName("org.postgresql.Driver"); connectionProps.put("user", "sfr1315206"); connectionProps.put("password", "secret"); // protocolVersion 2 is needed to trigger the problem. connectionProps.put("protocolVersion", "2"); Connection conn = DriverManager.getConnection( "jdbc:postgresql://pg9-test/test1315206", connectionProps); String hint = new String("com.ingenico.de.data.DataException: " + "(Bitmap 2: ( (Data exceeds format length!); " + "Producer f = `PropLLXPVar(19): null') (F1F2672191104016...)): " + "class com.ingenico.de.data.DataException (5): " + "[thrown in `consume()' at BitmapConsumer.java, line 84]"); PreparedStatement ps = conn.prepareStatement( "SELECT foo(?) AS result"); ps.setString(1, hint); ResultSet result = ps.executeQuery(); result.next(); System.out.println(result.getString(1)); } } // Configuration stuff for the emacs editor. Please don't remove // Local Variables: // tab-width: 4 // End: // Modeline for VIM. Please don't remove. // (Help: autoindent, expandtab, shiftwidth=4, tabstop=4, textwidth=75) // vi: set ai et sw=4 ts=4 tw=75: -- To unsubscribe, e-mail: opensuse-security+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-security+owner@opensuse.org
Steffen Dettmer wrote:
The problem can be reproduced for example with version 8.1-415 (released 2010-05-11), which still can be downloaded from the official download location (although in `Archived Section'), however this version is included in Linux distributions that are still supported (for example SuSE Linux Enterprise Edition with long-term support).
The SLE11 package claims to be version 8.1. However AFIACS it actually packages 8.2-506. Did you already check whether 8.2-512 has the problem fixed?
[...] Possible fix or workaround:
Do not use PostgreSQL JDBC driver version 8.1 but upgrade to most recent version. If the distribution offers no suited package (RPM), driver should be downloaded from jdbc.postgresql.org and installed manually. This breaks package management consitency but seems to be the smaller issue.
Actually better complain to the security team of the distro first and ask why there is no update :-) In this case noone knew that there is an SQL injection and AFAICT upstream didn't flag any updates as security relevant so no CVE assigned either. cu Ludwig PS: better use security@suse.de to reach the SUSE security team. opensuse-security@opensuse.org is a discussion list. -- (o_ Ludwig Nussel //\ V_/_ http://www.suse.de/ SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe, e-mail: opensuse-security+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-security+owner@opensuse.org
* Ludwig Nussel wrote on Tue, Mar 27, 2012 at 13:32 +0200:
Steffen Dettmer wrote:
The problem can be reproduced for example with version 8.1-415 (released 2010-05-11), which still can be downloaded from the official download location (although in `Archived Section'), however this version is included in Linux distributions that are still supported (for example SuSE Linux Enterprise Edition with long-term support).
The SLE11 package claims to be version 8.1. However AFIACS it actually packages 8.2-506. Did you already check whether 8.2-512 has the problem fixed?
I think it is not affected, but we stopped further checking after:
* security@postgresql.org:
Reporting a security bug against anything that's not current or supported is pointless.
What A pity, but if no one cares, why should we do...
[...] Possible fix or workaround:
Do not use PostgreSQL JDBC driver version 8.1 but upgrade to most recent version. If the distribution offers no suited package
Actually better complain to the security team of the distro first and ask why there is no update :-)
Yes, I reported it non-publicly first via pg-security, but maintainers told it is old and you must only use the latest JDBC driver (which, IMHO, isn't even documented that clearly). In the end I only had to apologize for bothering, there was no interest to pass the information or clarify the documentation, not talking about to even patch it. I admit I was surprised by such disintrest, so I mailed to some lists, but seems most didn't deliver (because of attachment?).
In this case noone knew that there is an SQL injection and AFAICT upstream didn't flag any updates as security relevant so no CVE assigned either.
It is not true that no one knew. I wrote heaps of mails and invested a lot of time to tell the responsible persons and tried to push some advisory. I don't know how to assign CVE, so I informed the official channel according to the PostgreSQL website especially to avoid someone could say "no one knew" before I published publicly: * Steffen to security@postgresql.org, March 22th:
(I just want to avoid someone rants me about not giving vendors a chance to fix, instead of publishing a "0day", so I'd like to include a "official" statement like "vendor notified xx.xx.xxxx")
seems I failed even on that...
PS: better use security@suse.de to reach the SUSE security team. opensuse-security@opensuse.org is a discussion list.
ok, thank you for the information. oki, Steffen -- Dieses Schreiben wurde maschinell erstellt, es trägt daher weder Unterschrift noch Siegel. -- To unsubscribe, e-mail: opensuse-security+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-security+owner@opensuse.org
participants (2)
-
Ludwig Nussel
-
Steffen Dettmer