Lompat ke konten
dokumentasi.id
Commit 0a16c9d
v2
Star6,9 rb

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

8

Web Cache dan Denial of Service

Tiga berkas catatan di halaman ini bekerja pada satu asumsi yang sama: ada lapisan cache di antara klien dan origin. Catatan Web Cache Deception menyebut caching proxy yang menyimpan informasi privat, catatan Web Cache Poisoning menyebut respons berbahaya yang tersimpan dan disajikan ke pengguna lain, sedangkan catatan Denial Of Service menyebut gangguan fungsi normal layanan. Ketiganya bertumpu pada selisih pemahaman antara cache dan origin. Web Cache Deception.md:4, Web Cache Poisoning.md:4, Denial Of Service.md:4

Cache key dan unkeyed input

Cache memilih respons berdasarkan cache key. Header yang tidak ikut dihitung ke dalam cache key tetap dibaca oleh origin saat menyusun respons; bagian inilah yang disebut unkeyed input. Repositori tidak menuliskan rumus cache key secara eksplisit, tetapi batasnya bisa dibaca dari nilai header status cache dan dari header Vary.

graph LR
    REQ["GET /profile/setting/.js"] --> KEY["cache key: path dan query"]
    HDR["X-Forwarded-Host / X-Host / X-Forwarded-Scheme"] -.unkeyed input.-> KEY
    KEY --> LOOKUP{"entri ada?"}
    LOOKUP -->|"MISS"| ORIGIN["origin server"]
    LOOKUP -->|"HIT"| CLIENT["respons tersimpan"]
    ORIGIN --> STORE["simpan ke cache"]
    STORE --> CLIENT
    style KEY fill:#f59e0b,color:#000
    style LOOKUP fill:#f59e0b,color:#000
    style HDR fill:#f59e0b,color:#000
    style ORIGIN fill:#336791,color:#fff
    style STORE fill:#8b5cf6,color:#fff
    style CLIENT fill:#8b5cf6,color:#fff
%% fig: Cache key dan unkeyed input
%% desc: Cache hanya mencocokkan path dan query, sementara header forward dipakai origin dan tetap memengaruhi isi respons yang disimpan.
Fig. 1: Cache key dan unkeyed inputCache hanya mencocokkan path dan query, sementara header forward dipakai origin dan tetap memengaruhi isi respons yang disimpan.
InputPosisi terhadap cache keyEfek yang tercatat di catatanRujukan
X-Forwarded-Hostunkeyedmasuk ke <img href="https://evil.com/a.png"> dan ke Set-Cookie: locale=en; domain=xyzWeb Cache Poisoning.md:10-22, Web Cache Poisoning.md:70-104
X-Hostunkeyedmenghasilkan <script src="https://evil.com/x.js">Web Cache Poisoning.md:37-52
X-Forwarded-Schemeunkeyedmemicu 301 Moved Permanently menuju https://attacker.com/en saat digabung dengan X-Forwarded-HostWeb Cache Poisoning.md:70-104
X-Forwarded-Serverunkeyedorigin membalas 404 Not Found dengan CF-Cache-Status: MISSWeb Cache Poisoning.md:106-131
User-Agentkeyed lewat Varypayload hanya tersaji ke kelompok user agent yang samaWeb Cache Poisoning.md:54-68

Baris User-Agent menjadi pembanding: respons selective poisoning menyertakan Vary: User-Agent, Accept-Encoding, sehingga cache memisahkan salinan per kelompok user agent. Web Cache Poisoning.md:54-68

Web Cache Deception

Catatan ini memakai satu fitur privat sebagai contoh, yaitu pengaturan profil. Tiga probe dipakai berurutan, dan setiap probe dinilai dari header status cache plus header Content-Type. Web Cache Deception.md:10-21

RequestNilai yang dicariPengamatan pendukung
GET /profile/settingCf-Cache-Status: HITrespons tetap Content-Type: text/html
GET /profile/setting/.jsHIT, bukan MISS atau ErrorContent-Type tetap text/html walau path berakhiran .js
GET /profile/setting/;.jsHITekstensi dipisah ; supaya tidak diparse sebagai berkas oleh origin

Langkah terakhir setiap probe adalah membuka URL hasilnya di incognito mode. Web Cache Deception.md:23-35, Web Cache Deception.md:37-49

