安全漏洞問題3:跨站指令碼

inzaghi1984發表於2017-11-21

安全漏洞問題3:跨站指令碼
1.1. 漏洞描述
跨站指令碼攻擊(也稱為XSS)指利用網站漏洞從使用者端惡意盜取資訊。使用者在瀏覽網站、使用即時通訊軟體、甚至在閱讀電子郵件時,通常會點選其中的連結,攻擊者通過在連結中插入惡意程式碼,系統在接收到包含惡意程式碼的請求之後會產成一個包含惡意程式碼的頁面,而這個頁面看起來和系統應當生成的合法頁面一樣,當使用者瀏覽器顯示該頁面內容時即會執行攻擊者插入的而惡意程式碼,攻擊者就能夠盜取使用者資訊。攻擊者通常會用十六進位制(或其他編碼方式)將連結編碼,以免使用者懷疑它的合法性。
1.2. 漏洞危害
惡意攻擊者可以通過實施跨站指令碼攻擊造成如下危害:
 盜取各類使用者帳號,如機器登入帳號、使用者網銀帳號、各類管理員帳號
 盜竊企業重要的具有商業價值的資料
 實施非法轉賬
 強制傳送電子郵件
 網站掛馬
 控制受害者機器向其它網站發起攻擊
 控制企業資料,包括讀取、篡改、新增、刪除企業敏感資料的能力
1.3. 解決方案
針對跨站指令碼攻擊漏洞,可以從輸入或輸出兩個途徑解決該問題,分別通過對輸入資料和輸出資料進行淨化來防止跨站指令碼攻擊:
 驗證輸入的資料型別是否正確
所有 HTTP 請求引數或 cookie 值的型別都是“字串”。開發者應在伺服器端驗證輸入的資料型別是否正確,檢查是否可將欄位值安全地轉換為所需的基本資料型別。
驗證數字欄位(int 型別)的方式的示例:
public Class Validator {

  ...
  public static boolean validateInt(String value) {
      boolean isFieldValid = false;
      try {
          Integer.parseInt(value);
          isFieldValid = true;
      } catch (Exception e) {
          isFieldValid = false;
      }
      return isFieldValid;
  }
  ...

}

// check if the HTTP request parameter is of type int
String fieldValue = request.getParameter(“fieldName”);
if (Validator.validateInt(fieldValue)) {

  // fieldValue is valid, continue processing request
  ...

}
 使用白名單對輸入資料進行驗證
採用白名單對輸入資料進行驗證,在所有資料進入應用程式之前把可能的危險攔截,拒絕包含HTML特殊字元的輸入,處理必須在伺服器端完成。
例如,如果 userName 欄位應僅允許字母數字字元,且不區分大小寫,則使用以下正規表示式:^[a-zA-Z0-9]*$ 對userName欄位資料進行驗證。
Java 1.3 或更早的版本不包含任何正規表示式包。建議將“Apache 正規表示式包”(請參閱以下“資源”)與 Java 1.3 一起使用,以解決缺乏支援的問題。執行正規表示式驗證的示例:
import org.apache.regexp.RE;
import org.apache.regexp.RESyntaxException;
public Class Validator {

  ...
  public static boolean matchPattern(String value, String expression) {
      boolean match = false;
      if (validateRequired(expression)) {
           RE r = new RE(expression);
           match = r.match(value);             
      }
      return match;
  }
  ...

}

// 此處校驗userName
String userName = request.getParameter(“userName”);
if (Validator.matchPattern(userName, “^[a-zA-Z0-9]*$”)) {

  // userName 驗證通過後的程式碼
  ...

}
 使用黑名單對輸入資料進行安全檢查或過濾
針對非法的HTML 程式碼包括單雙引號等,可以編寫函式對其進行檢查或過濾,這些處理必須在伺服器端完成。需要檢查或過濾的特殊字元至少包含如下表字元:
特殊/關鍵字元(不區分大小寫)
`(單引號)
“(雙引號)
<

空格鍵

TAB鍵
script
&

%
+
$
()圓括號
xss
expression
表1HTML特殊字元表
檢查函式的示例程式碼如下:
public int XssCheck(pValue)
{
pValue = pValue.toUpperCase();

String[] strCross = {“SCRIPT”,”<“,”>”,”””,”`”,”&”,”#”,”%”,”+”,”$”,”(”,”)”,” “,”t”,”XSS”,”EXPRESSION”};

for(int i = 0;i

if(pValue.indexOf(strCross[i])>=0){                  
    return 1;                                     
    //包含HTML特殊字元           
                                              
}                                                  

}
return 0;
//資料不包含HTML特殊字元
}
 採用開發框架自帶的標籤輸出方式
禁止採用<% =pValue %>這種不安全的輸出方式,而採用標籤形式輸出,如: ,採用標籤方式輸出時,系統在預設設定時會自動對資料做HTML轉換。
 對輸出資料進行淨化
通過過濾和轉義輸出資料,通過將敏感字元轉換為其對應的字元實體來清理 HTML特殊字元保護應用程式免遭跨站點指令碼漏洞攻擊,

以下示例通過將敏感字元轉換為其對應的字元實體來過濾指定字串:

  ...
  public static String filter(String value) {
      if (value == null) {
          return null;
      }        
      StringBuffer result = new StringBuffer(value.length());
      for (int i=0; i<value.length(); ++i) {
          switch (value.charAt(i)) {
          case `<`:
              result.append("&lt;");
              break;
          case `>`: 
              result.append("&gt;");
              break;
          case `"`: 
              result.append("&quot;");
              break;
          case ```: 
              result.append("&#39;");
              break;
          case `%`: 
              result.append("&#37;");
              break;
          case `;`: 
              result.append("&#59;");
              break;
          case `(`: 
              result.append("&#40;");
              break;
          case `)`: 
              result.append("&#41;");
              break;
          case `&`: 
              result.append("&amp;");
              break;
          case `+`:
              result.append("&#43;");
              break;
          default:
              result.append(value.charAt(i));
              break;
      }        
      return result;
  }
  ...

 將Cookie設定為HttpOnly,防止被指令碼獲取
很多攻擊都是為了獲得合法使用者的cookie資訊,然後攻擊Web應用程式。所以應該減少大量的資料儲存在cookie中,在任何可能的時候使用HttpOnly cookie。
HttpOnly cookie是某些瀏覽器所支援的一種防禦機制,許多應用程式使用它來防止XSS攻擊。
當一個cookie以這種方式標記是,支援它的瀏覽器將阻止客戶端JavaScript直接訪問cookie。雖然瀏覽器仍然會在請求的HTTP訊息頭中提交這個cookie,但它不會出現在document.cookie返回的字串中。


相關文章