class SqlInjectionChecker
extends TypeCheckingDSL
Checks at compile-time for a common SQL injection mistake when using groovy.sql.Sql:
surrounding an interpolated GString expression with SQL quotes, for example:
sql.rows("select * from Book where title = '${title}'") // '${...}' → injection risk
Quoting a dynamic expression prevents Groovy from binding the value through a JDBC
PreparedStatement placeholder, so the value would have to be inlined into the SQL text,
reopening a SQL injection hole (CWE-89). The correct form omits the quotes so the value is bound
as a parameter:
sql.rows("select * from Book where title = $title") // bound as a '?' placeholder
This is a compile-time complement to the runtime protection in Sql.asSql(GString, List)
(GROOVY-12118). The runtime guard only fires when a GString reaches the query method. It
cannot see the value once the GString has been coerced to a plain String before the call,
because the interpolated value is then already inlined and the String overload is selected.
This checker covers exactly those coercion cases, which are otherwise silent:
String query = "... where title = '${title}'"; sql.rows(query) // assignment coercion
sql.rows("... where title = '${title}'".toString()) // explicit toString()
sql.rows("... where title = '${title}'" as String) // cast coercion
as well as flagging the direct GString case earlier (at compile time rather than at runtime).
String b = a), and merges if/else branches pessimistically (unsafe in
either branch is unsafe afterwards). Taint reaching a sink through a local is reported as a
compile error; taint reaching a sink through a field initializer is reported as a warning
only, because a field may be reassigned elsewhere before the query runs.
@SuppressWarnings("groovy.sql.injection").
@TypeChecked, so it is a defence-in-depth
aid rather than a guarantee: strings built across method boundaries, by raw concatenation, or read
from external sources are not tracked, and dynamic (non type-checked) code still relies on the
runtime guard.
Usage:
@TypeChecked(extensions='groovy.typecheckers.SqlInjectionChecker')
| Constructor and description |
|---|
SqlInjectionChecker() |
Copyright © 2003-2026 The Apache Software Foundation. All rights reserved.