java防止html腳本注入


html腳本注入就是跨站腳本攻擊(XSS),指的是惡意攻擊者往Web頁面里插入惡意html代碼,當用戶瀏覽該頁之時,嵌入其中Web里面的html代碼會被執行,從而達到惡意用戶的特殊目的。

有如下案例:

在前端輸入一些內容,提交到服務器后直接原樣返回,然后再append到一個div中顯示:

<form id="f1">
    Name:<input type="text" name="name"/>
    <input type="button" value="submit"/>
</form>
<div id="content"></div>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
    $(function(){
        $(':button').on('click', function(){
            var param = $('#f1').serialize();
            $.ajax({
                url : 'add',
                type : 'post',
                data : param,
                success : function(result){
                    console.log(result);
                    $('#content').append(result + '<br>');
                }
            });
        });
    })
</script>

 

@RestController
public class TestController {

    @PostMapping("/add")
    public String add(String name){
        System.out.println(name);
        return name;
    }
}

如果在運行后輸入一串html腳本代碼,運行如下:

在控制台輸出內容:

<a href="#">hello<a>

可以看到,如果輸入一個html腳本代碼,那么打印的就可能不再是原本的那串字符,而是經過解析后呈現的一個標簽。

這里就來解決html腳本注入問題:

這里的解決思路就是定義一個攔截器,攔截所有請求,因為請求的所有表單數據都存放在HttpServletRequest對象中,所以只需要拿到這個對象並對原有的方法進行增強即可。

導包:

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.3.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>1.6</version>
    </dependency>
</dependencies>

自定義一個請求包裹器,繼承HttpServletRequestWrapper類,HttpServletRequestWrapper這個類就是一個請求包裹器,用於覆蓋request對象中的方法,對原有的方法進行增強,這里就是典型的裝飾者模式。在代碼中,可以使用StringEscapeUtils.escapeHtml4(),這個方法是對字符串進行格式化,如“<,>,*,#”等字符串會格式成“<”,等。

public class XssRequestWrapper extends HttpServletRequestWrapper {

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

    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        return StringEscapeUtils.escapeHtml4(value);
    }

    @Override
    public String getParameter(String name) {
        //獲取頁面數據
        String value = super.getParameter(name);
        //進行字符轉義
        System.out.println("轉義后的字符:" + StringEscapeUtils.escapeHtml4(value));
        return StringEscapeUtils.escapeHtml4(value);
    }

    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if(values != null){
            String[] escValues = new String[values.length];
            for (int i=0; i<values.length; i++) {
                escValues[i] = StringEscapeUtils.escapeHtml4(values[i]);
            }
            return escValues;
        }
        return super.getParameterValues(name);
    }
}

定義一個過濾器,攔截所有請求:

@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        //實例化自定義的RequestWrapper對象
        XssRequestWrapper requestWrapper = new XssRequestWrapper(request);
        //放行,HttpServletRequest最終也是實現了ServletRequest,所以放行可以傳requestWrapper對象
        filterChain.doFilter(requestWrapper, servletResponse);
    }
}

運行結果:

控制台輸出:

&lt;a href=&quot;#&quot;&gt;hello&lt;a&gt;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM