我正在努力确保我的泽西请求参数被清理.
处理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.