On one side, Spring MVC automatically bind request parameters to beans declared as arguments of methods annotated with
@RequestMapping
. Because of this automatic binding feature, it's possible to feed some unexpected fields on the arguments of the
@RequestMapping
annotated methods.
On the other end, persistent objects (@Entity
or @Document
) are linked to the underlying database and updated
automatically by a persistence framework, such as Hibernate, JPA or Spring Data MongoDB.
These two facts combined together can lead to malicious attack: if a persistent object is used as an argument of a method annotated with
@RequestMapping
, it's possible from a specially crafted user input, to change the content of unexpected fields into the database.
For this reason, using @Entity
or @Document
objects as arguments of methods annotated with @RequestMapping
should be avoided.
In addition to @RequestMapping
, this rule also considers the annotations introduced in Spring Framework 4.3: @GetMapping
,
@PostMapping
, @PutMapping
, @DeleteMapping
, @PatchMapping
.
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 WishListController { @PostMapping(path = "/saveForLater") public String saveForLater(Wish wish) { session.save(wish); } @RequestMapping(path = "/saveForLater", method = RequestMethod.POST) public String saveForLater(Wish wish) { session.save(wish); } }
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 { @PostMapping(path = "/saveForLater") public String saveForLater(WishDTO wish) { Wish persistentWish = new Wish(); // do the mapping between "wish" and "persistentWish" [...] session.save(persistentWish); } @RequestMapping(path = "/saveForLater", method = RequestMethod.POST) public String saveForLater(WishDTO wish) { Wish persistentWish = new Wish(); // do the mapping between "wish" and "persistentWish" [...] session.save(persistentWish); } }
No issue is reported when the parameter is annotated with @PathVariable
from Spring Framework, since the lookup will be done via id,
the object cannot be forged on client side.