如何在Jersey 2中修改QueryParam和PathParam

时间:2015-10-05 00:51:15

标签: java api rest jersey xss

我正在尝试过滤/修改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,这是不可能通过实现相同的接口,因为我们不能再getQueryParameters()或getPathParameters(),但相反,我们只能getUriInfo(),但是因为查询参数它是无用的是不可改变的。我查看了泽西岛的Filters and Interceptors但不幸的是,他们只能访问标题和Cookie。

我花了很多时间研究,但我找不到我想要的东西。

是否有其他方法可以过滤路径和查询参数?有什么我想念的吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

我在下面添加了一个适用于Jersey 2.x的过滤器。但是,它没有执行Cookie的XSS修复,因为我还没有找到修改它们的方法。

需要注意的是,这需要与POJO属性上的@SafeHtml结合使用,以便清理这些值。

$('#export').on('click', function() {
  var sqlsend = dataTable.ajax.json().sql;
  window.location.href="server-side-CSV.php?val="+sqlsend;
});

stripXSS功能如下:

@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 );
        }
    }
}

还更新了原帖:http://codehustler.org/blog/jersey-cross-site-scripting-xss-filter-for-java-web-apps/

答案 1 :(得分:0)

您可以使用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”仅允许在资源前匹配阶段。因此需要更换整条路径。