|
1 | | -<p>Formatting strings used as SQL queries is security-sensitive. It has led in the past to the following vulnerabilities:</p> |
2 | | -<ul> |
3 | | - <li> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-9019">CVE-2018-9019</a> </li> |
4 | | - <li> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-7318">CVE-2018-7318</a> </li> |
5 | | - <li> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5611">CVE-2017-5611</a> </li> |
6 | | -</ul> |
7 | | -<p>SQL queries often need to use a hardcoded SQL string with a dynamic parameter coming from a user request. Formatting a string to add those |
8 | | -parameters to the request is a bad practice as it can result in an <a href="https://www.owasp.org/index.php/SQL_Injection">SQL injection</a>. The safe |
9 | | -way to add parameters to a SQL query is to use SQL binding mechanisms.</p> |
10 | | -<p>This rule raises an issue when an SQL query is built by formatting Strings, even if there is no injection. This rule does not detect SQL |
11 | | -injections. The goal is to guide security code reviews and to prevent a common bad practice.</p> |
12 | | -<p>The following method signatures from Java JDBC, JPA, JDO, Hibernate and Spring are tested: </p> |
13 | | -<ul> |
14 | | - <li> <code>org.hibernate.Session.createQuery</code> </li> |
15 | | - <li> <code>org.hibernate.Session.createSQLQuery</code> </li> |
16 | | - <li> <code>java.sql.Statement.executeQuery</code> </li> |
17 | | - <li> <code>java.sql.Statement.execute</code> </li> |
18 | | - <li> <code>java.sql.Statement.executeUpdate</code> </li> |
19 | | - <li> <code>java.sql.Statement.executeLargeUpdate</code> </li> |
20 | | - <li> <code>java.sql.Statement.addBatch</code> </li> |
21 | | - <li> <code>java.sql.Connection.prepareStatement</code> </li> |
22 | | - <li> <code>java.sql.Connection.prepareCall</code> </li> |
23 | | - <li> <code>java.sql.Connection.nativeSQL</code> </li> |
24 | | - <li> <code>javax.persistence.EntityManager.createNativeQuery</code> </li> |
25 | | - <li> <code>javax.persistence.EntityManager.createQuery</code> </li> |
26 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.batchUpdate</code> </li> |
27 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.execute</code> </li> |
28 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.query</code> </li> |
29 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.queryForList</code> </li> |
30 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.queryForMap</code> </li> |
31 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.queryForObject</code> </li> |
32 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.queryForRowSet</code> </li> |
33 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.queryForInt</code> </li> |
34 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.queryForLong</code> </li> |
35 | | - <li> <code>org.springframework.jdbc.core.JdbcOperations.update</code> </li> |
36 | | - <li> <code>org.springframework.jdbc.core.PreparedStatementCreatorFactory.<init></code> </li> |
37 | | - <li> <code>org.springframework.jdbc.core.PreparedStatementCreatorFactory.newPreparedStatementCreator</code> </li> |
38 | | - <li> <code>javax.jdo.PersistenceManager.newQuery</code> </li> |
39 | | - <li> <code>javax.jdo.Query.setFilter</code> </li> |
40 | | - <li> <code>javax.jdo.Query.setGrouping</code> </li> |
41 | | -</ul> |
42 | | -<p>If a method is defined in an interface, implementations are also tested. For example this is the case for |
43 | | -<code>org.springframework.jdbc.core.JdbcOperations</code> , which is usually used as <code>org.springframework.jdbc.core.JdbcTemplate</code>). </p> |
| 1 | +<p>Formatted SQL queries can be difficult to maintain, debug and can increase the risk of SQL injection when concatenating untrusted values into the |
| 2 | +query. However, this rule doesn't detect SQL injections (unlike rule s3649), the goal is only to highlight complex/formatted queries.</p> |
44 | 3 | <h2>Ask Yourself Whether</h2> |
45 | 4 | <ul> |
46 | | - <li> the SQL query is built using string formatting technics, such as concatenating variables. </li> |
47 | | - <li> some of the values are coming from an untrusted source and are not sanitized. </li> |
| 5 | + <li> Some parts of the query come from untrusted values (like user inputs). </li> |
| 6 | + <li> The query is repeated/duplicated in other parts of the code. </li> |
| 7 | + <li> The application must support different types of relational databases. </li> |
48 | 8 | </ul> |
49 | 9 | <p>There is a risk if you answered yes to any of those questions.</p> |
50 | 10 | <h2>Recommended Secure Coding Practices</h2> |
51 | 11 | <ul> |
52 | | - <li> Avoid building queries manually using formatting technics. If you do it anyway, do not include user input in this building process. </li> |
53 | 12 | <li> Use <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">parameterized queries, prepared statements, or stored |
54 | | - procedures</a> whenever possible. </li> |
55 | | - <li> You may also use ORM frameworks such as Hibernate which, if used correctly, reduce injection risks. </li> |
56 | | - <li> Avoid executing SQL queries containing unsafe input in stored procedures or functions. </li> |
57 | | - <li> <a href="https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet">Sanitize</a> every unsafe input. </li> |
| 13 | + procedures</a> and bind variables to SQL query parameters. </li> |
| 14 | + <li> Consider using ORM frameworks if there is a need to have an abstract layer to access data. </li> |
58 | 15 | </ul> |
59 | | -<p>You can also reduce the impact of an attack by using a database account with low privileges.</p> |
60 | 16 | <h2>Sensitive Code Example</h2> |
61 | 17 | <pre> |
62 | 18 | public User getUser(Connection con, String user) throws SQLException { |
|
0 commit comments