zoukankan      html  css  js  c++  java
  • StringEscapeUtils防止xss攻击详解

    StringUtils和StringEscapeUtils这两个实用类。

    1、转义防止xss攻击

    1、转义可以分为下面的几种情况

    第一用户输入特殊字符的时候,在提及的时候不做任何处理保持到数据库,当用户从数据库查询对对于的数据的时候,因为数据中存在特殊字符,要让特殊字符能够正常显示不被网页执行,需要对从数据库中查询出来的数据进行转义,比如用户输入一个左尖括号(<),在输出HTML代码对其进行显示的话,应该用”&lt;”来表示

    例如在数据库中存储的数据是:

    <alert>(123)(*&^%$#@!)</alert>

    如果不对这个数据中特殊字符进行转义,浏览器执行的时候会吧上面的语句当做是js引擎可以执行的语句,弹出一个alter对话框,经过转义之后

    import org.apache.commons.lang3.StringEscapeUtils;

    public class XSStest
    {
    public static void main(String[] args)
    {
    String s = "<alert>(123)(*&^%$#@!)</alert>";

    s = StringEscapeUtils.escapeHtml4(s);

    System.out.println(s);
    }
    }

    输出的结果是:

    这样输出是: &lt;alert&gt;(123)(*&amp;^%$#@!)&lt;/alert&gt;

    可以有效的防止恶意的页面跳转,alert弹框。

    commons-lang常用工具类StringEscapeUtils

    2.escapeHtml /unescapeHtml 转义/反转义html脚本

    System.out.println(StringEscapeUtils.escapeHtml("<a>dddd</a>"));
    输出结果为:&lt;a&gt;dddd&lt;/a&gt;
    System.out.println(StringEscapeUtils.unescapeHtml("&lt;a&gt;dddd&lt;/a&gt;"));
    输出为:<a>ddd</a>
    3.escapeJavascript/unescapeJavascript 转义/反转义js脚本

    System.out.println(StringEscapeUtils.escapeJavaScript("<script>alert('1111')</script>"));
    输出为:&lt;script&gt;alert('111')&lt;/script&gt;
    4.escapeJava/unescapeJava 把字符串转为unicode编码

    System.out.println(StringEscapeUtils.escapeJava("中国"));
    输出为:用escapeJava方法转义之后的字符串为:/u4E2D/u56FD/u5171/u4EA7/u515A

    那么,所谓的加密其实就是做了unicode编码而已。

     注意点:

    表单富文本输入时,有html,需要转义,html+加中文时,用StringEscapeUtils.escapeHtml转义时,中文也转义了,经过查找,最终找到spring的org.springframework.web.util.HtmlUtils.htmlEscape,改转义不会对中午进行转义

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>3.0.6.RELEASE</version>
    </dependency>
    
    
    public static void main(String[] args) {
            String a = "<html>吃饭</html>";
            System.out.println(StringEscapeUtils.escapeHtml(a));
            System.out.println(StringEscapeUtils.unescapeHtml(StringEscapeUtils.escapeHtml(a)));
            System.out.println(HtmlUtils.htmlEscape(a));
            System.out.println(HtmlUtils.htmlUnescape(HtmlUtils.htmlEscape(a)));
        }
    执行结果:
    
    &lt;html&gt;&#21507;&#39277;&lt;/html&gt;
    
    <html>吃饭</html>
    
    &lt;html&gt;吃饭&lt;/html&gt;
    
    <html>吃饭</html>
    
    感觉还是spring好,一点一滴的比较贴心。

     这里,我们使用代码进行详细测试下

    需要引入最新的依赖

    <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.4</version>
    </dependency>

    import java.io.IOException;
    
    import org.apache.commons.lang3.StringEscapeUtils;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Test {
    
        
        public static void main(String[] args) throws IOException {
            
                
                String str = "thi is <alter>a test 这是一个测试</alter>";
                String xml = "<?xml version="1.0" encoding="UTF-8"?>
    " +
                        "<persons>
    " +
                        "   <person id="23">
    " +
                        "         <name>张   三</name>
    " +
                        "         <age>26</age>
    " +
                        "  </person>
    " +
                        "  <person id="22">
    " +
                        "        <name>李四</name>
    " +
                        "        <age>25</age>
    " +
                        " </person>
    " +
                        "</persons>";
    
                System.out.println("用escapeJava方法转义之后的字符串为:"+ StringEscapeUtils.escapeJava(str));
    
                System.out.println("用unescapeJava方法反转义之后的字符串为:"+StringEscapeUtils.unescapeJava(StringEscapeUtils.escapeJava(str)));
    
    
    
                System.out.println("用escapeHtml方法转义之后的字符串为:"+StringEscapeUtils.escapeHtml3(str));
    
                System.out.println("用unescapeHtml方法反转义之后的字符串为:"+StringEscapeUtils.unescapeHtml3(StringEscapeUtils.escapeHtml3(str)));
    
    
                System.out.println("用escapeXml方法转义之后的字符串为:"+StringEscapeUtils.escapeXml(xml));
    
                System.out.println("用unescapeXml方法反转义之后的字符串为:"+StringEscapeUtils.unescapeXml(StringEscapeUtils.escapeXml(xml)));
    
    
                String json2 = "{"name":"chenggang","age":24}";
                System.out.println("用escapeJson方法转义之后的字符串为:"+StringEscapeUtils.escapeJson(json2));
    
                System.out.println("用unescapeJson方法反转义之后的字符串为:"+StringEscapeUtils.unescapeJson(StringEscapeUtils.escapeJson(json2)));
    
                
    
            }
    
        
    }

    程序运行的结果是:

    用escapeJava方法转义之后的字符串为:thi is <alter>a test u8FD9u662Fu4E00u4E2Au6D4Bu8BD5</alter>
    用unescapeJava方法反转义之后的字符串为:thi is <alter>a test 这是一个测试</alter>
    用escapeHtml方法转义之后的字符串为:thi is &lt;alter&gt;a test 这是一个测试&lt;/alter&gt;
    用unescapeHtml方法反转义之后的字符串为:thi is <alter>a test 这是一个测试</alter>
    用escapeXml方法转义之后的字符串为:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
    &lt;persons&gt;
    &lt;person id=&quot;23&quot;&gt;
    &lt;name&gt;张 三&lt;/name&gt;
    &lt;age&gt;26&lt;/age&gt;
    &lt;/person&gt;
    &lt;person id=&quot;22&quot;&gt;
    &lt;name&gt;李四&lt;/name&gt;
    &lt;age&gt;25&lt;/age&gt;
    &lt;/person&gt;
    &lt;/persons&gt;
    用unescapeXml方法反转义之后的字符串为:<?xml version="1.0" encoding="UTF-8"?>
    <persons>
    <person id="23">
    <name>张 三</name>
    <age>26</age>
    </person>
    <person id="22">
    <name>李四</name>
    <age>25</age>
    </person>
    </persons>
    用escapeJson方法转义之后的字符串为:{"name":"chenggang","age":24}
    用unescapeJson方法反转义之后的字符串为:{"name":"chenggang","age":24}

    2、转义预防sql注入

     在commons-lang3版本上去除了2版本中对于的StringEscapeUtils.escapeSql这个方法,因为这个办法原来的实现采用下面的代码

    public static String escapeSql(String str) {
    693            if (str == null) {
    694                return null;
    695            }
    696            return StringUtils.replace(str, "'", "''");

    官网不推荐采用这种方法预防sql注入,而应该采用预编译的方式来防止sql注入,不要采用拼接的方式

    You do not need to escape any elements that you insert using the functions on a prepared statement. Those are escaped automatically.

    采用下面预编译的方式来防止sql注入

    con.prepareStatement("INSERT INTO table1 VALUES (?,?)");
    pstmt.setInt(1, 200);
    pstmt.setString(2, "Julie");
    pstmt.executeUpdate();
  • 相关阅读:
    9、搜索 :ion-searchbar
    8、列表:ion-list
    uwp 的work project 的 取消闹钟
    long ? 的使用和理解
    uwp 中的音频开发
    uwp 之语音朗读
    uwp 语音指令
    C# 泛型(Generic)
    C# 排序列表(SortedList)
    C# 反射(Reflection)
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/11188061.html
Copyright © 2011-2022 走看看