I have a query where there is sql injection in line .I'm currently working on below code
I noticed that my query is vulnerable to SQL injection. Here's the part of the code that’s causing concern:
return iSearchResultsService.getSearchResults(searchresultbean);
How can I rewrite this query to prevent SQL injection?
I’ve heard about parameterized queries or prepared statements, but I’m not sure how to apply that in my case.
public List<SearchResultPojo> getSearchResults(
@RequestBody SearchResultsBean searchresultbean,
@PathVariable("cId") int catalogId, @PathVariable("region") String region,
@PathVariable("languageId") int languageId) {
logger.info(" Search Result Controller Started");
if(catalogId >= 0) {
int catId=Integer.parseInt(Integer.toString(catalogId));
searchresultbean.setCatId(catId);
} else {
searchresultbean.setCatId(catalogId);
}
searchresultbean.setLangId(languageId);
searchresultbean.setRegion(region);
char[][] replaceChars = new char[1][2];
char[] badChars = new char[2];
// Characters to be replaced (e.g. replace '*' with '%')
replaceChars[0][0] = '*';
replaceChars[0][1] = '%';
// Characters to be removed from product description search
badChars[0] = '*';
badChars[1] = '\'';
searchresultbean.setReplaceChars(replaceChars);
searchresultbean.setBadChars(badChars);
Map<String, Object> buuidMap = iSearchResultsService.getUnitId(region, cId,
languageId);
if (buuidMap.size() > 0) {
searchresultbean.setBuId((int) buuidMap.get("business_unit_id"));
}
logger.info(" Product Search Result Controller Exit");
return iSearchResultsService.SearchResult(searchresultbean);
}
}
public String getSearchQuery(searchresultbean searchresultbean) {
logger.info("Search Result Sql QueryBuild function started");
searchresultbean.setReturnStyle(1);
StringBuilder queryString = new StringBuilder();
queryString.append(buildSQLSelectFields(searchresultbean));
queryString.append(buildSQLFrom(searchresultbean));
queryString.append(buildSQLWhereClause(searchresultbean));
queryString.append(this.buildSQLOrderBy(searchresultbean.getOrderBy()));
logger.info(" Search Result Sql QueryBuild function Exit");
return queryString.toString();
}
}
private String buildSQLWhereClause(searchresultbean searchresultbean) {
logger.info("Inside the Search Result Sql WHERE CLAUSE function started");
StringBuilder whereClause = new StringBuilder(" WHERE 1 = 1 ");
if (searchresultbean.getDId() > 0) {
whereClause.append(
SqlHelper.getSqlArgs("AND", "v.id", String.valueOf(searchresultbean.getDId()),
SqlHelper.NUMBER, false, true, searchresultbean.getReplaceChars()));
}
if (!StringUtils.isEmpty(searchresultbean.getNum())) {
whereClause
.append(SqlHelper.getSqlArgs("AND", "v._num", searchresultbean.getNum(),
SqlHelper.TEXT, true, true, searchresultbean.getReplaceChars()));
}
if (!StringUtils.isEmpty(searchresultbean.getDesc())) {
boolean flag = searchresultbean.isUseBoolAndWhereClause();
whereClause.append(buildDescClause(searchresultbean.getDesc(),
searchresultbean.getBadChars(), flag));
}
if (searchresultbean.getId() > 0) {
whereClause.append(
SqlHelper.getSqlArgs("AND", "v.id", String.valueOf(searchresultbean.getId()),
SqlHelper.NUMBER, false, true, searchresultbean.getReplaceChars()));
}
if (!StringUtils.isEmpty(searchresultbean.getName())) {
whereClause.append(
SqlHelper.getSqlArgs("AND", "v.name", searchresultbean.getName(),
SqlHelper.TEXT, true, true, searchresultbean.getReplaceChars()));
}
if (!StringUtils.isEmpty(searchresultbean.getNum())) {
whereClause
.append(SqlHelper.getSqlArgs("AND", "v.num", searchresultbean.getNum(),
SqlHelper.TEXT, true, true, searchresultbean.getReplaceChars()));
}
if (!StringUtils.isEmpty(searchresultbean.getStdNum())) {
whereClause.append(
SqlHelper.getSqlArgs("AND", "v.stdnum", searchresultbean.getStdNum(),
SqlHelper.TEXT, true, true, searchresultbean.getReplaceChars()));
}
if (!searchresultbean.getIncludeOff()) {
whereClause.append(" AND v.flag = 1");
}
if (searchresultbean.getFilterFlag()) {
whereClause.append(" AND v.flag1 = 1");
}
whereClause.append(" AND v.ID=").append(searchresultbean.getId()).append(' ');
whereClause.append("AND ISNULL(bup.FLAG, 0) != 1 ");
// Software Type filter
if (searchresultbean.getSOFTWAREId() > 0) {
whereClause.append(" AND dp.software_type_id = ");
whereClause.append(searchresultbean.getSoftwareId() + "\n");
}
// Licensing filters
if (searchresultbean.isLSearch()) {
buildWhereClauseForsodtware(whereClause, searchresultbean);
}
logger.info("Search Result Sql WHERE CLAUSE");
return whereClause.toString();
}
How can we avoid these vulnerabilities ?
buildSQLWhereClause, so that whenever any of the fields insearchresultbeanis populated, you'll add something to the SQL such asAND v.id = ?orAND v._num = ?and so on - use a?instead of the actual value. But you'll also need to write a second method, which iterates through the fields again and sets the parameters in the prepared statement