Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0b27508

Browse files
committed
Add models for org.springframework.jdbc.object
Also add tests for the existing Spring JDBC SQL injection sinks in the process
1 parent a0481bd commit 0b27508

38 files changed

Lines changed: 913 additions & 2 deletions

java/ql/src/semmle/code/java/frameworks/SpringJdbc.qll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,16 @@ private class SqlSinkCsv extends SinkModelCsv {
2424
"org.springframework.jdbc.core;JdbcTemplate;false;queryForMap;;;Argument[0];sql",
2525
"org.springframework.jdbc.core;JdbcTemplate;false;queryForObject;;;Argument[0];sql",
2626
"org.springframework.jdbc.core;JdbcTemplate;false;queryForRowSet;;;Argument[0];sql",
27-
"org.springframework.jdbc.core;JdbcTemplate;false;queryForStream;;;Argument[0];sql"
27+
"org.springframework.jdbc.core;JdbcTemplate;false;queryForStream;;;Argument[0];sql",
28+
"org.springframework.jdbc.object;BatchSqlUpdate;false;BatchSqlUpdate;;;Argument[1];sql",
29+
"org.springframework.jdbc.object;MappingSqlQuery;false;BatchSqlUpdate;;;Argument[1];sql",
30+
"org.springframework.jdbc.object;MappingSqlQueryWithParameters;false;BatchSqlUpdate;;;Argument[1];sql",
31+
"org.springframework.jdbc.object;RdbmsOperation;true;setSql;;;Argument[0];sql",
32+
"org.springframework.jdbc.object;SqlCall;false;SqlCall;;;Argument[1];sql",
33+
"org.springframework.jdbc.object;SqlFunction;false;SqlFunction;;;Argument[1];sql",
34+
"org.springframework.jdbc.object;SqlQuery;false;SqlQuery;;;Argument[1];sql",
35+
"org.springframework.jdbc.object;SqlUpdate;false;SqlUpdate;;;Argument[1];sql",
36+
"org.springframework.jdbc.object;UpdatableSqlQuery;false;UpdatableSqlQuery;;;Argument[1];sql"
2837
]
2938
}
3039
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import java.sql.ResultSet;
2+
import java.util.Map;
3+
import org.springframework.jdbc.core.JdbcTemplate;
4+
import org.springframework.jdbc.core.RowMapper;
5+
import org.springframework.jdbc.object.BatchSqlUpdate;
6+
import org.springframework.jdbc.object.MappingSqlQueryWithParameters;
7+
import org.springframework.jdbc.object.SqlFunction;
8+
import org.springframework.jdbc.object.SqlUpdate;
9+
import org.springframework.jdbc.object.UpdatableSqlQuery;
10+
11+
public class SpringJdbc {
12+
13+
public static String source() { return null; }
14+
15+
private static class MyUpdatableSqlQuery extends UpdatableSqlQuery<String> {
16+
public MyUpdatableSqlQuery() {
17+
super(null, source()); // $ sqlInjection
18+
}
19+
20+
protected String updateRow(ResultSet rs, int rowNum, Map<?,?> context) {
21+
return null;
22+
}
23+
}
24+
25+
public static void test(JdbcTemplate template) {
26+
new BatchSqlUpdate(null, source()); // $ sqlInjection
27+
new SqlFunction(null, source()); // $ sqlInjection
28+
new SqlUpdate(null, source()); // $ sqlInjection
29+
30+
(new BatchSqlUpdate()).setSql(source()); // $ sqlInjection
31+
32+
template.batchUpdate(source()); // $ sqlInjection
33+
template.batchUpdate(source(), null, 0, null); // $ sqlInjection
34+
template.execute(source()); // $ sqlInjection
35+
template.update(source()); // $ sqlInjection
36+
template.query(source(), (RowMapper)null); // $ sqlInjection
37+
template.queryForList(source()); // $ sqlInjection
38+
template.queryForMap(source()); // $ sqlInjection
39+
template.queryForObject(source(), (Class)null); // $ sqlInjection
40+
template.queryForRowSet(source()); // $ sqlInjection
41+
template.queryForStream(source(), (RowMapper)null); // $ sqlInjection
42+
}
43+
44+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient
1+
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/springframework-5.3.8

java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.expected

Whitespace-only changes.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import java
2+
import semmle.code.java.dataflow.TaintTracking
3+
import semmle.code.java.security.QueryInjection
4+
import TestUtilities.InlineExpectationsTest
5+
6+
private class QueryInjectionFlowConfig extends TaintTracking::Configuration {
7+
QueryInjectionFlowConfig() { this = "SqlInjectionLib::QueryInjectionFlowConfig" }
8+
9+
override predicate isSource(DataFlow::Node src) {
10+
src.asExpr() = any(MethodAccess ma | ma.getMethod().hasName("source"))
11+
}
12+
13+
override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }
14+
15+
override predicate isSanitizer(DataFlow::Node node) {
16+
node.getType() instanceof PrimitiveType or
17+
node.getType() instanceof BoxedType or
18+
node.getType() instanceof NumberType
19+
}
20+
21+
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
22+
any(AdditionalQueryInjectionTaintStep s).step(node1, node2)
23+
}
24+
}
25+
26+
class HasFlowTest extends InlineExpectationsTest {
27+
HasFlowTest() { this = "HasFlowTest" }
28+
29+
override string getARelevantTag() { result = "sqlInjection" }
30+
31+
override predicate hasActualResult(Location location, string element, string tag, string value) {
32+
tag = "sqlInjection" and
33+
exists(DataFlow::Node src, DataFlow::Node sink, QueryInjectionFlowConfig conf |
34+
conf.hasFlow(src, sink)
35+
|
36+
sink.getLocation() = location and
37+
element = sink.toString() and
38+
value = ""
39+
)
40+
}
41+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Generated automatically from org.springframework.core.NestedRuntimeException for testing purposes
2+
3+
package org.springframework.core;
4+
5+
6+
abstract public class NestedRuntimeException extends RuntimeException
7+
{
8+
protected NestedRuntimeException() {}
9+
public NestedRuntimeException(String p0){}
10+
public NestedRuntimeException(String p0, Throwable p1){}
11+
public String getMessage(){ return null; }
12+
public Throwable getMostSpecificCause(){ return null; }
13+
public Throwable getRootCause(){ return null; }
14+
public boolean contains(Class<? extends Object> p0){ return false; }
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Generated automatically from org.springframework.dao.DataAccessException for testing purposes
2+
3+
package org.springframework.dao;
4+
5+
import org.springframework.core.NestedRuntimeException;
6+
7+
abstract public class DataAccessException extends NestedRuntimeException
8+
{
9+
protected DataAccessException() {}
10+
public DataAccessException(String p0){}
11+
public DataAccessException(String p0, Throwable p1){}
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Generated automatically from org.springframework.jdbc.core.BatchPreparedStatementSetter for testing purposes
2+
3+
package org.springframework.jdbc.core;
4+
5+
import java.sql.PreparedStatement;
6+
7+
public interface BatchPreparedStatementSetter
8+
{
9+
int getBatchSize();
10+
void setValues(PreparedStatement p0, int p1);
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Generated automatically from org.springframework.jdbc.core.CallableStatementCallback for testing purposes
2+
3+
package org.springframework.jdbc.core;
4+
5+
import java.sql.CallableStatement;
6+
7+
public interface CallableStatementCallback<T>
8+
{
9+
T doInCallableStatement(CallableStatement p0);
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Generated automatically from org.springframework.jdbc.core.CallableStatementCreator for testing purposes
2+
3+
package org.springframework.jdbc.core;
4+
5+
import java.sql.CallableStatement;
6+
import java.sql.Connection;
7+
8+
public interface CallableStatementCreator
9+
{
10+
CallableStatement createCallableStatement(Connection p0);
11+
}

0 commit comments

Comments
 (0)