kaliatech
kaliatech

Reputation: 17867

How to safely escape arbitrary strings for SQL in PostgreSQL using Java

I have a special case requiring that I generate part of a SQL WHERE clause from user supplied input values. I want to prevent any sort of SQL Injection vulnerability. I've come up with the following code:

private String encodeSafeSqlStrForPostgresSQL(String str) {

  //Replace all apostrophes with double apostrophes
  String safeStr = str.replace("'", "''");

  //Replace all backslashes with double backslashes
  safeStr = safeStr.replace("\\", "\\\\");

  //Replace all non-alphanumeric and punctuation characters (per ASCII only)
  safeStr = safeStr.replaceAll("[^\\p{Alnum}\\p{Punct}]", "");

  //Use PostgreSQL's special escape string modifier
  safeStr = "E'" + safeStr + "'";

  return safeStr;
}

Questions:

Notes:

Ideally I would've liked a more generic and robust solution that I knew would be safe and support all possible UTF-8 strings.

Upvotes: 20

Views: 24008

Answers (2)

sixtyfootersdude
sixtyfootersdude

Reputation: 27221

I asked a similar question here, but I think that the best thing to do is to use org.postgresql.core.Utils.escapeLiteral. This is a Postgres library so using it should be safe. If/when Postgres adds new string delimiters this method should be updated.

Upvotes: 9

A.H.
A.H.

Reputation: 66223

The most easiest way would be to use PostgreSQL's Dollar Quoting in the combination with a small random tag:

  • For each invocation calculate a small, random tag (e.g 4 characters) (redundant)
  • Look whether or not the quote tag is part of the input string.
  • If it is, recalculate a new random tag.
  • Otherwise build your query like this:

    $tag$inputString$tag$
    

This way you escape the whole hassle of different nested quoting techniques and you also set up a moving target by using a random tag.

Depending on your security requirements this might do the job or not. :-)

Upvotes: 21

Related Questions