Lindungi resource Anda dari serangan web dengan Mengambil Metadata

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.

Dukungan Browser

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Sumber

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.

Asal yang Sama
Permintaan yang berasal dari situs yang disalurkan oleh server Anda sendiri (origin yang sama) akan terus berfungsi. Permintaan pengambilan dari https://site.example untuk resource https://site.example/foo.json di JavaScript menyebabkan browser mengirim header permintaan HTTP 'Sec Fetch-Site: same-origin'.
Lintas situs
Permintaan lintas situs yang berbahaya dapat ditolak oleh server karena konteks tambahan dalam permintaan HTTP yang disediakan oleh header Sec-Fetch-*. Gambar di https://evil.example yang telah menetapkan atribut src elemen img ke 'https://site.example/foo.json' menyebabkan browser mengirim header permintaan HTTP 'Sec-Fetch-Site: cross-site'.

Sec-Fetch-Site

Dukungan Browser

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Sumber

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

Dukungan Browser

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Sumber

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

Dukungan Browser

  • Chrome: 80.
  • Edge: 80.
  • Firefox: 90.
  • Safari: 16.4.

Sumber

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 meminta site.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

  1. Instal modul seperti cuplikan kode dari atas untuk mencatat dan memantau perilaku situs Anda serta memastikan pembatasan tidak memengaruhi traffic yang sah.
  2. Perbaiki potensi pelanggaran dengan mengecualikan endpoint lintas origin yang sah.
  3. 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