最近我在通用 JSR245 portlet 类中发现了这样的函数:
public class MyGenericPortlet extends GenericPortlet {
@Override
public void processAction(ActionRequest rq, ActionResponse rs) throws PortletException{
String actParam = rq.getParameter("myAction");
if( (actParam != null) && (!("").equals(actParam))) {
try{
Method m = this.getClass().getMethod(actParam, new Class[]{ActionRequest.class, ActionResponse.class});
m.invoke(this, new Object[]{rq, rs});
}
catch(Exception e){
setRequestAttribute(rq.getPortletSession(),"error", "Error in method:"+action);
e.printStackTrace();
}
}
else setRequestAttribute(rq.getPortletSession(),"error", "Error in method:"+action);
}
}
这样的代码安全吗?据我所知,可能会出现以下问题:
- 从客户端传输的参数未经检查即可用于调用函数。这使得任何能够将数据传输到相应 portlet 的人都可以调用任何匹配的函数。另一方面,要调用的函数必须具有特定的接口(interface)。通常这样的功能很少见。
- 程序员可能会无意中添加具有相应接口(interface)的功能。由于似乎只能找到公共(public)函数,只要该函数是私有(private)的或 protected ,就不会有问题。
- 错误消息可能会向客户端透露有关软件的信息。这应该不是问题,因为软件本身是开源的。
显然,存在一些可被利用的编程错误。是否还有其他可能发生的不良副作用?我(或开发者)应该如何判断这个功能带来的风险?
如果您认为它是安全的,我想知道为什么。
最佳答案
只有具有特定签名的公共(public)方法才能远程调用,这一点很好。但是,可以通过例如要求对操作方法进行特殊注释来使其更加安全。这表明开发人员特别希望该方法成为可调用的操作。
当前实现可能存在危险的一个现实场景是,开发人员添加一个操作来验证请求中的信息是否安全,然后将请求和响应传递给另一个方法进行实际处理。如果攻击者能够知道委托(delegate)方法的名称,他就可以直接调用它,绕过参数安全验证。
关于java - 表单值上的 getMethod 安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11103329/