防止sql攻击和跨网站脚本攻击处理办法

问题:

网站Web攻击,主要有:sql注入,css攻击,跨站脚本攻击,挂马,缓冲区溢出等。

        1.  sql注入:即通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击

       2. CSS攻击:通过在URL里插入script标签,然后 诱导信任它们的用户点击它们,确保恶意Javascript代码在受害人的机器上运行。这些攻击利用了用户和服务器之间的信任关系,事实上服务器没有对输入、输出进行检测,从而未拒绝javascript代码。


        3. 跨站脚本攻击(也称为XSS):指利用网站漏洞从用户那里恶意盗取信息。用户在浏览网站、使用即时通讯软件、甚至在阅读电子邮件时,通常会点击其中的链接。攻击者通过在链接中插入恶意代码,就能够盗取用户信息。

        4. 网页挂马:把一个木马程序上传到一个网站里面然后用木马生成器生一个网马,再上到空间里面,再加代码使得木马在打开网页里运行。

        5. 缓冲区溢出:由于TCP/IP的设计是没有考虑安全问题的,这使得在网络上传输的数据是没有任何安全防护的。攻击者可以利用系统漏洞造成系统进程缓冲区溢出


解决方案:

1.定义一个过滤器用于监听http请求并获取参数

@Slf4j
public class CrosXssAndSqlInjectFilter implements Filter {

    private FilterConfig filterConfig = null;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,                              ServletException {
        log.info("=======开始进入sql和xss过滤器=======");
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //跨域设置
        if (response instanceof HttpServletResponse) {
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            //通过在响应 header 中设置 ‘*’ 来允许来自所有域的跨域请求访问。
            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
            //通过对 Credentials 参数的设置,就可以保持跨域 Ajax 时的 Cookie
            //设置了Allow-Credentials,Allow-Origin就不能为*,需要指明具体的url域
            //httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            //请求方式
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
            //(预检请求)的返回结果(即 Access-Control-Allow-Methods 和Access-Control-Allow-Headers 提供的信息) 可以被缓存多久
            httpServletResponse.setHeader("Access-Control-Max-Age", "86400");
            //首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段
            httpServletResponse.setHeader("Access-Control-Allow-Headers", "*");
            //sql,xss过滤
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            log.info("CrosXssAndSqlInjectFilter.......orignal url:{},ParameterMap:{}", httpServletRequest.getRequestURI(), JSONObject.toJSONString(httpServletRequest.getParameterMap()));
            XssAndSqlHttpServletRequestWrapper xssAndSqlHttpServletRequestWrapper = new XssAndSqlHttpServletRequestWrapper(
                    httpServletRequest);
            /**
             * 对不需要过滤的静态资源url,作忽略处理
             */
            String[] exclusionsUrls = {".js", ".gif", ".jpg", ".png", ".css", ".ico"};
            String path = httpServletRequest.getServletPath();
            for (String str : exclusionsUrls) {
                if (path.contains(str)) {
                    chain.doFilter(request, response);
                    return;
                }
            }
            chain.doFilter(xssAndSqlHttpServletRequestWrapper, response);
            log.info("CrosXssAndSqlInjectFilter..........doFilter url:{},ParameterMap:{}", xssAndSqlHttpServletRequestWrapper.getRequestURI(), JSONObject.toJSONString(xssAndSqlHttpServletRequestWrapper.getParameterMap()));

        }
    }

    @Override
    public void destroy() {
        this.filterConfig = null;
    }
}

2.定义sql关键字过滤和跨网站脚本攻击处理的处理器

@Slf4j
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private static Set<String> notAllowedKeyWords = new HashSet<>(0);

    static {
        String key = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|" +
                "char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" +
                "table|from|grant|use|group_concat|column_name|" +
                "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" +
                "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";
        String[] keyStr = key.split("\\|");
        Collections.addAll(notAllowedKeyWords, keyStr);
    }

    private String currentUrl;

    public XssAndSqlHttpServletRequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
        currentUrl = servletRequest.getRequestURI();
    }


    /**
     * 覆盖getParameter方法,将参数名和参数值都做xss过滤。
     * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取
     * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
     */
    @Override
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        if (value == null) {
            return null;
        }
        return this.cleanXSS(value);
    }

    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);
        if (values == null) {
            return null;
        }
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = this.cleanXSS(values[i]);
        }
        return encodedValues;
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> values = super.getParameterMap();
        if (values == null) {
            return null;
        }
        Map<String, String[]> result = new HashMap<>();
        for (String key : values.keySet()) {
            String encodedKey = this.cleanXSS(key);
            int count = values.get(key).length;
            String[] encodedValues = new String[count];
            for (int i = 0; i < count; i++) {
                encodedValues[i] = this.cleanXSS(values.get(key)[i]);
            }
            result.put(encodedKey, encodedValues);
        }
        return result;
    }

    /**
     * 覆盖getHeader方法,将参数名和参数值都做xss过滤。
     * 如果需要获得原始的值,则通过super.getHeaders(name)来获取
     * getHeaderNames 也可能需要覆盖
     */
    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        if (value == null) {
            return null;
        }
        return this.cleanXSS(value);
    }

    private String cleanXSS(String values) {
        // 采用HtmlUtils实现xss过滤
        String value = HtmlUtils.htmlEscape(values);
        // 采用StringEscapeUtils实现xss过滤
        // String value = StringEscapeUtils.escapeHtml4(values);

//        String value = values.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
//        value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
//        value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
//        value = value.replaceAll("'", "& #39;");
//        value = value.replaceAll("eval\\((.*)\\)", "");
//        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
//        value = value.replaceAll("script", "");
        // sql过滤
        value = this.cleanSqlKeyWords(value);
        return value;
    }

    private String cleanSqlKeyWords(String value) {
        String paramValue = value;
        for (String keyword : notAllowedKeyWords) {
            if (paramValue.length() > keyword.length() + 4
                    && (paramValue.contains(" " + keyword) || paramValue.contains(keyword + " ") || paramValue.contains(" " + keyword + " "))) {
                String replacedString = "INVALID";
                paramValue = StringUtils.replace(paramValue, keyword, replacedString);
                log.error(this.currentUrl + "已被过滤,因为参数中包含不允许sql的关键词(" + keyword
                        + ")" + ";参数:" + value + ";过滤后的参数:" + paramValue);
            }
        }
        return paramValue;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值