Question

Our team is looking to have better compliance with the OWASP guidelines, and one of the tasks is the prevention of SQL Injection attacks. In order to facilitate this, I was looking for a way to automatically check for the usage of java.sql.Statement in our codebase, so this could be flagged and changed to use PreparedStatement.

Our build process is based on Maven and we also have Sonar setup to run analytics on the project. Some rules are already in place in Sonar to fail our builds if certain thresholds are met, so this could be implemented there. I have seen where I could setup a checkstyle regex rule looking for the import, but I wanted to see if there were other options as well.

Any location along the development/build path would work. If there were something in intellij that would flag this, something in the maven build process, or a different way to flag this in Sonar, any of these would be fine.

Thanks!!

Was it helpful?

Solution

I would suggest creating an architectural constraint within Sonar.

The example demonstrates a rule banning the use of *java.sql.** classes.

OTHER TIPS

I have not used it, but PMD looks like it might be a good tool for this.

Instead of detecting class usage, could you instead detect their generation with a java.sql.Connection proxy? When you get your connection from the factory, you would wrap it in your proxy. Your proxy would be instrumented to could method calls, log query strings, and/or report on stack traces when folks are using createStatement() or other off-limit calls.

public class ProxyConnection implements Connection {
    private Connection realConnection;

    public ProxyConnection(Connection realConnection) {
        this.realConnection = realConnection;
    }

    public Statement createStatement() throws SQLException {
       // could the offenders
       createCounter.incrementAndGet();
       // log the callers -- expensive so maybe every 100th or every 10 secs
       logger.info("call to createStatment", new Exception("createStatement"));
       // maybe just throw
       if (throwOnBadCall) {
           throw new SQLException("calls to createStatement aren't allowed"));
       }
       return realConnection.createStatement();
    }

If you don't want to get too heavy in production then you could always count them and have a volatile boolean logBadCall type of flag to only enable the checking for a period of time to sample looking for problems. Maybe initially you do some sampling, attack the 80% locations and then only have the detection on permanently when you've taken care of the high query load parts of your application.

If you do not have a central location to wrap the connection then you may have to wrap the connection pool or the factory up the chain a bit.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top