1.实体对象常见分类
在 Java Web 项目里,常见的实体类可以分成 3 类:
- 直接映射数据库表,一般在 entity/pojo/model/domain 包里。
- 字段多,几乎和数据库列一一对应:id, role, balance, status, password 等。
- 典型注解:@Entity、@Table、@Id(JPA),或者只是 MyBatis 的 POJO。
- 用来做“数据搬运”,封装接口输入输出。
- 字段只包含 业务需要的内容,不会完整等同数据库字段。
- 常在 dto、vo、form 包里。
比如 UserUpdateForm、LoginRequestDto。
- 更贴近页面/接口的输入输出。
- 和 DTO 很像,有的项目里 DTO 和 Form/VO 不严格区分。
2. 如何区分绑定的是 Entity 还是 DTO?
审计时可以从这几个角度判断:
包路径:
com.xxx.entity、com.xxx.model → 多半是持久化实体。
com.xxx.dto、com.xxx.form、com.xxx.vo → 基本就是 DTO/表单对象。
字段内容:
如果类里有 id、role、isAdmin、balance、status、createTime → 高度怀疑是数据库实体。
如果类只包含业务输入字段(比如 email, nickname)→ 这是 DTO。
是否有 ORM 注解:
@Entity, @Table, @Column, @Id → 这是持久化实体。
DTO 一般没有数据库映射注解。
命名习惯:
User → 常见的是数据库实体。
UserUpdateForm, UserDto, LoginRequest → 一看就是 DTO/表单对象。
3. 你给的两个代码示例对比
❌ 例1:绑定 Entity
@PostMapping("/update")
public String updateUser(@ModelAttribute User user) {
userService.update(user);
return "ok";
}
这里的 User 大概率是 数据库实体(包含敏感字段)。
Spring MVC 会自动把 HTTP 参数填充进 User 对象。
如果攻击者多传一个 role=admin,就能直接覆盖数据库里的角色字段。
风险点:关键参数篡改漏洞。
✅ 例2:绑定 DTO
@PostMapping("/update")
public String updateUser(@ModelAttribute UserUpdateForm form, Principal principal) {
User user = userService.findByUsername(principal.getName());
user.setEmail(form.getEmail());
user.setNickname(form.getNickname());
userService.update(user);
return "ok";
}
这里的 UserUpdateForm 是 DTO(只包含 email、nickname)。
用户传 role=admin,Spring MVC 也找不到对应字段,不会赋值。
最终 userService.update(user) 时,只有允许修改的字段被更新。
安全性:避免了关键参数篡改。
4.总结
Entity(持久化实体):字段多,映射数据库,绝不能直接用来绑定前端输入。
DTO/Form(数据传输对象/表单对象):只暴露安全字段,推荐绑定。
👉 在你看代码时,如果看到 Controller 方法直接用 Entity 做参数,审计结论就是:
“存在关键参数篡改风险,应改用 DTO/Form 对象或增加字段白名单限制”。
Entity vs DTO/Form 对比表
| 对比维度 | Entity(持久化实体) | DTO/Form(数据传输/表单对象) |
|---|---|---|
| 字段组成 | 基本等同数据库表的全部字段:id, role, isAdmin, balance, createTime, status … | 只包含业务输入/输出需要的字段,例如 email, nickname, passwordConfirm |
| 用途 | 映射数据库表,用于 ORM(JPA、Hibernate、MyBatis),直接存取数据库 | 用于接口请求/响应的数据交换,不直接映射数据库 |
| 常见位置 | 包路径:entity/pojo/model/domain,常带 ORM 注解(@Entity, @Table) | 包路径:dto/form/vo/request/response,一般没有 ORM 注解 |
| 典型特征 | 字段多且全面,包含敏感字段(如权限、余额、主键 id) | 精简、面向业务场景,只暴露安全字段 |
| 示例类名 | User, Order, Account | UserUpdateForm, LoginRequestDto, OrderResponseVo |
| 安全风险 | ❌ 如果直接绑定到 HTTP 请求,攻击者可篡改敏感字段(如 role=admin、balance=99999) → 关键参数篡改漏洞 | ✅ 只包含允许修改/返回的字段,不会暴露敏感字段,避免篡改风险 |
| 审计提示 | 🔍 重点关注 Controller 方法参数是否直接使用 Entity,例如:public String update(@ModelAttribute User user) ⚠️ 风险点:敏感字段可能被篡改 | 审计结论:绑定 DTO/Form 通常是安全做法,但要确认 DTO 中是否仍然意外包含敏感字段 |
| 最佳实践 | - 不直接暴露给前端请求绑定 - Entity ↔ DTO 转换在 Service 层或使用 MapStruct 等工具 | - 每个接口专门定义输入/输出 DTO - DTO 字段经过严格白名单控制 |
“Entity 全表字段,DTO 精选字段。Entity 不能绑输入,DTO 专绑输入。”

被折叠的 条评论
为什么被折叠?



