1

I'm taking a look at an webapp source code and, although the dev has been careful enough as to use prepared statements to fill in the query's "String" parameters, he/she has filled all the query's "Long" parameters using simple concatenation.

Example:

Obs: status has type String, var1 has type Long

Query query = entityManager.createQuery(
            "SELECT UPPER(request.attributeValue) FROM PreOrderedRequests request 
             WHERE request.status = :status AND request.report.id = " + var1);

I know he/she should not have done that, but my question is: has anyone here seen an actual exploit for that? How would one take advantage of this behavior?

For the suspicious ones: I'm not hacking anything. Just a friend of mine that asked me to take a look at this specific piece of code.

6
  • You will be pleased to hear that you did not sound suspicious with this question. Aug 9, 2016 at 0:19
  • 1
    It would be possible to enumerate the report.id field (direc object reference), but depending on the type of data (ie, all public) this may not be an issue.
    – wireghoul
    Aug 9, 2016 at 8:14
  • @wireghoul, can you elaborate on that? Aug 9, 2016 at 15:54
  • 1
    While not an SQLi attack, @wireghoul is pointing out that your code does allow enumeration of the ids in the database. This simply means that the visitor can use brute-force to determine what IDs exist in the database. One possible counter-measure for that is to use randomly-generated IDs instead of the usual sequential IDs. Aug 9, 2016 at 16:11
  • Correct me if i got it wrong, but that enumeration would still be possible even if he had used the expected prepared statement, right? Aug 9, 2016 at 16:20

2 Answers 2

1

In your Java example:

Query query = entityManager.createQuery(
        "SELECT UPPER(request.attributeValue) FROM PreOrderedRequests request 
         WHERE request.status = :status AND request.report.id = " + var1);

If var1 is a byte, short, int, long then there is no security exploit. These will be interpreted by the SQL server as the developer intended.

If 'cached prepared statements' is enabled, then such code would degrade the cache's effectiveness, but that would not qualify as a security issue.

If var1 were a double, float or char then an attacker could likely cause an SQL syntax error (with Infinity, -Infinity or some unexpected charactor), but it would be rare for that error to become a usable SQLi attack. This would primarily be a means of gathering information. (i.e. error pages could reveal a vulnerability in some edge cases)

If var1 were a String it is obviously a serious issue.

If var1 were some other Object, then the risk would depend on the Object's toString method. (i.e. Integer is safe, but CharSequence is unsafe, and Collection is probably unsafe)

0

Java is statically typed language which means that types are defined at compile time.

So, if there's Long type in Java, there's no way to change it to String in any way and make injection. If that would be some different dynamic language then it is theoretically possible, however some web frameworks like Play and Grails require or recommend static definition of every argument passed via GET and POST.

So as GET and POST parameters are defined statically, during argument parsing Java web framework will check if the argument passed is actually anything which can be converted to Long. If it cannot be, then the exception will be thrown and the whole request will be failed without starting any SQL queries.

Even if the GET/POST argument is defined as String, since var1 is typed as Long, it will be always converted to Long and never replaced with String.

So there's no way to exploit this concatenation.

1
  • OK I corrected it to specific frameworks.
    – Aria
    Aug 10, 2016 at 16:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .