<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    The important thing in life is to have a great aim , and the determination

    常用鏈接

    統(tǒng)計(jì)

    IT技術(shù)鏈接

    保險(xiǎn)相關(guān)

    友情鏈接

    基金知識(shí)

    生活相關(guān)

    最新評(píng)論

    特殊字符的轉(zhuǎn)義


  • 特殊字符轉(zhuǎn)義   
  •   
  • 由于 Web 應(yīng)用程序需要聯(lián)合使用到多種語(yǔ)言,每種語(yǔ)言都包含一些特殊的字符,對(duì)于動(dòng)態(tài)語(yǔ)言或標(biāo)簽式的語(yǔ)言而言,如果需要?jiǎng)討B(tài)構(gòu)造語(yǔ)言的內(nèi)容時(shí),一個(gè)我們經(jīng)常會(huì)碰到的問(wèn)題就是特殊字符轉(zhuǎn)義的問(wèn)題。下面是 Web 開發(fā)者最常面對(duì)需要轉(zhuǎn)義的特殊字符類型:   
  •   
  • HTML 特殊字符;    
  • JavaScript 特殊字符;    
  • SQL 特殊字符;    
  • 如果不對(duì)這些特殊字符進(jìn)行轉(zhuǎn)義處理,則不但可能破壞文檔結(jié)構(gòu),還可以引發(fā)潛在的安全問(wèn)題。Spring 為 HTML 和 JavaScript 特殊字符提供了轉(zhuǎn)義操作工具類,它們分別是 HtmlUtils 和 JavaScriptUtils。   
  •   
  • HTML 特殊字符轉(zhuǎn)義   
  •   
  • HTML 中 <,>,& 等字符有特殊含義,它們是 HTML 語(yǔ)言的保留字,因此不能直接使用。使用這些個(gè)字符時(shí),應(yīng)使用它們的轉(zhuǎn)義序列:   
  •   
  • &:&    
  • " :"    
  • < :<    
  • > :>    
  • 由于 HTML 網(wǎng)頁(yè)本身就是一個(gè)文本型結(jié)構(gòu)化文檔,如果直接將這些包含了 HTML 特殊字符的內(nèi)容輸出到網(wǎng)頁(yè)中,極有可能破壞整個(gè) HTML 文檔的結(jié)構(gòu)。所以,一般情況下需要對(duì)動(dòng)態(tài)數(shù)據(jù)進(jìn)行轉(zhuǎn)義處理,使用轉(zhuǎn)義序列表示 HTML 特殊字符。下面的 JSP 網(wǎng)頁(yè)將一些變量動(dòng)態(tài)輸出到 HTML 網(wǎng)頁(yè)中:   
  •   
  •   
  • 清單 1. 未進(jìn)行 HTML 特殊字符轉(zhuǎn)義處理網(wǎng)頁(yè)   
  •                    
  • <%@ page language="java" contentType="text/html; charset=utf-8"%>   
  • <%!   
  •    String userName = "</td><tr></table>";   
  •    String address = " \" type=\"button";   
  •  %>   
  • <table border="1">   
  •    <tr>   
  •      <td>姓名:</td><td><%=userName%></td> ①   
  •    </tr>   
  •    <tr>   
  •      <td>年齡:</td><td>28</td>   
  •    </tr>   
  • </table>   
  •  <input value="<%=address%>"  type="text" /> ②   
  •     
  •   
  •   
  • 在 ① 和 ② 處,我們未經(jīng)任何轉(zhuǎn)義處理就直接將變量輸出到 HTML 網(wǎng)頁(yè)中,由于這些變量可能包含一些特殊的 HTML 的字符,它們將可能破壞整個(gè) HTML 文檔的結(jié)構(gòu)。我們可以從以上 JSP 頁(yè)面的一個(gè)具體輸出中了解這一問(wèn)題:   
  •   
  • <table border="1">   
  •    <tr>   
  •      <td>姓名:</td><td></td><tr></table></td>    
  •      ① 破壞了 <table> 的結(jié)構(gòu)   
  •    </tr>   
  •    <tr>   
  •      <td>年齡:</td><td>28</td>   
  •    </tr>   
  • </table>   
  •  <input value=" " type="button"  type="text" />    
  •  ② 將本來(lái)是輸入框組件偷梁換柱為按鈕組件   
  •     
  •   
  •   
  • 融合動(dòng)態(tài)數(shù)據(jù)后的 HTML 網(wǎng)頁(yè)已經(jīng)面目全非,首先 ① 處的 <table> 結(jié)構(gòu)被包含 HTML 特殊字符的 userName 變量截?cái)嗔耍斐善浜蟮?nbsp;<table> 代碼變成無(wú)效的內(nèi)容;其次,② 處 <input> 被動(dòng)態(tài)數(shù)據(jù)改換為按鈕類型的組件(type="button")。為了避免這一問(wèn)題,我們需要事先對(duì)可能破壞 HTML 文檔結(jié)構(gòu)的動(dòng)態(tài)數(shù)據(jù)進(jìn)行轉(zhuǎn)義處理。Spring 為我們提供了一個(gè)簡(jiǎn)單適用的 HTML 特殊字符轉(zhuǎn)義工具類,它就是 HtmlUtils。下面,我們通過(guò)一個(gè)簡(jiǎn)單的例子了解 HtmlUtils 的具體用法:   
  •   
  •   
  • 清單 2. HtmpEscapeExample   
  •                    
  • package com.baobaotao.escape;   
  • import org.springframework.web.util.HtmlUtils;   
  • public class HtmpEscapeExample {   
  •     public static void main(String[] args) {   
  •         String specialStr = "<div id=\"testDiv\">test1;test2</div>";   
  •         String str1 = HtmlUtils.htmlEscape(specialStr); ①轉(zhuǎn)換為HTML轉(zhuǎn)義字符表示   
  •         System.out.println(str1);   
  •           
  •         String str2 = HtmlUtils.htmlEscapeDecimal(specialStr); ②轉(zhuǎn)換為數(shù)據(jù)轉(zhuǎn)義表示   
  •         System.out.println(str2);   
  •           
  •         String str3 = HtmlUtils.htmlEscapeHex(specialStr); ③轉(zhuǎn)換為十六進(jìn)制數(shù)據(jù)轉(zhuǎn)義表示   
  •         System.out.println(str3);   
  •           
  •         ④下面對(duì)轉(zhuǎn)義后字符串進(jìn)行反向操作   
  •         System.out.println(HtmlUtils.htmlUnescape(str1));   
  •         System.out.println(HtmlUtils.htmlUnescape(str2));   
  •         System.out.println(HtmlUtils.htmlUnescape(str3));   
  •     }   
  • }   
  •     
  •   
  •   
  • HTML 不但可以使用通用的轉(zhuǎn)義序列表示 HTML 特殊字符,還可以使用以 # 為前綴的數(shù)字序列表示 HTML 特殊字符,它們?cè)谧罱K的顯示效果上是一樣的。HtmlUtils 提供了三個(gè)轉(zhuǎn)義方法:   
  •   
  • 方法 說(shuō)明    
  • static String htmlEscape(String input)  將 HTML 特殊字符轉(zhuǎn)義為 HTML 通用轉(zhuǎn)義序列;    
  • static String htmlEscapeDecimal(String input)  將 HTML 特殊字符轉(zhuǎn)義為帶 # 的十進(jìn)制數(shù)據(jù)轉(zhuǎn)義序列;    
  • static String htmlEscapeHex(String input)  將 HTML 特殊字符轉(zhuǎn)義為帶 # 的十六進(jìn)制數(shù)據(jù)轉(zhuǎn)義序列;    
  •   
  • 此外,HtmlUtils 還提供了一個(gè)能夠?qū)⒔?jīng)過(guò)轉(zhuǎn)義內(nèi)容還原的方法:htmlUnescape(String input),它可以還原以上三種轉(zhuǎn)義序列的內(nèi)容。運(yùn)行以上代碼,您將可以看到以下的輸出:   
  •   
  • str1:<div id="testDiv">test1;test2</div>   
  • str2:<div id="testDiv">test1;test2</div>   
  • str3:<div id="testDiv">test1;test2</div>   
  • <div id="testDiv">test1;test2</div>   
  • <div id="testDiv">test1;test2</div>   
  • <div id="testDiv">test1;test2</div>   
  •     
  •   
  •   
  • 您只要使用 HtmlUtils 對(duì)代碼 清單 1 的 userName 和 address 進(jìn)行轉(zhuǎn)義處理,最終輸出的 HTML 頁(yè)面就不會(huì)遭受破壞了。   
  •   
  • JavaScript 特殊字符轉(zhuǎn)義   
  •   
  • JavaScript 中也有一些需要特殊處理的字符,如果直接將它們嵌入 JavaScript 代碼中,JavaScript 程序結(jié)構(gòu)將會(huì)遭受破壞,甚至被嵌入一些惡意的程序。下面列出了需要轉(zhuǎn)義的特殊 JavaScript 字符:   
  •   
  • ' :\'    
  • " :\"    
  • \ :\\    
  • 走紙換頁(yè): \f    
  • 換行:\n    
  • 換欄符:\t    
  • 回車:\r    
  • 回退符:\b    
  • ?    
  • 我們通過(guò)一個(gè)具體例子演示動(dòng)態(tài)變量是如何對(duì) JavaScript 程序進(jìn)行破壞的。假設(shè)我們有一個(gè) JavaScript 數(shù)組變量,其元素值通過(guò)一個(gè) Java List 對(duì)象提供,下面是完成這一操作的 JSP 代碼片斷:   
  •   
  •   
  • 清單 3. jsTest.jsp:未對(duì) JavaScript 特殊字符進(jìn)行處理   
  •                    
  • <%@ page language="java" contentType="text/html; charset=utf-8"%>   
  • <jsp:directive.page import="java.util.*"/>   
  • <%   
  •   List textList = new ArrayList();   
  •   textList.add("\";alert();j=\"");   
  • %>   
  • <script>   
  •   var txtList = new Array();   
  •    <% for ( int i = 0 ; i < textList.size() ; i++) { %>   
  •      txtList[<%=i%>] = "<%=textList.get(i)%>";    
  •      ① 未對(duì)可能包含特殊 JavaScript 字符的變量進(jìn)行處理   
  •    <% } %>   
  • </script>   
  •     
  •   
  •   
  • 當(dāng)客戶端調(diào)用這個(gè) JSP 頁(yè)面后,將得到以下的 HTML 輸出頁(yè)面:   
  •   
  • <script>   
  •   var txtList = new Array();   
  •    txtList[0] = "";alert();j=""; ① 本來(lái)是希望接受一個(gè)字符串,結(jié)果被植入了一段JavaScript代碼   
  • </script>   
  •     
  •   
  •   
  • 由于包含 JavaScript 特殊字符的 Java 變量直接合并到 JavaScript 代碼中,我們本來(lái)期望 ① 處所示部分是一個(gè)普通的字符串,但結(jié)果變成了一段 JavaScript 代碼,網(wǎng)頁(yè)將彈出一個(gè) alert 窗口。想像一下如果粗體部分的字符串是“";while(true)alert();j="”時(shí)會(huì)產(chǎn)生什么后果呢?   
  •   
  • 因此,如果網(wǎng)頁(yè)中的 JavaScript 代碼需要通過(guò)拼接 Java 變量動(dòng)態(tài)產(chǎn)生時(shí),一般需要對(duì)變量的內(nèi)容進(jìn)行轉(zhuǎn)義處理,可以通過(guò) Spring 的 JavaScriptUtils 完成這件工作。下面,我們使用 JavaScriptUtils 對(duì)以上代碼進(jìn)行改造:   
  •   
  • <%@ page language="java" contentType="text/html; charset=utf-8"%>   
  • <jsp:directive.page import="java.util.*"/>   
  • <jsp:directive.page import="org.springframework.web.util.JavaScriptUtils"/>   
  • <%   
  •   List textList = new ArrayList();   
  •   textList.add("\";alert();j=\"");   
  • %>   
  • <script>   
  •    var txtList = new Array();   
  •    <% for ( int i = 0 ; i < textList.size() ; i++) { %>   
  •    ① 在輸出動(dòng)態(tài)內(nèi)容前事先進(jìn)行轉(zhuǎn)義處理   
  •    txtList[<%=i%>] = "<%=JavaScriptUtils.javaScriptEscape(""+textList.get(i))%>";   
  •    <% } %>   
  • </script>   
  •     
  •   
  •   
  • 通過(guò)轉(zhuǎn)義處理后,這個(gè) JSP 頁(yè)面輸出的結(jié)果網(wǎng)頁(yè)的 JavaScript 代碼就不會(huì)產(chǎn)生問(wèn)題了:   
  •   
  • <script>   
  •    var txtList = new Array();   
  •    txtList[0] = "\";alert();j=\"";   
  •    ① 粗體部分僅是一個(gè)普通的字符串,而非一段 JavaScript 的語(yǔ)句了   
  • </script>   
  •     
  •   
  •   
  • SQL特殊字符轉(zhuǎn)義   
  •   
  • 應(yīng)該說(shuō),您即使沒(méi)有處理 HTML 或 JavaScript 的特殊字符,也不會(huì)帶來(lái)災(zāi)難性的后果,但是如果不在動(dòng)態(tài)構(gòu)造 SQL 語(yǔ)句時(shí)對(duì)變量中特殊字符進(jìn)行處理,將可能導(dǎo)致程序漏洞、數(shù)據(jù)盜取、數(shù)據(jù)破壞等嚴(yán)重的安全問(wèn)題。網(wǎng)絡(luò)中有大量講解 SQL 注入的文章,感興趣的讀者可以搜索相關(guān)的資料深入研究。   
  •   
  • 雖然 SQL 注入的后果很嚴(yán)重,但是只要對(duì)動(dòng)態(tài)構(gòu)造的 SQL 語(yǔ)句的變量進(jìn)行特殊字符轉(zhuǎn)義處理,就可以避免這一問(wèn)題的發(fā)生了。來(lái)看一個(gè)存在安全漏洞的經(jīng)典例子:   
  •   
  • SELECT COUNT(userId)    
  • FROM t_user    
  • WHERE userName='"+userName+"' AND password ='"+password+"';   
  •     
  •   
  •   
  • 以上 SQL 語(yǔ)句根據(jù)返回的結(jié)果數(shù)判斷用戶提供的登錄信息是否正確,如果 userName 變量不經(jīng)過(guò)特殊字符轉(zhuǎn)義處理就直接合并到 SQL 語(yǔ)句中,黑客就可以通過(guò)將 userName 設(shè)置為 “1' or '1'='1”繞過(guò)用戶名/密碼的檢查直接進(jìn)入系統(tǒng)了。   
  •   
  • 所以除非必要,一般建議通過(guò) PreparedStatement 參數(shù)綁定的方式構(gòu)造動(dòng)態(tài) SQL 語(yǔ)句,因?yàn)檫@種方式可以避免 SQL 注入的潛在安全問(wèn)題。但是往往很難在應(yīng)用中完全避免通過(guò)拼接字符串構(gòu)造動(dòng)態(tài) SQL 語(yǔ)句的方式。為了防止他人使用特殊 SQL 字符破壞 SQL 的語(yǔ)句結(jié)構(gòu)或植入惡意操作,必須在變量拼接到 SQL 語(yǔ)句之前對(duì)其中的特殊字符進(jìn)行轉(zhuǎn)義處理。Spring 并沒(méi)有提供相應(yīng)的工具類,您可以通過(guò) jakarta commons lang 通用類包中(spring/lib/jakarta-commons/commons-lang.jar)的 StringEscapeUtils 完成這一工作:   
  •   
  •   
  • 清單 4. SqlEscapeExample   
  •                    
  • package com.baobaotao.escape;   
  • import org.apache.commons.lang.StringEscapeUtils;   
  • public class SqlEscapeExample {   
  •     public static void main(String[] args) {   
  •         String userName = "1' or '1'='1";   
  •         String password = "123456";   
  •         userName = StringEscapeUtils.escapeSql(userName);   
  •         password = StringEscapeUtils.escapeSql(password);   
  •         String sql = "SELECT COUNT(userId) FROM t_user WHERE userName='"  
  •             + userName + "' AND password ='" + password + "'";   
  •         System.out.println(sql);   
  •     }   
  • }   
  •     
  •   
  •   
  • 事實(shí)上,StringEscapeUtils 不但提供了 SQL 特殊字符轉(zhuǎn)義處理的功能,還提供了 HTML、XML、JavaScript、Java 特殊字符的轉(zhuǎn)義和還原的方法。如果您不介意引入 jakarta commons lang 類包,我們更推薦您使用 StringEscapeUtils 工具類完成特殊字符轉(zhuǎn)義處理的工作。   

  • posted on 2011-01-24 14:16 鴻雁 閱讀(3852) 評(píng)論(0)  編輯  收藏 所屬分類: IT技術(shù)相關(guān)

    主站蜘蛛池模板: 亚洲中文字幕无码久久综合网| 中文字字幕在线高清免费电影| 四虎成年永久免费网站 | 成人片黄网站色大片免费观看cn| 亚洲一级毛片免费看| 日本阿v免费费视频完整版| 中文字幕无码免费久久9一区9| 亚洲精品乱码久久久久久蜜桃图片 | 德国女人一级毛片免费| 精品亚洲视频在线| 亚洲不卡中文字幕| 亚洲AV无码久久精品蜜桃| 91精品国产免费久久久久久青草| 最新久久免费视频| 国产99久久久国产精免费 | 人与禽交免费网站视频| 中文字幕乱码一区二区免费| 污网站免费在线观看| 亚洲国产成人精品无码区花野真一 | 亚洲日本成本人观看| 亚洲国产成人超福利久久精品| 亚洲国产精品无码久久一线 | 亚洲视频在线观看2018| 亚洲欧洲国产精品久久| 亚洲综合色区在线观看| 99国产精品永久免费视频| 99爱视频99爱在线观看免费| 国产做国产爱免费视频| 黄网站免费在线观看| 另类免费视频一区二区在线观看 | 午夜亚洲国产理论秋霞| 国产成人青青热久免费精品| 好大好硬好爽免费视频| 成年性生交大片免费看| 美丽姑娘免费观看在线观看中文版| 99久久成人国产精品免费| 好男人资源在线WWW免费| 最近免费字幕中文大全| 久久青草国产免费观看| 无码人妻一区二区三区免费视频| 亚洲AV无码一区二区三区性色|