How to prevent SQL second order injections in java (Spring Application) - java

I have been facing the second order SQL injection in this following code
if(subjectId!=null){Query query= sessionFactory
.getCurrentSession()
.createSQLQuery(HubQueryConstants.GET_QUERY)
.setParameter(MyConstants.SUBJECT_ID, subjectId)
.setFirstResult(offset)
.setMaxResults(limit)
.setResultTransformer(
Transformers.aliasToBean(MyClass.class));}
My Constant file is :
Constant file is Final class
GET_QUERY="Select * from MyClass where id=:id ";
though it is in static query by default still my security report is giving it as Second order SQL injection
Should we declare constants in interface? to avoid Security issue?

A SQL injection occurs, when a placeholder is replaced with a SQL term that alters the original SQL string so that the SQL does something different than intened.
You can find more details at SQL_injection
SQL injection happens when the placeholder of the parameters are replaced. So declaring constants instead of reading the SQL from a properties file does not help. The injection happens later, independently from where the SQL string was obtained.
The easiest way to prevent SQL injection is by using prepared statements.
When a prepared statement is executed, the SQL string and the parameters are handled completely seperate by the SQL server, making SQL injection impossible.
With JPA you can use the annotation javax.persistence.NamedNativeQuery; to declare a SQL query that will be executed as prepared statement.
You find a tutorial using NamedNativeQuers at the end of jpa-native-queries

Related

Checkmarx report sql injection JpaRepository

im running Checkmarx on my code and im getting an sql injection vulnerability.
this is the simplified method im using
public String assignRole(String userId, String roleId) {
Optional<RoleEntity> roleEntity = roleRepository.findById(roleId)
if (roleEntity.isPresent()) {
UserEntity user = UserEntity.builder().userId(userId).role(roleEntity.get()).build();
userRepository.save(user);
return "SUCCESS";
} else {
throw new ServiceException("ERROR");
}}
and the analysis of checkmax says:
The application's assignRole method executes an SQL query with save, at line xx of
src/Service.java. The application
constructs this SQL query by embedding an untrusted string into the query without proper sanitization. The
concatenated string is submitted to the database, where it is parsed and executed accordingly.
An attacker would be able to inject arbitrary syntax and data into the SQL query, by crafting a malicious
payload and providing it via the input roleId;
This may enable an SQL Injection attack.
im a little bit confused because im not building a native query or concatenating strings in a query, or maybe im missing something.
any ideas for fix this? or maybe is a false positive.
This sounds like a false positive.
If your Java code uses Spring, I recommend configuring your scan (Settings > Scan Settings > Preset Manager) with the SQL_Injection and Second_Order_SQL_Injection items under the Java section disabled (unchecked) to avoid false positives from these items.
If your code persists data to the database exclusively via the Spring save action, it is not at risk of SQL injection exploitation. That’s because Spring saves (inserts or updates) to the database using an object mapped to your db (the ORM approach) which does not allow additional sql to be maliciously forced in.
Nonetheless, from what I’ve seen, Checkmarx marks Spring save actions, falsely, as high severity SQL Injection vulnerabilities (SQL_Injection and/or Second_Order_SQL_Injection). Given this, disabling those rules seems to me valid and in fact the only viable way around this.
But if you do take this approach, make sure your code does not for some reason also use some other some other sql approach such as a String containing SQL that’s not sanitized via the use of PreparedStatement. Those statements are vulnerable to sql injection exploits and I believe are what the Checkmarx SQL injection rules are intending to identify.

Does Hibernate's Query.setParameter make SQL injection possible [duplicate]

This question already has answers here:
How to prevent SQL Injection with JPA and Hibernate?
(5 answers)
Closed 5 years ago.
I'm Using Struts2 Framework and Hibernate, I'm Enhancing a System that I didn't started, I enhanced some features of the system and implement it on the prod. But when they scan it using Acunetix, Somewhere in Login Module, there are some threats(alerts) that are detected in the System wherein the alert says:
Alert: SQL injection
Severity: High
Description: This script is possibly vulnerable to SQL Injection attacks.
Recommendation: Your script should filter metacharacters from user input. Check detailed information for more information about fixing
this vulnerability.
And then, I checked the Script that would be the fault on that alert. The Old Developer uses Hibernate to create a query.
List<UserBean> users = session.createQuery("from UserBean where username =?")
.setParameter(0,username)
.list();
My Question is:
-Is this Query using Hibernate can't Avoid SQL Injection?
-Is .setParameter should be .setString to be more specific to avoid SQL Injection?
or None of the Above ?
Thanks for the time.
If you use the Hibernate query parameter binding like this you are safe from SQL injection attacks.
In opposite to string concatenation, setParameter will fill the placeholders of the query after creating the prepared statement and before execution of the query, and the query processing engine knows which (probably malicious) chars should be escaped.
This is the common way to go.
setString is the non-generic pendant to setParameter. setParameter detects the datatype automatically.
A small improvement would be to use named parameter binding, e.g.:
List<UserBean> users = session.createQuery("from UserBean where username = :username")
.setParameter("username", username)
.list();
This way you will not get more problems with more parameters in the future.

Query with dynamic schema without using string concatenation

I have a system that uses a Oracle database, with a schema that is different from the application user. The schema name itself is not known in advance, so we can't just hardcode it. It's a system property.
Most of the data access is through Hibernate, which can specify the default schema on connection so this is not a problem in those cases.
However, there are a few places where plain SQL queries are used (using spring jdbcTemplate). So right now we have something that boils down to:
Map<String,Object> result = jdbcTemplate.queryForMap("SELECT A, B, C FROM "+schema+".TABLE WHERE blablablah");
And this, of course, is an open SQL injection vulnerability. We're planning security audits and this will be flagged for sure.
So the question is: How do I specify the schema on the query, be it with jdbcTemplate, another Sprint data access utility, or even plain jdbc?
Thank you,
JGN
You can use Connection.setSchema to specify the schema for a JDBC connection. This should be done before you create the Statement to execute a SQL command.

Getting exception while accessing values from data base using hibernate

I have two tables website_availability and status_codes.And these have foriegn key relation between them.status_codes is parent table.I am using hibernate.I need "list" of values from these tables after joining.I am following this code.
List<WebsiteAvailability>list=new ArrayList<WebsiteAvailability>
String selquery="select w.statusCode,w.updateTime,w.statusCodes.statusCodeValue from WebsiteAvailability w,StatusCodes s where w.statusCodes.statusCode=s.statusCode and w.url=?";
//here hibernate generates the POJO classes and these are having foriegn key relation so WebsiteAvailability is having private StatusCodes statusCodes.So I am accessing statuscodevalue of statuscodes table using w.statusCodes.statusCodeValue.
PreparedStatement ps=con.prepareStatement(selquery);
ps.setString(1,selUrl);
rs=ps.executeQuery();
while(rs.next())
{
list.add(new WebsiteAvailability(rs.getString("statusCode"),rs.getTimestamp("updateTime"),rs.getString("statusCodeValue")));
}
return list;
}
First of all can I use resultset with hibernate.Is there any alternative for this.Because as I am using ? placeholder I should use preparedstatement for setString().And executeQuery() to get the list.I need list of values how can i get.Am getting empty list.What is the error?
org.hibernate.QueryException:could not resolve the property statusCode of -----WebsiteAvailability---
In the hibernate mapping file I have checked for case sensitivity.Still getting could not resolve property exception
You're trying to execute an HQL query, working on Hibernate entities, as a SQL query, using JDBC statements. That doesn't make sense. HQL queries are executed by the Hibernate Session. Not by JDBC. If you're using Hibernate, you don't need JDBC anymore (except maybe in some corner cases when you need raw JDBC performance, like batches).
Read the documentation about HQL query execution. You'll also have to fix your query, because it doesn't seem right. It contains w.statusCode and also w.statusCodes. It also does a join using equality statements and selects from two entities, instead of simply using implicit or explicit joins. Those are also explained in the documentation.

prepared Statement in ejb3

i want to use prepared statement with ejb3 to insert data in oracle. is it possible to use.
i try to find some example on net but i could not find any good example.
Please help me to use it. or is there any other way to use parameter query (as we use ? in prepared statement) in ejb3
Thanks and regards
it is very simple:
public class YourEJB {
#Resource(mappedName="java:/DefaultDataSource")
DataSource dataSource;
// XXX: not handling exceptions
public void insertPerson(String name, String surname) {
Connection connection = dataSource.getConnection();
PreparedStatement insertPerson = connection.prepareStatement(
"INSERT INTO PEOPLE VALUES(?,?)");
insertPerson.setString(1, name);
insertPerson.setString(2, surname);
insertPerson.executeUpdate();
}
Take also a look at JDBC tutorials.
If you're using EJB, the idiom is to use entity beans for database interaction. If you're using EJB3, you should be creating an object and using annotations to deal with the database. SQL is generated for you using JPA.
So if EJB is providing all that abstraction to help you, why do you feel the need to go back to the lower level and write a PreparedStatement? Maybe the real answer is to rethink your object model and see how the query could fit into an entity bean abstraction.

Categories

Resources