Expression injection (OGNL)
ID |
scala.inject.scala_inject_rule_ognlinjection |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
medium |
Resource |
Inject |
Language |
Scala |
Description
A expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation.
Rationale
A expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation.
The following code illustrates a vulnerable pattern detected by this rule:
// OGNL reaches the whole object graph and can call methods, so an expression chosen by the
// caller is remote code execution rather than a lookup.
class ExpressionBinding {
@throws[OgnlException]
@throws[ReflectionException]
def fromTheCaller(ognlUtil: OgnlUtil, expression: String, values: util.HashMap[String,String]): Unit = {
// VULNERABLE: Expression injection (OGNL)
ognlUtil.setValue(expression, null, null, "42")
// VULNERABLE: Expression injection (OGNL)
ognlUtil.getValue(expression, null, null, null)
// VULNERABLE: Expression injection (OGNL)
ognlUtil.setProperty(expression, "42", null, null)
// VULNERABLE: Expression injection (OGNL)
ognlUtil.setProperty(expression, "42", null, null, true)
// VULNERABLE: Expression injection (OGNL)
ognlUtil.setProperties(values, new Object())
// VULNERABLE: Expression injection (OGNL)
ognlUtil.setProperties(values, null, null, true)
// VULNERABLE: Expression injection (OGNL)
ognlUtil.setProperties(values, null, true)
// VULNERABLE: Expression injection (OGNL)
ognlUtil.setProperties(values, null)
// VULNERABLE: Expression injection (OGNL)
ognlUtil.compile(expression)
// VULNERABLE: Expression injection (OGNL)
ognlUtil.compile(expression)
}
@throws[OgnlException]
@throws[ReflectionException]
def fromAConstant(ognlUtil: OgnlUtil): Unit = {
val expression = "order.total"
val values = new util.HashMap[String,String]()
ognlUtil.setValue(expression, null, null, "42")
ognlUtil.getValue(expression, null, null, null)
ognlUtil.setProperty(expression, "42", null, null)
ognlUtil.setProperty(expression, "42", null, null, true)
ognlUtil.setProperties(values, null, null)
ognlUtil.setProperties(values, null, null, true)
ognlUtil.setProperties(values, null, true)
ognlUtil.setProperties(values, null)
ognlUtil.compile(expression)
ognlUtil.compile(expression)
}
@throws[ReflectionException]
@throws[IntrospectionException]
def throughTheReflectionProvider(expression: Nothing, values: Nothing, unused: Nothing, `type`: Nothing): Unit = {
var provider: OgnlReflectionProvider = null
provider.getGetMethod(`type`, expression)
provider.getSetMethod(`type`, expression)
provider.getField(`type`, expression)
provider.setProperties(values, null, null, true)
provider.setProperties(values, null, null)
provider.setProperties(values, null)
provider.setProperty(expression, "order", null, null)
provider.getValue(expression, null, null)
provider.setValue(expression, null, null, null)
}
@throws[IntrospectionException]
@throws[ReflectionException]
def throughTheReflectionProviderFromConstants(unused: Nothing, `type`: Nothing): Unit = {
var provider: OgnlReflectionProvider = null
val expression = "order.total"
val empty = ""
val values = new util.HashMap[String,String]()
provider.getGetMethod(`type`, expression)
provider.getSetMethod(`type`, expression)
provider.getField(`type`, expression)
provider.setProperties(values, null, null, true)
provider.setProperties(values, null, null)
provider.setProperties(values, null)
provider.setProperty("order", empty, null, null)
provider.getValue(expression, null, null)
provider.setValue(expression, null, null, null)
}
def throughTextParseUtilFromAConstant(stack: Nothing, evaluator: Nothing, `type`: Nothing): Unit = {
val expression = "1+1"
TextParseUtil.translateVariables(expression, stack)
TextParseUtil.translateVariables(expression, stack, evaluator)
TextParseUtil.translateVariables('a', expression, stack)
TextParseUtil.translateVariables('a', expression, stack, `type`)
TextParseUtil.translateVariables('a', expression, stack, `type`, evaluator, 0)
}
}
Remediation
Follow secure coding practices and review the references below for detailed remediation guidance.
References
-
OWASP Top 10 2025 - A05 : Injection.