Safeguard
Application Security•

CWE-108 Struts Unvalidated Action Form: Map Every Form

Every Struts Action Form needs a validation form. CWE-108 explains the gap, how to audit your mappings, and how to close it.

Safeguard Security Team
3 min read

CWE-108, Struts: Unvalidated Action Form, states a rule in its description: every Action Form must have a corresponding validation form. If a Struts action form mapping specifies a form, the form must have a validation form defined under the Struts Validator.

When that pairing is missing, the form is a door with no lock, and nobody sees it because nothing fails.

How it happens

An action mapping names a form bean. The Validator looks up a validation form with the same name. If none exists, there is nothing to apply and the request goes through.

<action path="/updateProfile" type="app.UpdateProfileAction"
        name="profileForm" validate="true" scope="request"/>
<!-- validation.xml has no <form name="profileForm"> entry -->

Setting validate="true" gives a false sense of safety here. The flag asks for validation, but with no rules the check is empty.

What an attacker gains

MITRE says an action form mapping without a validation form may be vulnerable to a number of attacks that rely on unchecked input. It calls unchecked input the root cause of some of today's worst and most common software security problems: cross-site scripting, SQL injection and process control. The usual J2EE note applies too: native code without bounds checking can turn an input mistake into a buffer overflow.

How to find it

MITRE lists no detection method for this entry. Build a list of every form name used in action mappings, then a list of every form defined in validation configuration. Any name in the first list and not the second is a finding. This is easy to script and worth adding to your build.

How to fix it

MITRE's guidance: map every Action Form to a corresponding validation form. An action or a form may validate in other ways, but the Struts Validator provides an excellent way to verify that all input receives at least a basic level of validation. Without this approach, MITRE says, it is difficult and often impossible to establish with high confidence that all input is validated.

That last point is the real argument. You can audit a configuration file in minutes. You cannot audit scattered checks in every action with the same confidence.

<form name="profileForm">
  <field property="displayName" depends="required,maxlength">
    <arg position="0" name="maxlength" key="${var:maxlength}" resource="false"/>
    <var><var-name>maxlength</var-name><var-value>60</var-value></var>
  </field>
</form>

Quick check

The mapping says validate="true". Is the form protected?

Not necessarily. Without a validation form of the same name, there are no rules to apply, and the check passes everything.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.