141 lines
4.4 KiB
Plaintext
141 lines
4.4 KiB
Plaintext
With Spring, when a request mapping method is configured to accept bean objects
|
|
as arguments, the framework will automatically bind HTTP parameters to those
|
|
objects' properties. If the targeted beans are also persistent entities, the
|
|
framework will also store those properties in the storage backend, usually the
|
|
application's database.
|
|
|
|
== Why is this an issue?
|
|
|
|
By accepting persistent entities as method arguments, the application allows
|
|
clients to manipulate the object's properties directly.
|
|
|
|
=== What is the potential impact?
|
|
|
|
Attackers could forge malicious HTTP requests that will alter unexpected
|
|
properties of persistent objects. This can lead to unauthorized modifications of
|
|
the entity's state. This is known as a *mass assignment* attack.
|
|
|
|
Depending on the affected objects and properties, the consequences can vary.
|
|
|
|
==== Privilege escalation
|
|
|
|
If the affected object is used to store the client's identity or permissions,
|
|
the attacker could alter it to change their entitlement on the application. This
|
|
can lead to horizontal or vertical privilege escalation.
|
|
|
|
==== Security checks bypass
|
|
|
|
Because persistent objects are modified directly without prior logic, attackers
|
|
could exploit this issue to bypass security measures otherwise enforced by the
|
|
application. For example, an attacker might be able to change their e-mail
|
|
address to an invalid one by directly setting it without going through the
|
|
application's email validation process.
|
|
|
|
The same could also apply to passwords that attackers could change without
|
|
complexity validation or knowledge of their current value.
|
|
|
|
== How to fix it in Java EE
|
|
|
|
=== Code examples
|
|
|
|
The following code is vulnerable to a mass assignment attack because it allows
|
|
modifying the `User` persistent entities thanks to maliciously forged `Wish`
|
|
object properties.
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,java,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
import javax.persistence.Entity;
|
|
|
|
@Entity
|
|
public class Wish {
|
|
Long productId;
|
|
Long quantity;
|
|
Client client;
|
|
}
|
|
|
|
@Entity
|
|
public class Client {
|
|
String clientId;
|
|
String name;
|
|
String password;
|
|
}
|
|
|
|
import org.springframework.stereotype.Controller;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
@Controller
|
|
public class PurchaseOrderController {
|
|
|
|
@RequestMapping(path = "/saveForLater", method = RequestMethod.POST)
|
|
public String saveForLater(Wish wish) { // Noncompliant
|
|
session.save(wish);
|
|
}
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=1,diff-type=compliant]
|
|
----
|
|
public class WishDTO {
|
|
Long productId;
|
|
Long quantity;
|
|
Long clientId;
|
|
}
|
|
|
|
import org.springframework.stereotype.Controller;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
@Controller
|
|
public class PurchaseOrderController {
|
|
|
|
@RequestMapping(path = "/saveForLater", method = RequestMethod.POST)
|
|
public String saveForLater(WishDTO wish) {
|
|
Wish persistentWish = new Wish();
|
|
persistentWish.productId = wish.productId
|
|
persistentWish.quantity = wish.quantity
|
|
persistentWish.client = getClientById(with.clientId)
|
|
session.save(persistentWish);
|
|
}
|
|
}
|
|
----
|
|
|
|
=== How does this work?
|
|
|
|
The compliant code implements a Data Transfer Object (DTO) layer. Instead of
|
|
accepting a persistent `Wish` entity as a parameter, the vulnerable method
|
|
accepts a `WishDTO` object with a safe, minimal set of properties. It then
|
|
instantiates a persistent entity and initializes it based on the DTO properties'
|
|
values. The resulting object can safely be persisted in the database.
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* OWASP - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html[Mass Assignment Cheat Sheet]
|
|
|
|
=== Standards
|
|
|
|
* OWASP - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/[Top 10 2021 - Category A8 - Software and Data Integrity Failures]
|
|
* OWASP - https://owasp.org/www-project-top-ten/2017/A5_2017-Broken_Access_Control[Top 10 2017 - Category A5 - Broken Access Control]
|
|
* CWE - https://cwe.mitre.org/data/definitions/915[CWE-915 - Improperly Controlled Modification of Dynamically-Determined Object Attributes]
|
|
|
|
=== Articles & blog posts
|
|
|
|
OWASP O2 Platform Blog - https://o2platform.files.wordpress.com/2011/07/ounce_springframework_vulnerabilities.pdf[Two Security Vulnerabilities in the Spring Framework's MVC]
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Replace this persistent entity with a simple POJO or DTO object.
|
|
|
|
|
|
endif::env-github,rspecator-view[]
|