Java Jersey REST请求参数卫生

我正在努力确保我的泽西请求参数被清理.

处理Jersey GET请求时,是否需要过滤非String类型?
例如,如果提交的参数是一个整数,则选项1(getIntData)和选项2(getStringData)黑客都安全吗?那么JSON PUT请求,我的ESAPI实现是否足够,或者我需要在映射后验证每个数据参数?它可以在映射之前进行验证吗?

泽西休息示例类:

public class RestExample {

//Option 1 Submit data as an Integer
//Jersey throws an internal server error if the type is not Integer
//Is that a valid way to validate the data?

//Integer Data, not filtered
@Path("/data/int/{data}/")
@GET
@Produces(MediaType.TEXT_HTML)
public Response getIntData(@PathParam("data") Integer data){
    return Response.ok("You entered:" + data).build();  
}

//Option 2 Submit data as a String, then validate it and cast it to an Integer

//String Data, filtered
@Path("/data/string/{data}/")
@GET
@Produces(MediaType.TEXT_HTML)
public Response getStringData(@PathParam("data") String data) {
    data = ESAPI.encoder().canonicalize(data);
    if (ESAPI.validator().isValidInteger("data", data, 0, 999999, false))
    {
        int intData = Integer.parseInt(data);
        return Response.ok("You entered:" + intData).build();   
    }
    return Response.status(404).entity("404 Not Found").build();
}

//JSON data, HTML encoded
@Path("/post/{requestid}")
@POST
@Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON})
@Produces(MediaType.TEXT_HTML)
public Response postData(String json) {
    json = ESAPI.encoder().canonicalize(json);
    json = ESAPI.encoder().encodeForHTML(json);

    //Is there a way to iterate through each JSON KeyValue and filter here?

    ObjectMapper mapper = new ObjectMapper();
    DataMap dm = new DataMap();
    try {
        dm = mapper.readValue(json, DataMap.class);
    } catch (Exception e) {
        e.printStackTrace();
    } 

    //Do we need to validate each DataMap object value and is there a dynamic way to do it?
    if (ESAPI.validator().isValidInput("strData", dm.strData, "HTTPParameterValue", 25, false, true)) 
    {
        //Is Integer validation needed or will the thrown exception be good enough?
        return Response.ok("You entered:" + dm.strData + " and " + dm.intData).build();
    }
    return Response.status(404).entity("404 Not Found").build();
}
}

数据图类:

public class DataMap {

public DataMap(){}

String strData;
Integer intData;
}

解决方法:

简短的回答是肯定的,虽然通过“过滤器”我将其解释为“验证”,因为没有多少“过滤”将为您提供安全数据.您仍然可以在Java中遇到整数溢出,虽然这些可能没有直接的安全问题,但它们仍然可以将您的应用程序的某些部分置于计划外的状态,并且黑客攻击是以您可以控制的方式扰乱系统.

你把太多问题打包成一个“问题”,但我们走了:

首先,线路

json = ESAPI.encoder().canonicalize(json);
json = ESAPI.encoder().encodeForHTML(json);

不做你认为他们正在做的事情.如果你的JSON在这里作为一个原始字符串进入,这两个调用将在整个字符串中应用质量规则,当你真的需要以更高的手术精度处理这些时,你似乎至少在潜意识里意识到在下一个问题.

//Is there a way to iterate through each JSON KeyValue and filter
here?

this question.的部分副本

当您处于此处讨论的循环中时,您可以执行所需的任何数据转换,但您应该考虑的是使用第一个链接中引用的JSONObject类. Then you’ll have JSON parsed into an object where you’ll have better access to JSON key/value pairs.

//Do we need to validate each DataMap object value and is there a
dynamic way to do it?

是的,我们验证来自用户的所有内容.假设所有用户都是训练有素的黑客,并且比你聪明.但是,如果在进行数据映射转换之前处理过滤,则无需再次执行此操作.动态地做吗?

就像是:

JSONObject json = new JSONObject(s);
Iterator iterator = json.keys();

while( iterator.hasNext() ){
  String data = iterator.next();
  //filter and or business logic
}

^^该语法正在跳过typechecks,但它应该可以让你到达你需要去的地方.

/Is Integer validation needed or will the thrown exception be good
enough?

我没有看到你用这些代码行抛出异常的地方:

if (ESAPI.validator().isValidInput("strData", dm.strData, "HTTPParameterValue", 25, false, true)) 
{
    //Is Integer validation needed or will the thrown exception be good enough?
    return Response.ok("You entered:" + dm.strData + " and " + dm.intData).build();
}

首先,在java中我们有自动装箱,这意味着:

int foo = 555555;
String bar = "";
//the code
foo + bar; 

将在任何实例中强制转换为字符串.编译器将int提升为Integer,然后以静默方式调用Integer.toString()方法.另外,在Response.ok(String)中; call,这就是你想要编码FORHTML或输出上下文的地方.编码方法总是用于向用户输出数据,而规范化则在接收数据时要调用.最后,在这段代码中,我们还有一个错误,您假设您正在处理HTTPParameter.不是在代码中的这一点.您将在调用request.getParameter(“id”)的实例中验证http参数:其中id不是一大堆数据,如整个JSON响应或整个XML响应.此时你应该验证“SafeString”之类的东西

通常在Java中存在解析库,它们至少可以使您达到Java对象的级别,但在验证方面,您总是会运行每个项目并将任何可能恶意的内容放入其中.

最后请注意,在编码时,请牢记这些原则,您的代码将更清晰,您的思维过程更加集中:

>用户输入永远不会安全. (是的,即使您通过XSS过滤器运行它.)
>每当接收数据时使用validate和canonicalize方法,并在将数据传输到不同的上下文时编码方法,其中上下文被定义为“Html字段.Http属性.Javascript输入等…”
>而不是使用方法isValidInput()我建议使用getValidInput(),因为它将为您调用canonicalize,使您不得不提供少一个调用.
>编码将数据传递给另一种动态语言的任何时间,如SQL,groovy,Perl或javascript.

上一篇:java – 解析媒体类型’application / json; encoding = utf8,charset = utf-8’时出错


下一篇:java – jersey2单元测试,HttpServletRequest为null