sequenceDiagram
    participant Penyerang
    participant Cache
    participant Origin
    Penyerang->>Cache: GET /profile/setting
    Cache->>Origin: GET /profile/setting
    Origin-->>Cache: 200 Content-Type text/html
    Cache-->>Penyerang: Cf-Cache-Status HIT
    Penyerang->>Cache: GET /profile/setting/.js
    Cache->>Origin: GET /profile/setting/.js
    Origin-->>Cache: 200 Content-Type text/html
    Cache-->>Penyerang: Cf-Cache-Status HIT
    Penyerang->>Cache: GET /profile/setting/;.js
    Cache-->>Penyerang: isi halaman privat dari cache
    Note over Cache: origin tidak punya berkas .js di path itu
%% fig: Tiga probe cache deception pada satu fitur privat
%% desc: Ekstensi palsu membuat cache menganggap respons privat layak disimpan, padahal origin tetap mengembalikan HTML.
Fig. 2: Tiga probe cache deception pada satu fitur privatEkstensi palsu membuat cache menganggap respons privat layak disimpan, padahal origin tetap mengembalikan HTML.

⚠️ Tanda utama pada catatan ini adalah Content-Type: text/html yang bertahan pada path berakhiran .js. Bila Cf-Cache-Status bernilai MISS atau Error, trik ekstensi belum berhasil dan respons tidak tersimpan. Web Cache Deception.md:23-35

Web Cache Poisoning

Enam teknik dicatat, dan semuanya mengandalkan header yang dikirim klien tetapi tidak ikut dihitung cache. Web Cache Poisoning.md:4

TeknikHeader penentuBukti pada respons
Basic poisoningX-Forwarded-Host: evil.comCache-Control: public, no-cache dan <img href="https://evil.com/a.png" />
Basic poisoning dengan payload XSSX-Forwarded-Host: a.\"><script>alert(1)</script>atribut href terpotong dan script tereksekusi
Seizing the CacheX-Host: evil.comVia: 1.1 varnish-v4, Age: 174, Cache-Control: public, max-age=1800, <script src="https://evil.com/x.js">
Selective poisoningX-Forwarded-Host: a"><iframe onload=alert(1)>X-Served-By: cache-lhr6335-LHR dan Vary: User-Agent, Accept-Encoding
Route poisoningX-Forwarded-Server: evil lalu X-Forwarded-Host404 Not Found dengan CF-Cache-Status: MISS, judul HubSpot - Page not found
Hidden route poisoningX-Forwarded-Host: evil302 Found menuju https://ghost.org/fail/

Sumber baris tabel di atas adalah Web Cache Poisoning.md:10-22, Web Cache Poisoning.md:23-35, Web Cache Poisoning.md:37-52, Web Cache Poisoning.md:54-68, Web Cache Poisoning.md:106-131, dan Web Cache Poisoning.md:133-154.

Chaining unkeyed inputs berjalan dalam tiga langkah yang saling bergantung. Langkah pertama menyisipkan X-Forwarded-Host: xyz dan origin membalas Set-Cookie: locale=en; domain=xyz. Langkah kedua memakai X-Forwarded-Scheme: nothttps dan origin membalas 301 Moved Permanently ke https://redacted.net. Langkah ketiga mengirim kedua header sekaligus, sehingga Location berbelok ke https://attacker.com/en. Web Cache Poisoning.md:70-104

⚠️ Nilai Age: 174 dengan Cache-Control: public, max-age=1800 pada teknik Seizing the Cache berarti salinan tercemar tetap disajikan sampai sisa masa berlaku habis. Selama rentang itu, pengguna lain menerima respons dari cache, bukan dari origin. Web Cache Poisoning.md:37-52

Denial Of Service

Catatan ini menyatakan bahwa vektornya bisa muncul di semua fitur aplikasi, dan menyebut file upload berukuran sangat besar sebagai salah satu contoh. Denial Of Service.md:7

VektorYang dikirimPetunjuk pada catatan
Cookie bombnilai panjang pada param1 yang terpantul ke cookieperiksa cookie setelah parameter diisi
Payload panjang pada formusername=victim&password=aaaaaaaaaaaaaaaberlaku untuk password atau email panjang
Pixel floodgambar dengan jumlah piksel sangat besarbergantung pada berkas payload eksternal
Frame floodGIF dengan jumlah frame sangat besarbergantung pada berkas payload eksternal
Parameter resize gambarwidth=99999999999&height=99999999999nilai normal pada catatan adalah 500
Duplikasi Accept-Encodinggzip, gzip, deflate, br, brnilai header diulang
No rate limitrentetan request tanpa batasserver turun karena jumlah request
ReDoSpola regex yang dieksekusi serverberasal dari implementasi RegEx yang buruk

