escapeQuotes causes faults in DatabaseMataData - Mailing list pgsql-jdbc

From Paolo Predonzani
Subject escapeQuotes causes faults in DatabaseMataData
Date
Msg-id 1138985682.7276.24.camel@localhost.localdomain
Whole thread Raw
Responses Re: escapeQuotes causes faults in DatabaseMataData  (Kris Jurka <books@ejurka.com>)
List pgsql-jdbc
Hi everybody!
There is a particular type of input that causes trouble when calling DatabaseMetaData's methods such as getTables(), ecc.

The input I'm talking about are strings containing backslash characters in situations like the following:
dbmd.getTables(null, null, "my\\table", types);

The result is generally a wrong answer from the getTables method or, in the worst situation where the backslash is the last character, a PSQLException.

Some sample code:

    public void testPostgresQuote() throws Exception {
        System.out.println("testPostgresQuote:");
        Connection conn = null;
        try {
            String[] types = {"TABLE"};
            conn = ConnectionFactory.getConnection();
            DatabaseMetaData dbmd = conn.getMetaData();
            dbmd.getTables(null, null, "\\", types);
        } finally {
            if (conn != null) {
                try {conn.close();} catch (Exception e2) {}
            }
        }
    }

this causes a nasty exception (and opens a possibility for SQL injection?):

ERROR: unterminated quoted string at or near "'\'  AND (false )  ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME "
org.postgresql.util.PSQLException: ERROR: unterminated quoted string at or near "'\'  AND (false )  ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME "
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1512)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1297)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:188)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:430)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:332)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:231)
        at org.postgresql.jdbc2.AbstractJdbc2DatabaseMetaData.getTables(AbstractJdbc2DatabaseMetaData.java:2190)


I've looked at the source code for  postgresql-jdbc-8.1-404 and the trouble seems to come from the escapeQuotes function in AbstractJdbc2DatabaseMetaData.java

    protected static String escapeQuotes(String s) {
        StringBuffer sb = new StringBuffer();
        int length = s.length();
        char prevChar = ' ';
        char prevPrevChar = ' ';
        for (int i = 0; i < length; i++)
        {
            char c = s.charAt(i);
            sb.append(c);
            if (c == '\'' && (prevChar != '\\' || (prevChar == '\\' && prevPrevChar == '\\')))
            {
                sb.append("'");
            }
            prevPrevChar = prevChar;
            prevChar = c;
        }
        return sb.toString();
    }


I believe escapeQuotes only checks for single quotes, and does nothing to backslashes.
My temporary solution has been to patch escapeQuotes as follows:

    protected static String escapeQuotes(String s) {
        StringBuffer sb = new StringBuffer();
        int length = s.length();
        char prevChar = ' ';
        char prevPrevChar = ' ';
        for (int i = 0; i < length; i++)
        {
            char c = s.charAt(i);
            if ( c == '\\' || c == '\'' )
                sb.append('\\');

            sb.append(c);
        }
        return sb.toString();
    }

... which seems to work.

Regards

Paolo

pgsql-jdbc by date:

Previous
From: Markus Schaber
Date:
Subject: Re: JDBC keygen select
Next
From: Trevor Baker
Date:
Subject: why setFloat() changed to Oid.FLOAT8?