Mencegah kebocoran informasi CSRF, XSSI, dan lintas-asal.
Mengapa Anda harus mengisolasi resource web?
Banyak aplikasi web rentan terhadap serangan lintas origin seperti serangan 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 umum ini.
Biasanya resource yang diekspos oleh aplikasi web tertentu hanya dimuat oleh aplikasi itu sendiri, dan bukan oleh situs lainnya. 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 membujuk pengguna ke situs yang mereka kontrol, lalu mengirimkan formulir ke server yang digunakan pengguna untuk 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 yang tidak tepercaya, aplikasi tidak dapat menghapus traffic lintas situs yang berbahaya.
Memperkenalkan Metadata Pengambilan
Header permintaan Metadata Pengambilan 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 (mis. mengklik bookmark)cross-site
, jika permintaan dikirim oleh situs lain (misalnya,evil.example
)
Sec-Fetch-Mode
Sec-Fetch-Mode
menunjukkan mode permintaan. Ini kurang lebih 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 disediakan header permintaan ini cukup sederhana, tetapi konteks tambahannya memungkinkan Anda membangun logika keamanan yang kuat di sisi server, yang juga disebut sebagai Kebijakan Isolasi Resource, hanya dengan beberapa baris kode.
Mengimplementasikan Kebijakan Isolasi Resource
Kebijakan Isolasi Sumber Daya mencegah permintaan sumber daya oleh situs web 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 Fetch Metadata, Anda harus 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 yang dimulai oleh situs dan browser yang sama
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 origin yang sama dengan
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: Nonaktifkan endpoint yang dimaksudkan untuk menayangkan traffic lintas situs (Opsional)
Pada 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 menyalurkan endpoint yang mengaktifkan
CORS
, Anda harus secara eksplisit memilih tidak ikut dari isolasi resource untuk memastikan bahwa permintaan lintas situs ke endpoint ini masih memungkinkan. - Referensi publik (misalnya gambar, gaya, dll.): Semua resource publik dan yang 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 lintas situs dan bukan permintaan 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 canggih di server atau sebagai middleware untuk menolak permintaan resource lintas situs yang berpotensi berbahaya, sekaligus mengizinkan permintaan navigasi yang 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 secara 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 setiap pelanggaran yang mungkin dihasilkan oleh kebijakan Anda saat diterapkan ke traffic produksi.
Berdasarkan pengalaman kami dalam meluncurkan Kebijakan Isolasi Resource Metadata Pengambilan di Google, sebagian besar aplikasi secara default kompatibel dengan kebijakan semacam itu dan jarang sekali memerlukan pengecualian endpoint untuk mengizinkan traffic lintas situs.
Menegakkan 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)