如何修复HTTP参数/路径污染攻击Spring Rest

时间:2017-07-22 04:56:25

标签: spring rest spring-boot spring-security

从HTTP消息中提取参数并获取资源URL可能容易受到可能会改变预期资源语义的注入攻击。这里有两类攻击:HTTP参数/路径污染(HPPP)和服务器端请求伪造(SSRF)。请记住,我们的攻击者可以完全控制HTTP请求或HTTP响应。

在HPPP(HTTP参数/路径污染攻击)中,参数用于组成用于为资源准备REST请求(或生成嵌入式链接)的资源URL。问题是攻击者可能会改变路径或添加/覆盖“查询字符串”中的意外参数。此外,REST框架可以使用参数(如_method)来允许REST动词的规范与传入的HTTP方法不同,因此GET请求可以被解释为PUT操作。攻击者可能会更改REST资源URL的语义。

查找更多信息here

示例:

例如:如果在查询字符串中测试search_string参数,请求URL将包含该参数名称和值。

http://example.com/?mode=guest&search_string=kittens&num_results=100 

特定参数可能隐藏在其他几个参数中,但方法是相同的;保留其他参数并附加副本。

http://example.com/?mode=guest&search_string=kittens&num_results=100&search_string=puppies 

使用不同的值附加相同的参数

+"<button type='button' class='btn btn-primary' onclick='javascript:checkIn(\""+ JsonParseData[i].businessID + "\");'>Check in</button><br>"+

并提交新请求。

问题:

Spring Rest,Spring MVC和Spring Security并没有为修复HPPP问题提供任何内置支持。我们如何修复Spring框架内部?

1 个答案:

答案 0 :(得分:0)

花了几个小时后,我已经实施了以下解决方案,请告诉我你是否有更好的方法来处理它。

1)我添加了实现HandlerInterceptor

的CustomHandler

2)覆盖preHandle方法以读取所有输入参数

3)如果我的预定义列表中不存在输入参数,则抛出异常。

代码:

import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.ListIterator;

import javax.naming.AuthenticationException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class RequestInterceptor implements HandlerInterceptor {

    enum parameterChoices {
        inputParam1, inputParam2, inputParam3
    };

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        if (request.getParameterNames() != null) {
            Enumeration<String> parametrs = request.getParameterNames();
            List<String> list = Collections.list(parametrs);
            ListIterator<String> litr = list.listIterator();

            while (litr.hasNext()) {

                if (!contains(litr.next())) {
                    throw new RuntimeException("HTTP parameter/path pollution attack Exception");
                }
            }

        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("---method executed---");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("---Request Completed---");
    }

    private boolean contains(String paramValue) {
        System.out.println("contains paramValue=" + paramValue);
        if (paramValue == null || paramValue == "") {
            return false;
        }

        for (parameterChoices type : parameterChoices.values()) {
            if (type.name().equals(paramValue)) {
                return true;
            }
        }

        return false;
    }

}

现在注册:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {

    @Autowired
    RequestInterceptor requestInterceptor ;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(requestInterceptor );

    }
}