Ajax 请求 XSS 过滤器
Ajax request XSS filter
在我们的应用程序中,我们有一个 XSS 过滤器,它处理每个请求并检查值..
但是我们发现了请求是 Ajax 而我们的过滤器不起作用的情况..
当 AJAX 请求完成时它不起作用:
$.ajax({
url: '${someUrl}' ,
type: 'POST',
cache: false,
data: JSON.stringify(checkForm),
dataType: 'json',
contentType: 'application/json',
这里的值是 JSON 格式,看起来像:
{"poNumber":"123144","voucher":"","quoteNumber":"","collectNumber":"","otherCarrier":"","deliveryMethodCode":"21","paymentMethodCode":"invoice","concerns":""}
它在以下情况下有效:
ACC.pg = {
addToCart: function() {
var productCode = $(this).data("productcode");
var params = {
"productCodePost": productCode,
"qty": 1
};
$.post("${url}", params, ACC.quickordercustom.handleSuccess);
数量=1&productCodePost=12123
过滤器从请求中获取参数,例如
Map<String,String[]> params = req.getParameterMap();
for (Map.Entry<String,String[]> entry : params.entrySet()) {
String v[] = entry.getValue();
....
}
但是对于案例 1,req.getParameterMap()
是空的..有什么建议吗?
谢谢
Y
servlet 请求的参数是从 URL 参数填充的,并且 - 如果是内容类型为 application/x-www-form-urlencoded
的 POST 请求 - 来自已解析的请求正文。
由于您在情况 1 中发送 JSON 负载,因此参数映射为空。
以下是我的做法,以防有人感兴趣。
正如在 "wero" 的评论中所说,参数是从 url 或请求主体中填充的,具体取决于方法(POST 或 GET)..
所以,在我的例子中,我有 JSON 个对象,我需要读取它,执行 stripXSS 并再次包装它,然后 doFilter ..
这就是我识别 Ajax 请求的方式
final HttpServletRequest httpServletRequest = ((HttpServletRequest) paramServletRequest);
final boolean ajax = "XMLHttpRequest".equals(httpServletRequest.getHeader("X-Requested-With"));
所有这些都在过滤器中进行,所以接下来是读取 JSON 对象并执行 stripXSS
private String jsonToString(final HttpServletRequest httpServletRequest) throws IOException
{
final StringBuilder buffer = new StringBuilder();
final BufferedReader reader = httpServletRequest.getReader();
String line;
while ((line = reader.readLine()) != null)
{
buffer.append(line);
}
final String data = buffer.toString();
return data;
}
还有 stripXSS,模式在配置文件中定义
private String stripXSS(String value)
{
if ((value != null) && (value.length() > 0))
{
for (final Pattern scriptPattern : patterns)
{
value = scriptPattern.matcher(value).replaceAll("");
}
}
return value;
}
请求被消费后,我们需要将其包装起来,以便其他消费者能够阅读。
public class AjaxXSSRequestWrapper extends HttpServletRequestWrapper
{
private final ServletInputStream inputStream;
/**
* @param request
*/
public AjaxXSSRequestWrapper(final HttpServletRequest request, final ServletInputStream inputStream)
{
super(request);
this.inputStream = inputStream;
}
/*
* (non-Javadoc)
*
* @see javax.servlet.ServletRequestWrapper#getInputStream()
*/
@Override
public ServletInputStream getInputStream() throws IOException
{
return this.inputStream;
}
}
在这个例子中,只有 getInputStream 被重写,但你也可以为其他方法重写..
最后..
paramFilterChain.doFilter(requestWrapper, paramServletResponse);
使用 JSR-303 和 @SafeHtml 将表单值转换为对象后,您始终可以清除表单值。
看这里的例子:
在我们的应用程序中,我们有一个 XSS 过滤器,它处理每个请求并检查值..
但是我们发现了请求是 Ajax 而我们的过滤器不起作用的情况..
当 AJAX 请求完成时它不起作用:
$.ajax({
url: '${someUrl}' ,
type: 'POST',
cache: false,
data: JSON.stringify(checkForm),
dataType: 'json',
contentType: 'application/json',
这里的值是 JSON 格式,看起来像:
{"poNumber":"123144","voucher":"","quoteNumber":"","collectNumber":"","otherCarrier":"","deliveryMethodCode":"21","paymentMethodCode":"invoice","concerns":""}
它在以下情况下有效:
ACC.pg = {
addToCart: function() {
var productCode = $(this).data("productcode");
var params = {
"productCodePost": productCode,
"qty": 1
};
$.post("${url}", params, ACC.quickordercustom.handleSuccess);
数量=1&productCodePost=12123
过滤器从请求中获取参数,例如
Map<String,String[]> params = req.getParameterMap();
for (Map.Entry<String,String[]> entry : params.entrySet()) {
String v[] = entry.getValue();
....
}
但是对于案例 1,req.getParameterMap()
是空的..有什么建议吗?
谢谢 Y
servlet 请求的参数是从 URL 参数填充的,并且 - 如果是内容类型为 application/x-www-form-urlencoded
的 POST 请求 - 来自已解析的请求正文。
由于您在情况 1 中发送 JSON 负载,因此参数映射为空。
以下是我的做法,以防有人感兴趣。
正如在 "wero" 的评论中所说,参数是从 url 或请求主体中填充的,具体取决于方法(POST 或 GET)..
所以,在我的例子中,我有 JSON 个对象,我需要读取它,执行 stripXSS 并再次包装它,然后 doFilter ..
这就是我识别 Ajax 请求的方式
final HttpServletRequest httpServletRequest = ((HttpServletRequest) paramServletRequest);
final boolean ajax = "XMLHttpRequest".equals(httpServletRequest.getHeader("X-Requested-With"));
所有这些都在过滤器中进行,所以接下来是读取 JSON 对象并执行 stripXSS
private String jsonToString(final HttpServletRequest httpServletRequest) throws IOException
{
final StringBuilder buffer = new StringBuilder();
final BufferedReader reader = httpServletRequest.getReader();
String line;
while ((line = reader.readLine()) != null)
{
buffer.append(line);
}
final String data = buffer.toString();
return data;
}
还有 stripXSS,模式在配置文件中定义
private String stripXSS(String value)
{
if ((value != null) && (value.length() > 0))
{
for (final Pattern scriptPattern : patterns)
{
value = scriptPattern.matcher(value).replaceAll("");
}
}
return value;
}
请求被消费后,我们需要将其包装起来,以便其他消费者能够阅读。
public class AjaxXSSRequestWrapper extends HttpServletRequestWrapper
{
private final ServletInputStream inputStream;
/**
* @param request
*/
public AjaxXSSRequestWrapper(final HttpServletRequest request, final ServletInputStream inputStream)
{
super(request);
this.inputStream = inputStream;
}
/*
* (non-Javadoc)
*
* @see javax.servlet.ServletRequestWrapper#getInputStream()
*/
@Override
public ServletInputStream getInputStream() throws IOException
{
return this.inputStream;
}
}
在这个例子中,只有 getInputStream 被重写,但你也可以为其他方法重写..
最后..
paramFilterChain.doFilter(requestWrapper, paramServletResponse);
使用 JSR-303 和 @SafeHtml 将表单值转换为对象后,您始终可以清除表单值。
看这里的例子: