diff --git a/java/ql/src/semmle/code/java/frameworks/jOOQ.qll b/java/ql/src/semmle/code/java/frameworks/jOOQ.qll new file mode 100644 index 00000000000..5f473a18f33 --- /dev/null +++ b/java/ql/src/semmle/code/java/frameworks/jOOQ.qll @@ -0,0 +1,23 @@ +/** + * Provides classes and predicates for working with the jOOQ framework. + */ + +import java + +/** + * Methods annotated with this allow for generation of "plain SQL" + * and is prone to SQL injection. + * https://www.jooq.org/doc/current/manual/sql-building/plain-sql/ + */ +private class PlainSQLType extends Annotation { + PlainSQLType() { this.getType().hasQualifiedName("org.jooq", "PlainSQL") } +} + +/** + * Holds if `m` is a jOOQ SQL method taking an SQL string as its + * first argument. + */ +predicate jOOQSqlMethod(Method m) { + m.getAnAnnotation() instanceof PlainSQLType and + m.getParameterType(0) instanceof TypeString +} diff --git a/java/ql/src/semmle/code/java/security/QueryInjection.qll b/java/ql/src/semmle/code/java/security/QueryInjection.qll index 6eb4858519a..a81e19a2c28 100644 --- a/java/ql/src/semmle/code/java/security/QueryInjection.qll +++ b/java/ql/src/semmle/code/java/security/QueryInjection.qll @@ -3,6 +3,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.frameworks.Jdbc +import semmle.code.java.frameworks.jOOQ import semmle.code.java.frameworks.android.SQLite import semmle.code.java.frameworks.javaee.Persistence import semmle.code.java.frameworks.SpringJdbc @@ -30,6 +31,8 @@ private class SqlInjectionSink extends QueryInjectionSink { index = 0 and mybatisSqlMethod(m) or index = 0 and hibernateSqlMethod(m) + or + index = 0 and jOOQSqlMethod(m) ) } }