JYuan320271 (Community Member) asked a question.

How to fix CWE 89 SQL Injection flaws even though we have used prepared statements

We have some doubt on recent reports that clues CWE 89 SQL Injections flaws exist in some of our classes, even though we have used prepared statements, for example:

public static void createUser(String userName, String password, String tags) {

try {

byte[] salt = generateSalt();

byte[] bpass = getEncryptedPassword(password, salt);

String secuSchema = DSManager.getSecuSchema();

String strDS = DSManager.getSecuDS();

String sql = "INSERT into " + secuSchema + ".SEC_USER_TOKEN VALUES (?,?,?,?)";

try (Connection con = QueryUtil.getConnection(strDS); 

PreparedStatement ps = con.prepareStatement(sql)) {

ps.setString(1, userName);

ps.setBytes(2, bpass);

ps.setBytes(3, salt);

ps.setString(4, tags);

ps.execute(); //here is a flaw ?

} catch (NamingException | SQLException e) {

APLogExec.writeEEError(DataType.getErrorStackTrace(e));

}

}catch(Exception e) {

APLogExec.writeEEError(DataType.getErrorStackTrace(e));

}

 

And:

public boolean deleteRec(String dataSource, String sql, Object[] parameters) throws Exception {

Connection con = null;

try {

con = DSManager.getConnection(dataSource);

int ret = this.update(con, sql, parameters); // here is a flaw ?

return ret > 0;

} finally {

DbUtils.close(con);

}

}

}

 

this.update is extended from apache QueryRunner:

/**

   * Calls update after checking the parameters to ensure nothing is null.

   * @param conn The connection to use for the update call.

   * @param closeConn True if the connection should be closed, false otherwise.

   * @param sql The SQL statement to execute.

   * @param params An array of update replacement parameters. Each row in

   * this array is one set of update replacement values.

   * @return The number of rows updated.

   * @throws SQLException If there are database or parameter errors.

   */

  private int update(Connection conn, boolean closeConn, String sql, Object... params) throws SQLException {

    if (conn == null) {

      throw new SQLException("Null connection");

    }

 

    if (sql == null) {

      if (closeConn) {

        close(conn);

      }

      throw new SQLException("Null SQL statement");

    }

 

    PreparedStatement stmt = null;

    int rows = 0;

 

    try {

      stmt = this.prepareStatement(conn, sql);

      this.fillStatement(stmt, params);

      rows = stmt.executeUpdate();

 

    } catch (SQLException e) {

      this.rethrow(e, sql, params);

 

    } finally {

      close(stmt);

      if (closeConn) {

        close(conn);

      }

    }

 

    return rows;

  }

 

Why and How to fix these? Thanks


  • Hi @JYuan320271 (Community Member)​ 

     

    PreparedStatements does help remediate SQL Injection absolutely provided the SQL string used to 'Prepare' is statically defined (hardcoded)

     

    Given in the example above.

    String sql = "INSERT into " + secuSchema + ".SEC_USER_TOKEN VALUES (?,?,?,?)";

    where

    String secuSchema = DSManager.getSecuSchema();

     

    Sql is constructed using a variable 'secuScheme' which the scanner thinks is a tainted data.

     

    It is best to validate this variable using allowlist approach (Allowlist would a collection of all table names your database have.)

     

    I would recommend you to review solution in the below article here:

    https://community.veracode.com/s/article/How-to-fix-CWE-89-SQL-Injection-flaws

    https://community.veracode.com/s/article/sql-injection-mitigation-page2

     

    The second link actually covers the scenario of having dynamic table names.

     

    Regards,

    Kashif.

     

    Expand Post
    • JYuan320271 (Community Member)

      Thanks for your reply!

      I see now. Actually the secuSchema is got from a configure xml file and it's pre-encoded. But any way it's better to validate again.

      So, if we do the validation in DSManager.getSecuSchema() which is the root method, can the injection flaw of CWE 89 be fixed?

  • @JYuan320271 (Community Member)​ 

    Yes, we definitely recommend a validation for that variable. The implementation of the validation will determine whether it will automatically be fixed or not.

    If static analysis recognized the mitigation effort, it will close the flaw as fixed. But if the validation uses a logical check which may not be recognized by Static analysis, it would continue to show as an Open flaw, nevertheless, it is very much eligible for Mitigation-By-Design proposal.

    If your validation is based on the Allowlist definition, kindly also see this article to understand how Allowlist should be implemented.

    https://community.veracode.com/s/article/allowlist-helps-fix-cwe

    Expand Post

Topics (2)

No articles found
Loading

Ask the Community

Get answers, share a use case, discuss your favorite features, or get input from the community.