0

I m writing a small utility that captures and logs SQL statements, but will have to remove sensitive data from the Query text and replace with with some dummy text (i.e:XXXXX).

What is a good way to parse the SQL query in java and replace parameters value?

for example:

replace

SELECT NAME, ADDRESS, .... FROM USER WHERE SSN IN ('11111111111111', '22222222222222');

with

SELECT NAME, ADDRESS, .... FROM USER WHERE SSN IN (?, ?);
4
  • 1
    Use sql parser like jsqlparser..Don't use regex..There are too many cases to cover and regex would complicate your code.. Commented Oct 10, 2013 at 12:47
  • What do you use the database Commented Oct 10, 2013 at 12:50
  • @ Anirudh, can you post your comment as an answer so I can accept it :) Commented Oct 29, 2013 at 22:20
  • maybe p6spy could help too, but I could not really find their page (although you still can download it from sourceforge) Commented Feb 6, 2014 at 2:07

4 Answers 4

1

Using JSQLParser (V0.8.9) this is a solution for your problem:

String sql ="SELECT NAME, ADDRESS, COL1 FROM USER WHERE SSN IN ('11111111111111', '22222222222222');";
Select select = (Select) CCJSqlParserUtil.parse(sql);

//Start of value modification
StringBuilder buffer = new StringBuilder();
ExpressionDeParser expressionDeParser = new ExpressionDeParser() {

    @Override
    public void visit(StringValue stringValue) {
        this.getBuffer().append("XXXX");
    }

};
SelectDeParser deparser = new SelectDeParser(expressionDeParser,buffer );
expressionDeParser.setSelectVisitor(deparser);
expressionDeParser.setBuffer(buffer);
select.getSelectBody().accept(deparser);
//End of value modification 

System.out.println(buffer.toString());
//Result is: SELECT NAME, ADDRESS, COL1 FROM USER WHERE SSN IN (XXXX, XXXX)

This replaces all found String values within your SQL. To replace other types of data e.g. Long values, override the corresponding visit method in ExpressionDeParser.

Don't use regexp in this case. It turns out quickly to be hard maintainable.

Sign up to request clarification or add additional context in comments.

Comments

1

The correct answer depends on how much you want to replace. Something like:

[0-9]{3}-?[0-9]{2}-?[0-9]{4}

will replace social security numbers pretty well. I always take regex code to

regexpal.com

to tweak it and work out bugs.

If you need to replace tons of sensitive information though, and if there are a lot of cases, definitely start looking into using a parser to parse the SQL query string. (such as jsqlparser, as Anirudh recommended.)

Comments

0

String sqlDebit = select * from table where and billing_cycle_start_date between :startDate and :endDate

java:

sqlDebit= sqlDebit.replaceAll(":startDate ", ""+startDate).replaceAll(":endDate", ""+endDate);

Comments

0

With prepare statement you can replace "?" in your query string with your value. Use number to specify which "?" you are referring too. They go by order from right to left.

For example: "SELECT LastName, FirstName FROM Person.Contact WHERE LastName = ? and FirstName = ?"

pstmt.setString(1, "LastNameValue"); pstmt.setString(2, "FirstNameValue"); see full example below:

  public static void executeStatement(Connection con) {
        try(PreparedStatement pstmt = con.prepareStatement("SELECT LastName, FirstName FROM Person.Contact WHERE LastName = ?");) {
            pstmt.setString(1, "Smith");
            ResultSet rs = pstmt.executeQuery();
    
            while (rs.next()) {
                System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
            }
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

1 Comment

Please add some explanation of your code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.