Use a Java DTO (data transfer object) wherever data crosses a boundary, such as an HTTP request or response, so the shape of the payload is separate from your domain or database entity. For security, a request DTO that lists only editable fields prevents mass assignment. It does not replace authorization checks.
What is a DTO and why does Java keep recommending it?
A DTO is a plain object that carries data, with no business logic. The reason to use one is decoupling. Your entity can have fifteen fields, including internal flags and audit columns. The API might expose four. A DTO states exactly which four.
Java records, finalized in JDK 16 by JEP 395, are a natural fit. JEP 395 describes a record as an object oriented construct that expresses a simple aggregation of values, helps developers model immutable data, and automatically implements methods such as equals and accessors. The JEP also says it is not a goal to wage a "war on boilerplate", so records are a tool for data carriers, not a replacement for every class.
How do DTOs prevent mass assignment?
OWASP describes mass assignment as frameworks automatically binding HTTP request parameters into program objects. An attacker can add a parameter the developer never intended, which creates or overwrites fields in code that should not have been touched. Different frameworks call it autobinding, object injection or mass assignment. MITRE tracks the weakness as CWE-915, improperly controlled modification of dynamically determined object attributes.
OWASP's guidance is direct: prefer dedicated input objects such as DTOs that contain only fields the caller may edit, and explicitly allow list fields when binding to an object with additional properties. It warns not to rely on a block list as the sole protection, since a new or overlooked sensitive field remains bindable.
What does the fix look like?
A constructed example. The risky version binds a request straight to an entity:
// Risky: the request body can set every field on User, including isAdmin
@PostMapping("/users/me")
public User update(@RequestBody User user) { return repo.save(user); }
The safer version accepts only a record:
public record UpdateProfileRequest(String displayName, String email) {}
@PostMapping("/users/me")
public UserView update(@RequestBody UpdateProfileRequest req, Principal who) {
User u = repo.findByLogin(who.getName());
u.setDisplayName(req.displayName());
u.setEmail(req.email());
return UserView.from(repo.save(u));
}
If a caller adds an isAdmin property to the JSON, there is nowhere for it to land. The response type, UserView, also decides what leaves the system, so password hashes and internal ids stay inside.
What do DTOs not do?
OWASP is explicit that DTOs and field allow lists restrict writable properties but do not replace authorization for the requested object and operation. If the endpoint lets user A pass user B's id, a tidy DTO will not help. You still need ownership checks.
DTOs also add mapping code. Mapping by hand is verbose but obvious. Mapping libraries reduce the typing but can quietly copy fields you meant to skip, so test the mapping for sensitive fields.
When is a DTO overkill?
Inside a single service layer where objects never cross a trust boundary, passing the entity may be fine. The line to draw is the boundary: HTTP, message queues, files and anything a user or another system can shape. Cross it with a purpose built type.
How to check or apply this
- Search for controller methods that accept entity or domain classes as request bodies.
- Create a request DTO per operation, with only the fields that operation may change.
- Use records for DTOs where your JDK allows it, since fields are immutable.
- Return response DTOs as well, so internal fields do not leak.
- Keep authorization checks in the service layer, tied to the user and the object.
- Add a test that posts an extra field such as isAdmin and asserts it is ignored or rejected.
- Prefer allow lists to block lists wherever the framework binds fields automatically.
Quick check
Are Java records safe to use as request DTOs?
They are well suited, since they are immutable data carriers. Safety still depends on which fields you include and on authorization elsewhere.
Does a DTO stop insecure direct object references?
No. That needs an ownership or permission check on the object being accessed.
Sources
Last reviewed: 18 October 2026.