1. 程式人生 > >SSM框架搭建網站防止跨站指令碼攻擊(一)

SSM框架搭建網站防止跨站指令碼攻擊(一)

第一篇

1. 個人網站使用SSM框架搭建的,上線前使用IBM Security AppScan Standard掃描漏洞出現跨站指令碼攻擊。

修復方案 

普遍的解決方案是新增攔截器。

1.在專案中新建一個攔截器

XssFilter .java

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;  
import javax.servlet.FilterChain;  
import javax.servlet.FilterConfig;  
import javax.servlet.ServletException;  
import javax.servlet.ServletRequest;  
import javax.servlet.ServletResponse;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletRequestWrapper;
public class XssFilter implements Filter{  
	@Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)req;
        request = new MHttpServletRequest(request);
        chain.doFilter(request, res);
    }

    @Override
    public void destroy() {

    }
}

MHttpServletRequest .java


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MHttpServletRequest extends HttpServletRequestWrapper {

    public MHttpServletRequest(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        // 返回值之前 先進行過濾
        return XssShieldUtil.stripXss(super.getParameter(XssShieldUtil.stripXss(name)));
    }

    @Override
    public String[] getParameterValues(String name) {
        // 返回值之前 先進行過濾
        String[] values = super.getParameterValues(XssShieldUtil.stripXss(name));
        if(values != null){
            for (int i = 0; i < values.length; i++) {
                values[i] = XssShieldUtil.stripXss(values[i]);
            }
        }
        return values;
    }

}

 XssShieldUtil.java

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
public class XssShieldUtil {

    private static List<Pattern> patterns = null;

    private static List<Object[]> getXssPatternList() {
        List<Object[]> ret = new ArrayList<Object[]>();

        ret.add(new Object[] { "<(no)?script[^>]*>.*?</(no)?script>",
                Pattern.CASE_INSENSITIVE });
        ret.add(new Object[] { "eval\\((.*?)\\)",
                Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL });
        ret.add(new Object[] { "expression\\((.*?)\\)",
                Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL });
        ret.add(new Object[] { "(javascript:|vbscript:|view-source:)*",
                Pattern.CASE_INSENSITIVE });
        ret.add(new Object[] { "<(\"[^\"]*\"|\'[^\']*\'|[^\'\">])*>",
                Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL });
        ret.add(new Object[] {
                "(window\\.location|window\\.|\\.location|document\\.cookie|document\\.|alert\\(.*?\\)|window\\.open\\()*",
                Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL });
        ret.add(new Object[] {
                "<+\\s*\\w*\\s*(oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|onerror=|onerroupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmousout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onabort|onactivate|onafterprint|onafterupdate|onbefore|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload)+\\s*=+",
                Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL });
        return ret;
    }

    private static List<Pattern> getPatterns() {

        if (patterns == null) {

            List<Pattern> list = new ArrayList<Pattern>();

            String regex = null;
            Integer flag = null;
            int arrLength = 0;

            for (Object[] arr : getXssPatternList()) {
                arrLength = arr.length;
                for (int i = 0; i < arrLength; i++) {
                    regex = (String) arr[0];
                    flag = (Integer) arr[1];
                    list.add(Pattern.compile(regex, flag));
                }
            }

            patterns = list;
        }

        return patterns;
    }

    public static String stripXss(String value) {

        if (null == value) {
            return value;
        }
        if (StringUtils.isNotBlank(value)) {

            Matcher matcher = null;

            for (Pattern pattern : getPatterns()) {
                matcher = pattern.matcher(value);
                // 匹配
                if (matcher.find()) {
                    // 刪除相關字串
                    value = matcher.replaceAll("");
                }
            }
           // value = StringFilter.StringFilter(value);
        }
        // 預防SQL盲注
        String[] pattern = { "%", "select", "insert", "delete", "from",
                "count\\(", "drop table", "update", "truncate", "asc\\(",
                "mid\\(", "char\\(", "xp_cmdshell", "exec", "master",
                "netlocalgroup administrators", "net user", "or", "and" };
        for (int i = 0; i < pattern.length; i++) {
            value = value.replace(pattern[i].toString(), "");
        }
        return value;
    }

    public static void main(String[] args) {

        String value = null;
        value = XssShieldUtil
                .stripXss("<br>select  ***//||&;/*-+ <>$###@%$#@$%^#$^%$&^(&*)*\\''count or %% ..... ,,,, ");

        value = XssShieldUtil
                .stripXss("<script src='' onerror='alert(document.cookie)'></script>");

        value = XssShieldUtil.stripXss("</script>");

        value = XssShieldUtil.stripXss(" eval(abc);");

        value = XssShieldUtil.stripXss(" expression(abc);");

        value = XssShieldUtil
                .stripXss("<img src='' onerror='alert(document.cookie);'></img>");

        value = XssShieldUtil
                .stripXss("<img src='' onerror='alert(document.cookie);'/>");

        value = XssShieldUtil
                .stripXss("<img src='' onerror='alert(document.cookie);'>");

        value = XssShieldUtil
                .stripXss("<script language=text/javascript>alert(document.cookie);");

        value = XssShieldUtil.stripXss("<script>window.location='url'");

        value = XssShieldUtil.stripXss(" onload='alert(\"abc\");");

        value = XssShieldUtil.stripXss("<img src=x<!--'<\"-->>");

        value = XssShieldUtil.stripXss("<=img onstop=");
    }
}

2.在web.xml中配攔截器

 <filter>  
       <filter-name>XssFilter</filter-name>  
       <filter-class>com.*.*.filter.XssFilter</filter-class>   <!-- 修改為自己的專案路徑  -->
    </filter>  
    <filter-mapping>  
       <filter-name>XssFilter</filter-name>  
       <url-pattern>/*</url-pattern>  
    </filter-mapping> 

3.再次掃描發現跨站指令碼攻擊高危漏洞已經修復。