背景:我用ModelDriven编码了一个struts2 ActionSupport类。这是一个休眠/春季Web应用程序,在视图(JSP)中使用OSIV和附加的实体。
我今天收到建筑师发出的这封电子邮件,“惩罚”我放置物体
通过引用了struts2值堆栈上的附加实体ModelDriven<E>
界面。他是正确的还是什么?显然,这是我正在做的一件严肃的事情,但我没有听从他在说什么,而且我真的不希望接受他的提议并在此之后在他的办公桌前拜访他。好家伙。是时候改变职业了。
---来自建筑师---
比利,正如我们之前讨论的那样,您仍然在代码中犯同样的错误
一遍又一遍地。这是您第四次犯此错误,我很担心
关于您的工作质量。一次甚至两次是一回事,但是
第四次之后,我想知道您是否无法理解我在说什么。以下内容将为您详细说明。如果您在阅读完此电子邮件后仍未收到邮件,请到我的办公桌前进行处理。这必须立即停止,我希望所有人
您的代码会在一天结束前进行重构,以更正此错误。如果有类似的代码
流血到生产中,我们将面临严重的安全问题。另请注意,我正在此上复制戴夫,以便可以发出适当的谴责。我还将建议Dave将您从III级开发人员转移到II级开发人员。阅读以下内容,然后学习它,并按照我的指示重构所有代码。
关于绑定对象:
当Struts2动作类标记有ModelDriven接口时,该模型
将绑定到HTML页面中的表单元素。例如,如果是HTML表单
有一个名为userName的字段,并且操作类定义为:
公共类UserAction扩展ActionSupport实现ModelDriven
UserModel是一个POJO,如下所示:
public class UserModel {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
提交表单后,只要Action包含UserModel,struts2的实例
将字段userName绑定到UserModel.userName,自动填充值。
然而,这种简单性对于恶意用户而言具有高成本。如果声明了一个对象
作为ModelDriven,最终用户(即浏览用户)有权访问模型图
通过模型设置器。以这种情况为例:
公共类UserAction扩展ActionSupport实现ModelDriven
和...
public class UserModel {
private String userName;
private UserEntity userEntity;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
pubic UserEntity getUserEntity() {
return userEntity;
}
}
和...
@Entity
public class UserEntity {
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
假设正在使用OSIV模式,并且已附加实体UserEntity。
一个狡猾的用户,如果手上有一些先验知识或时间,可能会:
/myform?userName=billy&userEntity.password=newpassword
假设实体是在会话结束时保存的,则上述结果会导致更改
比利的密码。
关键是,对象图可用!
使用ModelDriven时,使用替代方法是一种可怕的方法,您必须定义
将细粒度的模型放在值堆栈上,然后将其从模型复制到
发送响应并允许事务提交之前的目标对象。
最佳答案
您的架构师是正确的,将可以访问敏感信息的对象放在ValueStack上会带来潜在的安全风险。恶意用户确实可以通过上述攻击来重置密码。
但:
由于他是一名建筑师,因此他应该设计出一些方法来正确验证/限制输入参数。在Struts2中使用ParamsInterceptor,仅允许将特定参数传递给动作是相当容易的。因此,糟糕的不是您的工作,而是系统的体系结构。
开发人员应该能够专注于实现业务逻辑。基础结构必须由架构师提供。
干杯,
w