Reputation: 31
I have this SQL query written in JDBC which contains dynamic table and fields names:
private String checkDimension(String tenantId, String prefix, Long schemaMetaId, Long transactionalMetaId,
String dimension, String dimensionValue) {
DataSource tenantDataSource = tenantDataSourceProvider.getTenantDataSource(checkEntityName(tenantId));
try (Connection connection = tenantDataSource.getConnection()) {
String sql = String.format("select * from \"%s_%s\" input_file join \"DIMENSION_VALUES_%s\" dv on " +
"(dv.\"DIMENSION\" = ? and dv.\"DIMENSION_VALUE\" = input_file.\"%s\") limit 1",
checkEntityName(prefix), checkEntityName(schemaMetaId.toString()),
checkEntityName(transactionalMetaId.toString()), checkEntityName(dimensionValue));
try (PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setString(1, dimension);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
return "OK";
} else {
return "Values do not match";
}
}
}
} catch (SQLException exception) {
throw new IllegalStateException(exception);
}
}
For mitigation flaws I am using function checkEntityName
which should silent them (make them false positive during Veracode scan)
@SQLQueryCleanser
static String checkEntityName(String entityName) {
if (!entityName.matches("^[-a-zA-Z0-9_]*$")) {
throw new SecurityException(String.format("Invalid name for entity: %s", entityName));
}
return entityName;
}
But Veracode is still reporting this issue:
Flaw Id: 1433
Description: This database query contains a SQL injection flaw. The call to java.sql.Statement.executeQuery() constructs a dynamic SQL query using a variable derived from untrusted input. An attacker could exploit this flaw to execute arbitrary SQL queries against the database. The first argument to executeQuery() contains tainted data from the variable format(). The tainted data originated from an earlier call to java.sql.Statement.executeQuery.
Remediation: Avoid dynamically constructing SQL queries. Instead, use parameterized prepared statements to prevent the database from interpreting the contents of bind variables as part of the query. Always validate untrusted input to ensure that it conforms to the expected format, using centralized data validation routines when possible.
Can you please give me advice how to solve this? Thank you :)
Upvotes: 3
Views: 1945
Reputation: 25
If it still gives an exception even using PrepareStatement
try to sanitize the native SQL query string by using the below code.
private static String sanitizeQuery(String query) {
return query
.chars()
.mapToObj(i -> (char) i)
.map(String::valueOf)
.collect(Collectors.joining());
}
Upvotes: 0