Lindungi resource Anda dari serangan web dengan Mengambil Metadata

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.

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

Asal yang Sama
Permintaan yang berasal dari situs yang ditayangkan oleh server Anda sendiri (asal 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 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 (misalnya, 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. 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

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 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 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: 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

  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 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