Fix to prevent SQL injection attacks when calling setObject(int,Object,int)
authorBarry Lind <[email protected]>
Tue, 22 Jul 2003 05:13:05 +0000 (05:13 +0000)
committerBarry Lind <[email protected]>
Tue, 22 Jul 2003 05:13:05 +0000 (05:13 +0000)
where the Object is a String and the type is numeric (i.e. INTEGER,LONG,etc).
The fix applies the standard escaping for these values.

 Modified Files:
  Tag: REL7_3_STABLE
  jdbc/org/postgresql/Driver.java.in
  jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java

src/interfaces/jdbc/org/postgresql/Driver.java.in
src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java

index 4d27f3da573b71f877359f647142f0406f7b53c1..164c1d056b4aec232d461c65324c2a3a3f901387 100644 (file)
@@ -446,6 +446,6 @@ public class Driver implements java.sql.Driver
    }
 
    //The build number should be incremented for every new build
-   private static int m_buildNumber = 110;
+   private static int m_buildNumber = 111;
 
 }
index d3e6022f0d10e43f1d8263f0d4389138f38b34ef..1558e2b50275dfc4211a3be654e57c2f7e4372bf 100644 (file)
@@ -8,7 +8,7 @@ import java.util.Vector;
 import org.postgresql.largeobject.*;
 import org.postgresql.util.*;
 
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.12.2.4 2003/04/17 04:19:55 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.12.2.5 2003/07/22 05:13:05 barry Exp $
  * This class defines methods of the jdbc1 specification.  This class is
  * extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
  * methods.  The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
@@ -913,22 +913,36 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
            {
                sbuf.setLength(0);
                sbuf.ensureCapacity(x.length());
-               int i;
-
                sbuf.append('\'');
-               for (i = 0 ; i < x.length() ; ++i)
-               {
-                   char c = x.charAt(i);
-                   if (c == '\\' || c == '\'')
-                       sbuf.append((char)'\\');
-                   sbuf.append(c);
-               }
+               escapeString(x, sbuf);
                sbuf.append('\'');
                bind(parameterIndex, sbuf.toString(), type);
            }
        }
    }
 
+   private String escapeString(String p_input) {
+       // use the shared buffer object. Should never clash but this makes
+       // us thread safe!
+       synchronized (sbuf)
+       {
+           sbuf.setLength(0);
+           sbuf.ensureCapacity(p_input.length());
+           escapeString(p_input, sbuf);
+           return sbuf.toString();
+       }
+   }
+
+   private void escapeString(String p_input, StringBuffer p_output) {
+       for (int i = 0 ; i < p_input.length() ; ++i)
+       {
+           char c = p_input.charAt(i);
+           if (c == '\\' || c == '\'')
+               p_output.append((char)'\\');
+           p_output.append(c);
+       }
+   }
+
    /*
     * Set a parameter to a Java array of bytes.  The driver converts this
     * to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
@@ -1342,7 +1356,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
        switch (targetSqlType)
        {
            case Types.INTEGER:
-               bind(parameterIndex, x.toString(), PG_INTEGER);
+               bind(parameterIndex, escapeString(x.toString()), PG_INTEGER);
                break;
            case Types.TINYINT:
            case Types.SMALLINT:
@@ -1355,7 +1369,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
                if (x instanceof Boolean)
                    bind(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0", PG_BOOLEAN);
                else
-                   bind(parameterIndex, x.toString(), PG_NUMERIC);
+                   bind(parameterIndex, escapeString(x.toString()), PG_NUMERIC);
                break;
            case Types.CHAR:
            case Types.VARCHAR:
@@ -1763,15 +1777,12 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
    }
 
    /*
-    * There are a lot of setXXX classes which all basically do
-    * the same thing.  We need a method which actually does the
-    * set for us.
-    *
-    * @param paramIndex the index into the inString
-    * @param s a string to be stored
-    * @exception SQLException if something goes wrong
+    * Note if s is a String it should be escaped by the caller to avoid SQL
+    * injection attacks.  It is not done here for efficency reasons as 
+    * most calls to this method do not require escaping as the source 
+    * of the string is known safe (i.e. Integer.toString())
     */
-   protected void bind(int paramIndex, Object s, String type) throws SQLException
+   private void bind(int paramIndex, Object s, String type) throws SQLException
    {
        if (paramIndex < 1 || paramIndex > m_binds.length)
            throw new PSQLException("postgresql.prep.range");