此文章記錄我在平時做功能測試(故事卡測試)時,在安全方面有哪些設計和執行來覆蓋最常見的一些安全漏洞
XSS(cross site scripting)
如何測試
“XSS是跨站腳本攻擊(Cross Site Scripting),為不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為XSS。惡意攻擊者往Web頁面里插入惡意Script代碼,當用戶瀏覽該頁之時,嵌入其中Web里面的Script代碼會被執行,從而達到惡意攻擊用戶的目的。”
推薦下面的方法進行測試
- 手工測試。對支持用戶動態輸入的數據使用下列語句進行攻擊
<script>alert(“hey!you are attacked”)</script>
<script>window.location.;</script>
-
<sCript>alert("hey!")</scRipt>
如果網站僅僅只過濾了<script>標簽,就可以用大小寫繞過 -
<sCri<script>pt>alert("hey!")</scRi</script>pt>
如果網站只過濾了一個script標簽,就可以利用過濾后返回語句再次構成攻擊語句來繞過 -
<script>eval(\u0061\u006c\u0065\u0072\u0074(1))</script>
alert(1) 有的時候,服務器往往會對代碼中的關鍵字(如alert)進行過濾,這個時候我們可以嘗試將關鍵字進行編碼后再插入,不過直接顯示編碼是不能被瀏覽器執行的,我們可以用另一個語句eval()來實現。eval()會將編碼過的語句解碼后再執行 -
<img src='w.123' onerror='alert("hey!")'>
<a onmousemove=’do something here’>
<div onmouseover=‘do something here’>
并不是只有script標簽才可以插入代碼
如何修復和預防
- 首先是過濾。對諸如<script>、<img>、<a>等標簽進行過濾。
- 其次是編碼。像一些常見的符號,如<>在輸入的時候要對其進行轉換編碼,這樣做瀏覽器是不會對該標簽進行解釋執行的,同時也不影響顯示效果。
- 最后是限制。通過以上的案例我們不難發現xss攻擊要能達成往往需要較長的字符串,因此對于一些可以預期的輸入可以通過限制長度強制截斷來進行防御。輸入檢查還有包含敏感詞和特殊字符等。對于cookie設置httpOnly屬性,這樣js是無法讀取
SQL注入(SQL injection)
如何測試
SQL注入需要輸入含有惡意的SQL語句帶入數據庫執行,通過這個惡意的SQL語句,獲取表數據以及對數據增查改刪,因為SQL注入漏洞的危害是極大的。 推薦下面二種方法進行測試
第一種 手工測試
如何判斷SQL注入是否存在--> 最為經典的單引號判斷法:在參數后面加上單引號,比如: http://xxx/abc.php?id=1'
如果頁面返回錯誤,則存在 Sql 注入。原因是無論字符型還是整型都會因為單引號個數不匹配而報錯。
判斷注入漏洞類型總結如下
1.對于數字 使用 100
判斷查詢正常, 100 and 1=1
判斷查詢正常, 100'
判斷頁面異常或是查詢為空, 100 and 1=2
查詢數據為空
2.對于字符串 使用 x
判斷查詢正常, x' and '1'='1
判斷查詢正常, x'
判斷頁面異常或是查詢為空, x' and '1'='2
查詢數據為空
3.對于搜索 使用 x
判斷查詢正常, x%' and '%'='
判斷查詢正常, x'
判斷頁面異常或是查詢為空, x%' and 'a%'='b
查詢數據為空
通過上面的方式可以確定SQL注入是否存在,存在之后,就可以結合其他sql語句進行攻擊。對于我們測試人員,在已知數據庫結構和數據的情況下,就非常簡單了,比如使用 union select
聯合查詢繼續獲取信息
1' order by 1#
;(按照Mysql語法,#后面會被注釋掉,使用這種方法屏蔽掉后面的單引號,避免語法錯誤) 不斷增加 order by 后面的數字會判斷出有多少列
- 輸入
1' union select database(),user()#
就等于SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user()#
;database()將會返回當前網站所使用的數據庫名字. user()將會返回執行當前查詢的用戶名. 類似地還有
1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#` information_schema是mysql自帶的一張表,這張數據表保存了Mysql服務器所有數據庫的信息,如數據庫名,數據庫的表,表欄的數據類型與訪問權限等
第二種 使用工具sqlmap
sqlmap 是一個開源的滲透測試工具,可以用來自動化的檢測,利用SQL注入漏洞,獲取數據庫服務器的權限。它具有功能強大的檢測引擎,針對各種不同類型數據庫的滲透測試的功能選項,包括獲取數據庫中存儲的數據,訪問操作系統文件甚至可以通過外帶數據連接的方式執行操作系統命令。
基本命令
-
python sqlmap.py -u 'http://mytestsite.com/page.php?id=5'
sqlmap會對id參數使用不同的注入方法進行測試,檢查是否有漏洞 -
python sqlmap.py -u 'http://mytestsite.com/page.php?id=5' --dbs
獲取數據庫信息 -
python.exe sqlmap/sqlmap.py -u http://aa.com/wcms/show.php?id=3 -D cms -T cms_users -C username,password --dump
指定庫名表名字段列出指定字段
可以參考的資料
一般推薦使用sqlmap進行測試。
如何修復和預防
- 當操作數據庫時,需要實現PreparementStatement接口對SQL語句進行預編譯處理。這種采用sql語句預編譯和綁定變量,是防御sql注入的最佳方法。其原因就是:采用了PreparedStatement,就會將sql語句:”select id, no from user where id=?” 預先編譯好,也就是SQL引擎會預先進行語法分析,產生語法樹,生成執行計劃,也就是說,后面你輸入的參數,無論你輸入的是什么,都不會影響該sql語句的語法結構了,因為語法分析已經完成了,而語法分析主要是分析sql命令,比如 select ,from ,where ,and, or ,order by 等等。所以即使你后面輸入了這些sql命令,也不會被當成sql命令來執行了,因為這些sql命令的執行, 必須先的通過語法分析,生成執行計劃,既然語法分析已經完成,已經預編譯過了,那么后面輸入的參數,是絕對不可能作為sql命令來執行的,只會被當做字符串字面值參數。所以sql語句預編譯可以防御sql注入。實際項目中,一般我們都是采用各種的框架,比如ibatis, hibernate,mybatis等等。他們一般也默認就是sql預編譯的
- 如果必須要用字符串拼接,也可以對輸入參數進行數據類型檢查
- 可以使用一些安全函數 ESAPI.encoder().encodeForSQL
權限管理
如何測試
- 越權 - 不同的用戶應該有嚴格的權限管理,不被允許的資源就應該有相應的處理,比如通過URL訪問不屬于自己權限內的資源,就應該進入相應報錯頁面。一般這類處理都應該在需求階段提出。越權一般分為水平越權和垂直越權。水平越權指得是同級別用戶的越權,垂直越權指得是具有從屬關系,從而帶來不同權限范圍的用戶的越權
敏感數據
如何測試
- 如果項目需求涉及圖片上傳,取名等時,我們就應該考慮對文字和圖片進行風險控制,避免涉及暴力、政治和色情等不良信息在系統中存儲使用。一般做法是對接第三方平臺進行驗證
- 如果項目中有涉及用戶密碼等隱私數據,我們就應該采用加密存儲,不允許明文傳輸和存儲
- 項目中的日志不允許明文顯示敏感數據
其他測試點
- 修改URL的參數
- 修改cookie中的數據