StringUtils和StringEscapeUtils這兩個實用類。
1、轉義防止xss攻擊
1、轉義可以分為下面的幾種情況
第一用戶輸入特殊字符的時候,在提及的時候不做任何處理保持到數據庫,當用戶從數據庫查詢對對於的數據的時候,因為數據中存在特殊字符,要讓特殊字符能夠正常顯示不被網頁執行,需要對從數據庫中查詢出來的數據進行轉義,比如用戶輸入一個左尖括號(<),在輸出HTML代碼對其進行顯示的話,應該用”<”來表示
例如在數據庫中存儲的數據是:
<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);
}
}
輸出的結果是:
這樣輸出是: <alert>(123)(*&^%$#@!)</alert>
可以有效的防止惡意的頁面跳轉,alert彈框。
commons-lang常用工具類StringEscapeUtils
2.escapeHtml /unescapeHtml 轉義/反轉義html腳本
System.out.println(StringEscapeUtils.escapeHtml("<a>dddd</a>"));
輸出結果為:<a>dddd</a>
System.out.println(StringEscapeUtils.unescapeHtml("<a>dddd</a>"));
輸出為:<a>ddd</a>
3.escapeJavascript/unescapeJavascript 轉義/反轉義js腳本
System.out.println(StringEscapeUtils.escapeJavaScript("<script>alert('1111')</script>"));
輸出為:<script>alert('111')</script>
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))); } 執行結果: <html>吃饭</html> <html>吃飯</html> <html>吃飯</html> <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\"?>\n" + "<persons>\n" + " <person id=\"23\">\n" + " <name>張 三</name>\n" + " <age>26</age>\n" + " </person>\n" + " <person id=\"22\">\n" + " <name>李四</name>\n" + " <age>25</age>\n" + " </person>\n" + "</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 \u8FD9\u662F\u4E00\u4E2A\u6D4B\u8BD5</alter>
用unescapeJava方法反轉義之后的字符串為:thi is <alter>a test 這是一個測試</alter>
用escapeHtml方法轉義之后的字符串為:thi is <alter>a test 這是一個測試</alter>
用unescapeHtml方法反轉義之后的字符串為:thi is <alter>a test 這是一個測試</alter>
用escapeXml方法轉義之后的字符串為:<?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>
用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();