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.

Configuration

This detector does not need any configuration.

References

© 2026 Xygeni. All rights reserved