[英]Issue: Jersey umarshalls parameter QueryParam/PathParam as null
[英]How to Modify QueryParam and PathParam in Jersey 2
我正在尝试过滤/修改Post和Put调用,以确保从HTML和JS代码中过滤用户提供的所有参数,以防止XSS攻击。 我想确保这是在API级别实现的,因此无论使用何种客户端,它都将受到保护。
使用Jersey 1.x,可以通过实现ContainerRequestFilter并在与请求的servlet匹配之前修改request.getQueryParameters()来实现。 示例: http : //codehustler.org/blog/jersey-cross-site-scripting-xss-filter-for-java-web-apps/
然而,对于Jersey 2,通过实现相同的接口是不可能的,因为我们不能再使用getParameters()或getPathParameters(),而是我们只能getUriInfo(),但是由于查询参数是不可变的,所以它没用。 我查看了Jersey的过滤器和拦截器,但遗憾的是它们只能访问标题和Cookie。
我花了很多时间研究,但我找不到我想要的东西。
有没有其他方法来过滤路径和查询参数? 有什么我想念的吗?
谢谢!
我在下面添加了一个适用于Jersey 2.x的过滤器。 但是,它没有执行Cookie的XSS修复,因为我还没有找到修改它们的方法。
需要注意的是,这需要与POJO属性上的@SafeHtml结合使用,以便清理这些值。
@PreMatching
public class XSSFilter implements ContainerRequestFilter
{
/**
* @see ContainerRequestFilter#filter(ContainerRequest)
*/
@Override
public void filter( ContainerRequestContext request )
{
cleanQueryParams( request );
cleanHeaders( request.getHeaders() );
}
/**
* Replace the existing query parameters with ones stripped of XSS vulnerabilities
* @param request
*/
private void cleanQueryParams( ContainerRequestContext request )
{
UriBuilder builder = request.getUriInfo().getRequestUriBuilder();
MultivaluedMap<String, String> queries = request.getUriInfo().getQueryParameters();
for( Map.Entry<String, List<String>> query : queries.entrySet() )
{
String key = query.getKey();
List<String> values = query.getValue();
builder.replaceQueryParam( key );
for( String value : values ) {
builder.replaceQueryParam( key, Utils.stripXSS( value ) );
}
}
request.setRequestUri( builder.build() );
}
/**
* Replace the existing headers with ones stripped of XSS vulnerabilities
* @param headers
*/
private void cleanHeaders( MultivaluedMap<String, String> headers )
{
for( Map.Entry<String, List<String>> header : headers.entrySet() )
{
String key = header.getKey();
List<String> values = header.getValue();
List<String> cleanValues = new ArrayList<String>();
for( String value : values ) {
cleanValues.add( Utils.stripXSS( value ) );
}
headers.put( key, cleanValues );
}
}
}
stripXSS函数如下:
/**
* Strips any potential XSS threats out of the value
*
* @param value
* @return
*/
public static String stripXSS( String value )
{
return stripXSS( value, Whitelist.none() );
}
/**
* Strips any potential XSS threats out of the value excluding
* the white listed HTML
*
* @param value
* @param whitelist
* @return
*/
public static String stripXSS( String value, Whitelist whitelist )
{
if( StringUtils.isBlank( value ) )
return value;
// Use the ESAPI library to avoid encoded attacks.
value = ESAPI.encoder().canonicalize( value );
// Avoid null characters
value = value.replaceAll("\0", "");
// Clean out HTML
Document.OutputSettings outputSettings = new Document.OutputSettings();
outputSettings.escapeMode( EscapeMode.xhtml );
outputSettings.prettyPrint( false );
value = Jsoup.clean( value, "", whitelist, outputSettings );
return value;
}
还更新了原帖: http : //codehustler.org/blog/jersey-cross-site-scripting-xss-filter-for-java-web-apps/
您可以使用ContainerRequestFilter,构造一个新URI(基于现有URI),并通过setRequestUri方法在ContainerRequestContext中设置URI。
@PreMatching
public class MyFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
UriBuilder builder = requestContext.getUriInfo().getRequestUriBuilder();
// Replace a query param
builder.replaceQueryParam("foo", "bar");
// Remove a query param
builder.replaceQueryParam("baz");
// Replace path
builder.replacePath("newPath");
requestContext.setRequestUri(builder.build());
}
}
然而,通过这种方法,我还没有找到一种方法来替换匹配的Jersey资源的URI模板中基于param名称的单个路径参数,因为“setRequestUri”仅允许在资源前匹配阶段。 因此需要更换整个路径。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.