表单上的getMethod值是否安全?

时间:2012-06-19 14:38:23

标签: java reflection portlet

最近我在一个通用的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);
      }
    }

这样的代码有多安全?据我所知,可能会出现以下问题:

  1. 从客户端传输的参数未经检查用于调用函数。这允许任何能够将数据传输到相应portlet的人调用任何匹配的函数。另一方面,要调用的函数必须具有特定的接口。通常这种功能非常罕见。
  2. 程序员可能会意外添加具有相应接口的函数。由于似乎只发现了公共函数,因此只要函数是私有函数或受保护函数就没有问题。
  3. 错误消息可以向客户端显示有关软件的信息。这不应该是一个问题,因为软件本身就是开源的。
  4. 显然,存在一些可以利用的编程错误的空间。是否还会出现其他不必要的副作用?我(或开发人员)应如何判断此功能带来的风险?

    如果您认为它是安全的,我想知道原因。

1 个答案:

答案 0 :(得分:1)

只能远程调用具有特定签名的公共方法这一事实。但是,例如,可以通过对动作方法进行特殊注释来使其更加安全。这表明开发人员特意将该方法作为可调用的操作。

当前实现可能很危险的一个现实场景是,当开发人员添加一个动作来验证请求中的信息是否安全时,然后将请求和响应传递给另一个方法进行实际处理。如果攻击者可以学习委托方法的名称,他可以直接调用它,绕过参数安全验证。