This episode covers Groovy application security: safe execution of dynamic scripts, input validation, sandboxing, and code injection prevention. You will also learn secure dependency management and supply chain awareness to protect applications from the start.

Groovy is very powerful — and that power is dangerous when misused. Executing dynamic scripts from untrusted sources can open the door to total system compromise. Episode 20 covers how to use Groovy's power safely.
You'll learn safe execution of dynamic scripts, input validation, sandboxing, code injection prevention, as well as secure dependency management and supply chain awareness.
Groovy scripts can call any Java API — including file access, networking, and system properties. If you execute scripts from user input without restrictions, an attacker could:
The golden rule: never execute scripts from sources you don't fully trust, except inside a sandbox.
Groovy provides CompilerConfiguration with SecureASTCustomizer to restrict the language constructs that are allowed:
import org.codehaus.groovy.control.customizers.SecureASTCustomizer
import org.codehaus.groovy.control.CompilerConfiguration
def secure = new SecureASTCustomizer()
secure.disallowedTokens = [":", "%"]
def config = new CompilerConfiguration()
config.addCompilationCustomizers(secure)secure.disallowedTokens = [":", "%"] forbids dangerous tokens, and config.addCompilationCustomizers(secure) applies them. new SecureASTCustomizer() creates an AST filter that blocks constructs before compilation — the first line of sandbox defense.
Restrict imports to a whitelist:
secure.allowedImports = ["java.math.BigDecimal"]
secure.allowedStarImports = ["java.lang"]
def shell = new GroovyShell(ClassLoader.systemClassLoader, new Binding(), config)
def hasil = shell.evaluate("2 + 2")
println hasilsecure.allowedImports = ["java.math.BigDecimal"] only allows specific imports, and allowedStarImports restricts wildcard imports. new GroovyShell(...config) creates a shell with the safe configuration — scripts can only use the allowed classes.
For legacy applications using Java 8-17, SecurityManager can restrict system access:
java -Djava.security.manager -Djava.security.policy=app.policy -jar app.jarjava -Djava.security.manager -Djava.security.policy=app.policy -jar app.jar enables the security manager with a policy file. Note: SecurityManager has been deprecated in JDK 17+ and removed in JDK 24, so for newer JDKs use SecureASTCustomizer and sandboxing at the OS or container level.
Input validation is the first defense against injection. For scripts that accept parameters, use a whitelist:
def namaValid = { String nama ->
nama ==~ /[a-zA-Z ]+/
}
def proses(String nama) {
if (!namaValid(nama)) {
throw new IllegalArgumentException("Nama tidak valid")
}
"Halo, ${nama}"
}
println proses("Arman")nama ==~ /[a-zA-Z ]+/ verifies that the input only contains letters and spaces. throw new IllegalArgumentException("Nama tidak valid") stops processing when input looks suspicious — a pattern that prevents injection before it happens.
Avoid concatenating user input into scripts that get executed. If parameters must enter a script, use binding rather than string interpolation:
def binding = new Binding([nama: "Arman"])
def shell = new GroovyShell(binding)
println shell.evaluate("println nama")new Binding([nama: "Arman"]) inserts the value as a variable instead of splicing text into code. shell.evaluate("println nama") executes a script that uses the binding variable. new Binding([nama: "Arman"]) avoids the injection hole that appears when values are interpolated directly into script strings.
Most Groovy applications depend on third-party libraries. Vulnerable dependencies are a serious risk:
gradle dependencyCheckAnalyzegradle dependencyCheckAnalyze runs OWASP Dependency-Check to scan for CVEs across all dependencies. gradle dependencyCheckAnalyze produces a vulnerability report that must be reviewed before release.
Several practices to protect the supply chain:
1.+.Gradle can verify artifact integrity:
dependencies {
implementation("org.codehaus.groovy:groovy:4.0.24") {
verifyChecksums = true
}
}verifyChecksums = true forces Gradle to check the documented checksums. implementation("org.codehaus.groovy:groovy:4.0.24"){ :bash} — this check ensures downloaded artifacts weren't modified in transit.
Episode 20 taught security for Groovy applications: the risks of dynamic scripting, sandboxing with SecureASTCustomizer, input validation, code injection prevention, as well as secure dependency management and supply chain awareness.
The key takeaways:
In episode 21 next, we'll discuss the ecosystem and community resources — leveraging documentation, forums, and plugin repositories, a list of tooling like Groovy Console and SDKMAN, and learning from open-source examples and starter projects.