Rujukan baris tabel di atas adalah Denial Of Service.md:10-15, Denial Of Service.md:17-24, Denial Of Service.md:26-28, Denial Of Service.md:30-32, Denial Of Service.md:34-41, Denial Of Service.md:43-46, Denial Of Service.md:48, dan Denial Of Service.md:50.

Vektor terakhir adalah CPDoS, yaitu Cache Poisoned Denial of Service, dengan tiga varian. Varian HTTP Header Oversize mengirim header yang lebih besar dari batas origin tetapi masih di bawah batas cache, sehingga origin membalas 400 Bad Request dengan pesan Header size exceeded. Varian HTTP Meta Character menyisipkan karakter kontrol seperti \r\n lewat X-Meta-Malicious-Header dan origin membalas 400 Bad Request dengan pesan Character not allowed. Varian HTTP Method Override memakai X-HTTP-Method-Override, X-HTTP-Method, atau X-Method-Override untuk mengubah metode request, dan origin membalas 404 Not Found dengan pesan POST on /index.php not found. Denial Of Service.md:52-69, Denial Of Service.md:70-86, Denial Of Service.md:87-108

Catatan juga menyertakan X-Forwarded-Port: 123 dan X-Forwarded-Host: www.hackerone.com:123 pada request GET /index.php?dontpoisoneveryone=1. Denial Of Service.md:110-124

⚠️ Pada CPDoS, error 400 atau 404 dibalas origin, bukan oleh cache. Bila cache menyimpan respons error itu, seluruh pengguna berikutnya menerima error yang sama tanpa pernah menyentuh origin. Denial Of Service.md:52-69

Perpindahan status cache

Nilai Cf-Cache-Status dan CF-Cache-Status dipakai sebagai penanda keadaan, sedangkan Age terhadap max-age menentukan kapan salinan tercemar berhenti disajikan. Web Cache Deception.md:10-21, Web Cache Poisoning.md:37-52

stateDiagram-v2
    [*] --> MISS
    MISS --> HIT: origin membalas 200
    HIT --> POISONED: unkeyed input ikut terkirim
    POISONED --> HIT: request berikutnya memakai cache key sama
    HIT --> STALE: Age melewati max-age
    STALE --> MISS: entri dibuang
    MISS --> ERROR: origin membalas 400 atau 404
    ERROR --> POISONED: cache menyimpan respons error
    POISONED --> MISS: entri dibersihkan
    style MISS fill:#8b5cf6,color:#fff
    style HIT fill:#2d7d46,color:#fff
    style POISONED fill:#dc2626,color:#fff
    style STALE fill:#f59e0b,color:#000
    style ERROR fill:#dc2626,color:#fff
%% fig: Perpindahan status cache dari MISS ke versi tercemar
%% desc: Entri cache berubah dari MISS menjadi HIT, lalu menjadi versi tercemar selama unkeyed input masih terbawa, dan menjadi STALE saat max-age terlampaui.
Fig. 3: Perpindahan status cache dari MISS ke versi tercemarEntri cache berubah dari MISS menjadi HIT, lalu menjadi versi tercemar selama unkeyed input masih terbawa, dan menjadi STALE saat max-age terlampaui.
StatusPemicuNilai atau header yang terlihat
MISScache belum punya entri untuk cache key ituCF-Cache-Status: MISS pada route poisoning
HITorigin membalas 200 dan cache menyimpanCf-Cache-Status: HIT pada fitur profil
POISONEDunkeyed input ikut menentukan isi responsX-Forwarded-Host dan X-Host pada body tersimpan
STALEAge melampaui max-ageAge: 174 terhadap max-age=1800
ERRORorigin membalas error yang ikut disimpanHeader size exceeded dan Character not allowed

Lapisan penyusun header di balik semua teknik ini dibahas di Injeksi Query dan Header, sedangkan payload script yang ditempel lewat X-Forwarded-Host dibahas di Kerentanan Sisi Klien dan Pengalihan URL.