3

我正在尝试确保我的 Jersey 请求参数已被清理。

处理 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;
}
4

1 回答 1

5

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

您将太多问题打包成一个“问题”,但我们开始吧:

首先,线条

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

没有做你认为他们正在做的事情。如果您的 JSON 在此处作为原始字符串输入,那么这两个调用将在整个字符串中应用质量规则,当您确实需要以更高的手术精度处理这些时,您似乎至少下意识地意识到了这一点在下一个问题中。

//有没有办法遍历每个JSON KeyValue并在这里过滤?

这个问题的部分重复。

当您处于此处讨论的循环中时,您可以执行任何您想要的数据转换,但您真正应该考虑的是使用JSONObject第一个链接中引用的类。 然后,您将 JSON 解析为一个对象,您可以在其中更好地访问 JSON 键/值对。

//我们需要验证每个 DataMap 对象的值吗?有动态的方法吗?

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

就像是:

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

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

^^该语法正在跳过类型检查,但它应该可以让您到达您需要去的地方。

/是否需要整数验证或抛出的异常是否足够好?

我看不出你在哪里用这些代码行抛出异常:

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为 anInteger然后静默调用该Integer.toString()方法。此外,在您的Response.ok( String );通话中,这是您想要的地方encodeForHTML或输出上下文可能是什么。编码方法总是用于向用户输出数据,而规范化你想在接收数据时调用。最后,在这段代码中,我们还有一个错误,您假设您正在处理一个 HTTPParameter。不在代码中的这一点。您将在调用request.getParameter("id"):where的实例中验证 http 参数id不是像整个 JSON 响应或整个 XML 响应那样的大数据块。此时,您应该验证“SafeString”之类的内容

通常在 Java 中有解析库,至少可以让你达到 Java 对象的水平,但在验证方面,你总是要遍历每个项目并剔除任何可能是恶意的东西。

最后一点,在编码时,请牢记这些原则,您的代码会更简洁,您的思考过程也会更加专注:

  1. 用户输入永远不会安全。(是的,即使您已经通过 XSS 过滤器运行它。)
  2. 每当接收数据时使用验证和规范化方法,并在将数据传输到不同上下文时使用编码方法,其中上下文定义为“Html 字段。Http 属性。Javascript 输入等...)
  3. 而不是使用isValidInput()我建议使用的方法,getValidInput()因为它会为您调用规范化,使您必须少提供一个调用。
  4. 在您的数据将被传递到另一种动态语言(如 SQL、groovy、Perl 或 javascript)的任何时候进行编码。
于 2014-10-25T06:18:39.930 回答