banner
cos

cos

愿热情永存,愿热爱不灭,愿生活无憾
github
tg_channel
bilibili

青訓營 |「Web開發的安全之旅」

本節課重點內容#

安全問題很常見,會危害

  • 用戶
  • 公司
  • 程序員(祭天 QAQ)

兩個角度看 web 安全#

假如你是一個 hacker—— 攻擊#

跨站腳本攻擊 XSS (Cross Site Scripting)#

image.png

注入惡意腳本,完成攻擊,後果:洩露用戶隱私等

XSS 主要利用了開發者對用戶提交內容的盲目信任

image.png

特點

  • 通常難以從 UI 上感知(一般都是暗地裡執行腳本)
    - 竊取用戶信息(cookie/token
  • 繪製 UI(如彈窗等),誘騙用戶點擊 / 填寫表單

舉個栗子

public async submit(ctx) {
    const {content, id} = ctx.request.body;
    await db.save({
       content,	// 沒有對content進行過濾!!
       id
    });
}
public async render(ctx) {
    const { content } = await db.query({
        id: ctx.query.id
    });
    // 沒有對content進行過濾!!
    ctx.body = `<div>${content}</div>`;
}

可以看到上述代碼,壓根沒有對用戶輸入的 content 內容進行任何過濾。這個時候就可以提交一個<script>alert('xss');</script>腳本,進行攻擊

xss 攻擊也分幾大類:Store XSS、Reflected XSS、DOM-based XSS、Mutation-based XSS

Store XSS#
  • 提交的惡意腳本被存在數據庫
  • 訪問頁面 -> 讀數據 == 被攻擊
  • 危害最大,對全部用戶可見
  • 如:某個視頻網站,上傳了惡意腳本被存到數據庫中,從此電商網站上便多了一個視頻共享賬戶。
Reflected XSS#
  • 不涉及數據庫

  • URL 上攻擊,在 URL 上帶上腳本

    image.png

DOM-based XSS#
  • 不需要服務器的參與

  • 惡意攻擊的發起 + 執行,全在瀏覽器完成

    image.png

  • 完成注入腳本的地方,是由瀏覽器來的,這是它與 Reflected XSS 的不同之處

Mutation-based XSS#
  • 一個巧妙地攻擊方式,利用瀏覽器的特性

    如果用戶所提供的富文本內容通過 javascript 代碼進入 innerHTML 屬性後,一些意外的變化會使得這個認定不再成立:瀏覽器的渲染引擎會將本來沒有任何危害的 HTML 代碼渲染成具有潛在危險的 XSS 攻擊代碼。

  • 巧妙,最難防禦的一種方式,攻擊者非常的懂瀏覽器

image.png

Cross-site request forgery(CSRF,跨站偽造請求)#

  • 在用戶不知情的前提下

  • 利用用戶權限(cookie)

  • 構造指定 HTTP 請求,進而竊取或修改用戶敏感信息

    image.png

    一個用戶訪問了一個惡意的頁面,這個頁面向銀行發送一個轉賬請求,ServerA 為銀行的服務器,發現這個請求帶有用戶的 cookie,成功

    CSRF 通過偽裝來自受信任用戶的請求來利用受信任的網站。與XSS攻擊相比,CSRF 攻擊往往不大流行(因此對其進行防範的資源也相當稀少)和難以防範,所以被認為比XSS更具危險性

Injection(注入)#

  • SQL 注入:通過 SQL 參數進行注入

    image.png

    案例:讀取請求字段,直接以字符串的形式拼接 SQL 語句

    public async rederForm(ctx) {
        const {username, form_id } = ctx.query;
        const result = await sql.query(`
        	SELECT a, b, c FROM table
        	WHERE username = ${username}
        	AND form_id = ${form_id}
        `);
        ctx.body = renderForm(result);
    } 
    

    那麼攻擊者可以傳入一個 userName:any; DROP TABLE table; ,於是被動刪庫跑路成就達成√

  • 命令行注入等image.png

  • 讀取 + 改進流量攻擊

    image.png

Denial of Service(DOS)攻擊#

  • 通過某種方式 (構造特定請求),導致服務器資源被顯著消耗,

  • 來不及響應更多請求,導致請求擠壓,進而雪崩效應。

  • 拓展:正則表達式 —— 貪婪模式

    • 重複匹配時,? /no ? :滿足”一個即可“ / 盡可能多
  • 例子:ReDoS: 基於正則表達式的 DoS

  • 貪婪:n 次不行?n-1 次再試試?—— 回溯

    image.png

  • Distributed Dos (DDOS)

    • 短時間內,來自大量殭屍設備的請求流量,服務器不能及時完成全部請求,導致請求堆積,進而雪崩效應,無法響應新請求。(量大就完事兒了)

    • 特點:

      • 直接訪問 IP

      • 任意 API

      • 消耗大量帶寬(耗盡)

        image.png

中間人攻擊(傳輸層)#

  • 明文傳輸

  • 信息篡改不可知

  • 對方身份未驗證

    image.png

假如你是一個開發者 —— 防禦#

XSS 攻擊防禦#

  • 永遠不要信任用戶的提交內容

    • 不要將用戶的提交內容直接轉換成 DOM
  • 現成工具

    • 主流框架默認防禦 XSS(react 等)
    • google-closure-library
    • 服務端:DOMPurify
  • 用戶需求:不講武德,必須動態生成 DOM?

    • new DOMParser();

    • svg:也要掃描,因為其中也可以插入 script 標籤

    • 不要用戶自定義跳轉鏈接(或者做好過濾)!

      <a href="javascript:alert('xss')"></a>

  • 自定義樣式也要留意image.png

同源策略(CSP)#
  • 協議
  • 域名
  • 端口

任意一者不同,跨域 ×

瀏覽器的同源策略 - Web 安全 | MDN (mozilla.org)

一般的同源請求都是沒有問題的,而跨域的不行,CSP 允許開發者定義

  • 哪些源(域名)是被認為是安全的
  • 來自安全源的腳本可以被執行,否則直接拋錯
  • 對 eval + inline script 直接拒絕
  • 設置
    • 服務器的響應頭部
     Content-Security-Policy: script-src 'self'; // 同源
     Content-Security-Policy: script-src 'self' https://domain.com
    
    • 瀏覽器的響應頭部
    <meta http-equiv=" Content-Security-Policy" content="script-src self"> 
    

CSRF 攻擊防禦#

image.png

  • Origin + Referrer

  • 其他判斷【請求來自於合法來源】的方式

    • 先有頁面,後有請求
      • if 請求來自合法頁面
      • then 服務器接受過頁面請求
      • then 服務器可以標識
  • image.png

  • iframe 攻擊:限制 Origin 是吧,那我同源請求

  • 避免 GET + POST 一起請求,攻擊者一石二鳥!

    // 不要像下面這樣將更新+獲取邏輯放到同一個GET接口
    public async getAndUpdate(ctx) {
        const { update, id } = ctx.query;
        if (update) {
            await this.update(update);
        }
        ctx.body = await this.get(id);
    }
    
  • SameSite Cookie

    • 限制 Cookie domain

    • 頁面域名是否匹配

    • 依賴 cookie 的第三方服務怎麼辦?

      內嵌一個 X 站播放器,識別不了用戶登錄態,發不了彈幕

      Set-Cookie: SameSite=None; Secure ;

    image.png

  • SameSite vs CORS(跨站資源共享)

    image.png

以上這麼多防禦 CSRF 的方法,那麼什麼是防禦 CSRF 的正確姿勢呢?寫一個中間件,專門生成這方面的防禦。

Injection 防禦#

  • 找到項目中查詢 SQL 的地方

  • 使用 prepared statement

    PREPARE q FROM 'SELECT user FROM users WHERE gender = ?';
    SET @gender = 'female';
    EXECUTE q USING @gender;
    DEALLOCATE PREPARE q;
    
  • 最小權限原則

    • 所有命令都不要用 sodo || root ×
  • 建立允許名單 + 過濾

    • rm 堅決拒絕
  • 對 URL 類型參數進行協議、域名、ip 等限制

    • 避免攻擊者訪問內網

防禦 DoS#

  • Code Review (避免貪婪匹配等)
  • 代碼掃描 + 正則性能測試
  • 避免用戶提供的使用正則

防禦 DDos#

image.png

傳輸層 —— 防禦中間人#

搬出大名鼎鼎的 HTTPS

  • 可靠性:加密
  • 完整性:MAC 驗證
  • 不可抵賴性:數字簽名

image.png

  • 拓展:數字簽名

    • 私鑰(自己藏好)

    • 公鑰(公開可見)

    • CA:Certificate Authority 證書機構

    • 數字簽名,瀏覽器內置 CA 公鑰

      image.png

image.png

  • 當簽名算法不夠健壯時:被暴力破解(現在都已比較完善)

HTTP Strict-Transport-Security(HSTS)

  • 將 HTTP 主動升級到 HTTPS

Subresource Integrity(SRI)

靜態資源被劫持篡改?對比 hash

image.png

尾聲#

總結感想#

這節課老師圖文並茂的講解了 Web 安全相關的很多知識,非常有意思,包括 Web 攻擊的種類、防禦方式等

本文引用的內容大部分來自劉宇晨老師的課、MDN、外部博客引用:這一次,徹底理解 XSS 攻擊淺談 CSRF

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。