栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

[JavaWeb]

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[JavaWeb]

场景
  1. 在开发Java Web程序时,为了防止XSS的Javascript攻击, 需要对用户输入转义,使Javascript脚本不能执行. 在前端可以通过获取的innerHTML属性来获取转义内容,但是在服务端如何进行转义?因为客户端是可以绕过的.
说明
  1. HTML内容的转义在开发Web时肯定是必须做的,在入数据库之前得转义,而不是在用的时候再转义。主要是防止在使用这类数据的时候忘记没有转义导致的XSS安全问题.

  2. 转义HTML字符主要涉及到5个字符<>"'&,所以只需要转义这几个即可。要实现转义字符,最基本的做法就是通过逐个分析String里的字符,之后使用转移字符串替换. 看htmlEscape1()方法即是最基本的做法。而另一种做法就是使用htmlEscape2(),它之前讲过的使用正则高效替换字符串的多个占位符为多个值[3]. 这两种方法在进行测试执行时间的时候方法1更快,可见正则匹配更耗费时间。

输出
package com.example.string;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.jupiter.api.Test;

public class HtmlEscapeTest{
    
    public static String htmlEscape1(String str) {

        if(isEmpty(str))
            return str;

        StringBuilder w = new StringBuilder();
        for (int i = 0, len = str.length(); i < len; i++) {
            char cur = str.charAt(i);
            switch (cur) {
                case '<':
                    w.append("<");
                    break;
                case '>':
                    w.append(">");
                    break;
                case '"':
                    w.append(""");
                    break;
                case ''':
                    w.append("'");
                    break;
                case '&':
                    w.append("&");
                    break;
                default:
                    w.append(cur);
                    break;
            }
        }
        return w.toString();
    }

    private static boolean isEmpty(String str) {
        return str == null || str.isEmpty();
    }

    
    public static void replaceOneMore(StringBuilder output, String input,
                                      String oldRegex, Map oldToNew){
        Pattern p = Pattern.compile(oldRegex);
        Matcher m = p.matcher(input);

        while (m.find()) {
            String one = m.group();
            if(oldToNew.containsKey(one))
                m.appendReplacement(output, oldToNew.get(one));
        }
        m.appendTail(output);
    }

    public static String htmlEscape2(String source){
        if(isEmpty(source))
            return source;

        StringBuilder builder = new StringBuilder();
        HashMap oldTonew = new HashMap<>();
        oldToNew.put("<","<");
        oldToNew.put(">",">");
        oldToNew.put(""",""");
        oldToNew.put("'","'");
        oldToNew.put("&","&");
        long start2 = System.currentTimeMillis();
        replaceOneMore(builder,source,"[<]|[>]|["]|[']|[&]",oldToNew);    
        long end2 = System.currentTimeMillis();
        print("replaceOneMore",end2-start2);
        return builder.toString();    
    }

    public static String htmlUnescape(String str){
        if(isEmpty(str))
            return str;

        if(str.indexOf("&") == -1)
            return str;

        StringBuilder sb = new StringBuilder();
        HashMap oldTonew = new HashMap<>();
        oldToNew.put("<","<");
        oldToNew.put(">",">");
        oldToNew.put(""",""");
        oldToNew.put("'","'");
        oldToNew.put("&","&");
        replaceOneMore(sb,str,"[&]lt;|[&]gt;|[&]quot;|[&]#39;|[&]amp;",oldToNew);
        return sb.toString();  
    }

    public static void print(String key,T t){
        System.out.println(key +" : "+t);
    }

    @Test
    public void testEscapeHtml(){
        String str = "&"
        +"&"
        +"&"
        +"&"
        +"&"
        +"&"
        +"&"
        +"&"
        +"&"
        +"&";
        
        long start1 = System.currentTimeMillis();
        String result1 = htmlEscape1(str);
        long old1 = System.currentTimeMillis();

        print("result1",result1);
        print("duration",old1-start1);

        long start2 = System.currentTimeMillis();
        String result2 = htmlEscape2(str);
        long end2 = System.currentTimeMillis();
        print("result2",result2);
        print("duration",end2-start2);

        assertEquals(result2, result1);
        String source = htmlUnescape(result2);
        assertEquals(source, str);
        print("source",source);
    }
}
输出
result1 : <a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&
duration : 1
replaceoneMore : 8
result2 : <a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&<a href="http://blog.csdn.net/infoworld?name=tobey&year=2021"></a><script>alert('hello')</script>&
duration : 8
source : &&&&&&&&&&

参考
  1. Java escape HTML - Stack Overflow

  2. Why to Encode (escape) Special Characters in HTML

  3. 使用正则高效替换字符串的多个占位符为多个值

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/425260.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号