The Checkmarx throws the error because the values you are setting to the query parameters are not validated for its type.
For example, let us assume the query formed with your PreparedStatement is as below and the value you want to pass to the query parameter is 'Test'
Select * from XYZ where COL1 = ?
If your code is compromised and if the intruder passes 'Test' OR 1 = 1 in the query parameter, then the condition will always be true and it would return all the records from the Table.
So, before executing the query you should validate all your inputs.
Hope this helps
Answer from Prasann on Stack OverflowThe Checkmarx throws the error because the values you are setting to the query parameters are not validated for its type.
For example, let us assume the query formed with your PreparedStatement is as below and the value you want to pass to the query parameter is 'Test'
Select * from XYZ where COL1 = ?
If your code is compromised and if the intruder passes 'Test' OR 1 = 1 in the query parameter, then the condition will always be true and it would return all the records from the Table.
So, before executing the query you should validate all your inputs.
Hope this helps
For solving your issue in Checkmarx, you need to validate that sql String
A second order SQL injection is an injection where the payload is already stored in the database (instead of say being delivered in a GET parameter). In that sense it is somewhat similar to stored XSS (and ordinary "first order" SQL injection would be analogous to reflected XSS).
How does it work? Lets say you let users pick any username. So an attacker could choose the name '; DROP TABLE Users; --. If you naively concatenate this username into your SQL query to retrieve information about that user you have a problem:
sql = "SELECT * FROM Users WHERE UserName = '" + $username + "'";
So, how do you deal with this?
Always use parametrized querires, always, always, always. Treat all variables as untrusted user data even if they originate from the database. Just pretend everything is GET parameters, and behave accordingly by binding them as parameters.
You can also sanitize and limit the input (e.g. only allow alphanumeric usernames) before it is stored in the database as well as after it is retrieved from the database. But I would not rely on that as my only line of defence, so use parametrized queries as well.
There is nothing 'special' here. The so called 'second order' SQL injection is just the same SQL injection with the minor difference that the content is coming from within the database rather than from data entered directly by the user. The same rules apply
always sanitise input data regardless of where it comes from (the user, a file a database etc)
Never use string concatenation to build up executable commands. Use prepared statements etc.
The rule of thumb is to never trust any input data regardless of how secure you think it might be. You cannot trust what the user might enter and you need to assume that even your own data repositories (i.e. your database) may have been compromised in some way or have had 'bad data' etnered into it. Write your code with the assumption your running in a hostile environment as the reality is, you are.
BTW I see that Oracle's documentation has not improved! That is a really badly worded and poorly explained blurb regarding SQl injection.
Checkmarx captures lot of False Positive scenarios - and it's justifiable as to warn user. But the problem is, even if you write validation functions to sanitize the inputs, it still flags them as bug - biggest issue of this tool.
Furthermore, it captures SQL Injection bugs even with MongoDB.
My recommendation is, just add validation functions which removes unnecessary characters, checks string length, data type, etc. That's good enough. Don't bother if Checkmarx still captures that as error. As rightly said - Checkmarx is far far behind from perfection.
There is only one solution to solve an SQL-Injection : Parametrize yours queries !
See https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
This is a false positive, you need to contact the vendor and notify them about this case. When Hibernate generates SQL, it uses PreparedStatement. All the Entity fields that you change will be sent separately from the query - there won't be any concatenation.
Spring Data doesn't change the way Hibernate works with entities. So either this is a false positive, or you're looking at the wrong line of code.
JPA repository is against SQL injection you don't need to add intentionally. JPA features already avoid injection