Mencegah kebocoran informasi CSRF, XSSI, dan lintas-asal.
Mengapa Anda harus memperhatikan isolasi resource web?
Banyak aplikasi web rentan terhadap serangan lintas origin seperti pemalsuan permintaan lintas situs (CSRF), penyertaan skrip lintas situs (XSSI), serangan pengaturan waktu, kebocoran informasi lintas origin, atau serangan side-channel eksekusi spekulatif (Spectre).
Header permintaan Fetch Metadata memungkinkan Anda men-deploy mekanisme defense-in-depth yang kuat—Kebijakan Isolasi Resource—untuk melindungi aplikasi Anda dari serangan lintas origin yang umum ini.
Resource yang ditampilkan oleh aplikasi web tertentu biasanya hanya dimuat oleh aplikasi itu sendiri, dan bukan oleh situs lain. Dalam kasus tersebut, men-deploy Kebijakan Isolasi Resource berdasarkan header permintaan Fetch Metadata tidak memerlukan banyak upaya, dan pada saat yang sama melindungi aplikasi dari serangan lintas situs.
Kompatibilitas browser
Header permintaan Fetch Metadata didukung di semua mesin browser modern.
Latar belakang
Banyak serangan lintas situs yang dapat terjadi karena web terbuka secara default dan server aplikasi Anda tidak dapat dengan mudah melindungi dirinya dari komunikasi yang berasal dari aplikasi eksternal. Serangan lintas origin yang umum adalah pemalsuan permintaan lintas situs (CSRF) saat penyerang memancing pengguna ke situs yang mereka kontrol, lalu mengirimkan formulir ke server tempat pengguna login. Karena server tidak dapat mengetahui apakah permintaan berasal dari domain lain (lintas situs) dan browser secara otomatis melampirkan cookie ke permintaan lintas situs, server akan menjalankan tindakan yang diminta oleh penyerang atas nama pengguna.
Serangan lintas situs lainnya seperti penyertaan skrip lintas situs (XSSI) atau kebocoran informasi lintas origin pada dasarnya mirip dengan CSRF dan mengandalkan pemuatan resource dari aplikasi korban dalam dokumen yang dikontrol penyerang dan kebocoran informasi tentang aplikasi korban. Karena aplikasi tidak dapat dengan mudah membedakan permintaan tepercaya dari permintaan tidak tepercaya, aplikasi tidak dapat menghapus traffic lintas situs berbahaya.
Memperkenalkan Metadata Pengambilan
Header permintaan Fetch Metadata adalah fitur keamanan platform web baru yang dirancang untuk membantu server mempertahankan diri dari serangan lintas-asal. Dengan memberikan informasi tentang konteks permintaan HTTP dalam serangkaian header Sec-Fetch-*
, header tersebut memungkinkan server yang merespons untuk menerapkan kebijakan keamanan sebelum memproses permintaan. Hal ini memungkinkan developer memutuskan apakah akan menerima atau menolak permintaan berdasarkan cara permintaan dibuat dan konteks tempat permintaan akan digunakan, sehingga memungkinkan untuk hanya merespons permintaan yang sah yang dibuat oleh aplikasi mereka sendiri.
Sec-Fetch-Site
Sec-Fetch-Site
memberi tahu server situs mana yang mengirim permintaan. Browser menetapkan nilai ini ke salah satu dari berikut:
same-origin
, jika permintaan dibuat oleh aplikasi Anda sendiri (misalnya,site.example
)same-site
, jika permintaan dibuat oleh subdomain situs Anda (misalnya,bar.site.example
)none
, jika permintaan secara eksplisit disebabkan oleh interaksi pengguna dengan agen pengguna (misalnya, mengklik bookmark)cross-site
, jika permintaan dikirim oleh situs lain (misalnya,evil.example
)
Sec-Fetch-Mode
Sec-Fetch-Mode
menunjukkan mode permintaan. Hal ini kira-kira sesuai dengan jenis permintaan dan memungkinkan Anda membedakan pemuatan resource dari permintaan navigasi. Misalnya, tujuan navigate
menunjukkan permintaan navigasi tingkat atas, sedangkan no-cors
menunjukkan permintaan resource seperti memuat gambar.
Sec-Fetch-Dest
Sec-Fetch-Dest
mengekspos tujuan permintaan (misalnya, jika tag script
atau img
menyebabkan resource diminta oleh browser).
Cara menggunakan Metadata Pengambilan untuk melindungi dari serangan lintas origin
Informasi tambahan yang diberikan header permintaan ini cukup sederhana, tetapi konteks tambahan memungkinkan Anda membuat logika keamanan yang andal di sisi server, yang juga disebut sebagai Kebijakan Isolasi Resource, hanya dengan beberapa baris kode.
Mengimplementasikan Kebijakan Isolasi Resource
Kebijakan Isolasi Resource mencegah resource Anda diminta oleh situs eksternal. Memblokir traffic tersebut akan mengurangi kerentanan web lintas situs yang umum seperti CSRF, XSSI, serangan pengaturan waktu, dan kebocoran informasi lintas origin. Kebijakan ini dapat diaktifkan untuk semua endpoint aplikasi Anda dan akan mengizinkan semua permintaan resource yang berasal dari aplikasi Anda sendiri serta navigasi langsung (melalui permintaan GET
HTTP). Endpoint yang seharusnya dimuat dalam konteks lintas situs (misalnya, endpoint yang dimuat menggunakan CORS) dapat dikecualikan dari logika ini.
Langkah 1: Izinkan permintaan dari browser yang tidak mengirim Metadata Pengambilan
Karena tidak semua browser mendukung Pengambilan Metadata, Anda perlu mengizinkan permintaan yang tidak menetapkan header Sec-Fetch-*
dengan memeriksa keberadaan sec-fetch-site
.
if not req['sec-fetch-site']:
return True # Allow this request
Langkah 2: Izinkan permintaan dari situs yang sama dan yang dimulai browser
Semua permintaan yang tidak berasal dari konteks lintas origin (seperti evil.example
) akan diizinkan. Secara khusus, ini adalah permintaan yang:
- Berasal dari aplikasi Anda sendiri (misalnya, permintaan dengan origin yang sama saat
site.example
memintasite.example/foo.json
akan selalu diizinkan). - Berasal dari subdomain Anda.
- Disebabkan secara eksplisit oleh interaksi pengguna dengan agen pengguna (misalnya, navigasi langsung atau dengan mengklik bookmark, dll.).
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True # Allow this request
Langkah 3: Izinkan navigasi tingkat atas dan iframing sederhana
Untuk memastikan situs Anda tetap dapat ditautkan dari situs lain, Anda harus mengizinkan navigasi tingkat teratas sederhana (HTTP GET
).
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
# <object> and <embed> send navigation requests, which we disallow.
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True # Allow this request
Langkah 4: Menonaktifkan endpoint yang dimaksudkan untuk menayangkan traffic lintas situs (Opsional)
Dalam beberapa kasus, aplikasi Anda mungkin menyediakan resource yang dimaksudkan untuk dimuat lintas situs. Resource ini harus dikecualikan berdasarkan per jalur atau per endpoint. Contoh endpoint tersebut adalah:
- Endpoint yang dimaksudkan untuk diakses lintas origin: Jika aplikasi Anda menayangkan endpoint yang mengaktifkan
CORS
, Anda harus memilih untuk tidak mengaktifkannya secara eksplisit dari isolasi resource untuk memastikan bahwa permintaan lintas situs ke endpoint ini masih dapat dilakukan. - Referensi publik (misalnya gambar, gaya, dll.): Semua resource publik dan tidak diautentikasi yang harus dapat dimuat lintas origin dari situs lain juga dapat dikecualikan.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
Langkah 5: Tolak semua permintaan lain yang bersifat lintas situs dan bukan navigasi
Permintaan lintas situs lainnya akan ditolak oleh Kebijakan Isolasi Resource ini sehingga melindungi aplikasi Anda dari serangan lintas situs yang umum.
Contoh: Kode berikut menunjukkan implementasi lengkap Kebijakan Isolasi Resource yang andal di server atau sebagai middleware untuk menolak permintaan resource lintas situs yang berpotensi berbahaya, sekaligus mengizinkan permintaan navigasi sederhana:
# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
# Allow requests from browsers which don't send Fetch Metadata
if not req['sec-fetch-site']:
return True
# Allow same-site and browser-initiated requests
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True
# Allow simple top-level navigations except <object> and <embed>
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True
# [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
# Reject all other requests that are cross-site and not navigational
return False
Men-deploy Kebijakan Isolasi Resource
- Instal modul seperti cuplikan kode dari atas untuk mencatat dan memantau perilaku situs Anda serta memastikan pembatasan tidak memengaruhi traffic yang sah.
- Perbaiki potensi pelanggaran dengan mengecualikan endpoint lintas origin yang sah.
- Terapkan kebijakan dengan menghapus permintaan yang tidak mematuhi kebijakan.
Mengidentifikasi dan memperbaiki pelanggaran kebijakan
Sebaiknya uji kebijakan Anda dengan cara yang bebas efek samping dengan mengaktifkannya terlebih dahulu dalam mode pelaporan di kode sisi server Anda. Atau, Anda dapat menerapkan logika ini di middleware, atau di reverse proxy yang mencatat pelanggaran apa pun yang mungkin dihasilkan kebijakan Anda saat diterapkan ke traffic produksi.
Dari pengalaman kami dalam meluncurkan Kebijakan Isolasi Resource Metadata Pengambilan di Google, sebagian besar aplikasi secara default kompatibel dengan kebijakan tersebut dan jarang memerlukan endpoint pengecualian untuk mengizinkan traffic lintas situs.
Menerapkan Kebijakan Isolasi Resource
Setelah memeriksa bahwa kebijakan Anda tidak memengaruhi traffic produksi yang sah, Anda siap menerapkan batasan, yang menjamin bahwa situs lain tidak akan dapat meminta resource Anda dan melindungi pengguna dari serangan lintas situs.
Bacaan lebih lanjut
- Spesifikasi Header Permintaan Metadata Pengambilan W3C
- Fetch Metadata Playground
- Presentasi Google I/O: Mengamankan Aplikasi Web dengan Fitur Platform Modern (Slide)