Resep cookie SameSite

Chrome, Firefox, Edge, dan lainnya akan mengubah perilaku default sesuai dengan proposal IETF, Cookie secara Inkremental sehingga:

  • Cookie tanpa atribut SameSite akan diperlakukan sebagai SameSite=Lax, yang berarti perilaku default-nya adalah membatasi cookie untuk konteks pihak pertama saja.
  • Cookie untuk penggunaan lintas situs harus menentukan SameSite=None; Secure untuk mengaktifkan penyertaan dalam konteks pihak ketiga.

Fitur ini adalah perilaku default dari versi stabil Chrome 84 dan seterusnya. Jika belum melakukannya, Anda harus memperbarui atribut untuk cookie pihak ketiga agar cookie pihak ketiga tidak diblokir di masa mendatang.

Dukungan lintas browser

Lihat bagian Kompatibilitas browser di halaman Set-Cookie MDN.

Kasus penggunaan untuk cookie lintas situs atau pihak ketiga

Ada sejumlah kasus dan pola penggunaan umum saat cookie perlu dikirim dalam konteks pihak ketiga. Jika Anda menyediakan atau bergantung pada salah satu kasus penggunaan tersebut, pastikan Anda atau penyedia memperbarui cookie-nya untuk memastikan layanan terus berfungsi dengan benar.

Konten dalam <iframe>

Konten dari situs lain yang ditampilkan di <iframe> berada dalam konteks pihak ketiga. Berikut adalah kasus penggunaan standar:

  • Konten tersemat yang dibagikan dari situs lain, seperti video, peta, contoh kode, dan postingan media sosial.
  • Widget dari layanan eksternal, seperti fungsi pembayaran, kalender, pemesanan, dan reservasi.
  • Widget seperti tombol sosial atau layanan antipenipuan yang membuat <iframes> terlihat kurang jelas.

Cookie dapat digunakan di sini untuk, antara lain, mempertahankan status sesi, menyimpan preferensi umum, mengaktifkan statistik, atau mempersonalisasi konten untuk pengguna dengan akun yang ada.

Diagram jendela browser dengan URL konten yang disematkan tidak cocok dengan URL halaman.
Jika konten yang disematkan tidak berasal dari situs yang sama dengan konteks penjelajahan level teratas, berarti konten tersebut adalah konten pihak ketiga.

Selain itu, karena web pada dasarnya dapat dikomposisi, <iframes> digunakan untuk menyematkan konten yang juga dilihat dalam konteks tingkat atas atau pihak pertama. Setiap cookie yang digunakan oleh situs tersebut akan dianggap sebagai cookie pihak ketiga saat situs ditampilkan dalam frame. Jika Anda membuat situs yang ingin Anda sematkan dengan mudah oleh orang lain sekaligus mengandalkan cookie agar dapat berfungsi, Anda juga harus memastikan situs tersebut ditandai untuk penggunaan lintas situs, atau Anda dapat dengan mudah melakukan penggantian tanpa cookie tersebut.

Permintaan "tidak aman" di seluruh situs

Meskipun "tidak aman" mungkin terdengar sedikit mengkhawatirkan di sini, hal ini mengacu pada permintaan apa pun yang mungkin dimaksudkan untuk mengubah status. Di web yang utamanya adalah permintaan POST. Cookie yang ditandai sebagai SameSite=Lax akan dikirim pada navigasi tingkat atas yang aman, mis. mengklik link untuk membuka situs lain. Namun, hal seperti pengiriman <form> melalui POST ke situs lain tidak akan menyertakan cookie.

Diagram permintaan yang berpindah dari satu halaman ke halaman lainnya.
Jika permintaan masuk menggunakan metode "aman", cookie akan dikirim.

Pola ini digunakan untuk situs yang mungkin mengalihkan pengguna ke layanan jarak jauh untuk melakukan beberapa operasi sebelum kembali, misalnya mengalihkan pengguna ke penyedia identitas pihak ketiga. Sebelum pengguna keluar dari situs, cookie akan ditetapkan yang berisi token penggunaan tunggal dengan ekspektasi bahwa token ini dapat diperiksa pada permintaan yang ditampilkan untuk mengurangi serangan Pemalsuan Permintaan Lintas Situs (CSRF). Jika permintaan yang kembali tersebut berasal melalui POST, Anda perlu menandai cookie sebagai SameSite=None; Secure.

Resource jarak jauh

Setiap resource jarak jauh di halaman mungkin mengandalkan cookie untuk dikirim dengan permintaan, dari tag <img>, tag <script>, dan sebagainya. Kasus penggunaan umum mencakup piksel pelacakan dan mempersonalisasi konten.

Hal ini juga berlaku untuk permintaan yang dimulai dari JavaScript Anda oleh fetch atau XMLHttpRequest. Jika fetch() dipanggil dengan opsi credentials: 'include', ini merupakan indikasi yang baik bahwa cookie mungkin diharapkan pada permintaan tersebut. Untuk XMLHttpRequest, Anda harus mencari instance properti withCredentials yang ditetapkan ke true. Ini merupakan indikasi yang baik bahwa cookie mungkin diharapkan pada permintaan tersebut. Cookie tersebut harus ditandai dengan tepat agar disertakan dalam permintaan lintas situs.

Konten dalam WebView

WebView di aplikasi khusus platform didukung oleh browser dan Anda harus menguji apakah batasan atau masalah yang sama berlaku. Di Android, jika WebView didukung oleh Chrome, default baru tidak akan langsung diterapkan dengan Chrome 84. Namun, tujuannya adalah untuk menerapkannya di masa mendatang, jadi Anda tetap harus menguji dan mempersiapkannya. Selain itu, Android mengizinkan aplikasi khusus platform untuk menetapkan cookie secara langsung melalui CookieManager API. Seperti cookie yang ditetapkan melalui header atau JavaScript, pertimbangkan untuk menyertakan SameSite=None; Secure jika cookie tersebut ditujukan untuk penggunaan lintas situs.

Cara menerapkan SameSite sekarang

Untuk cookie yang hanya diperlukan dalam konteks pihak pertama, idealnya Anda harus menandainya sebagai SameSite=Lax atau SameSite=Strict, bergantung pada kebutuhan Anda. Anda juga dapat memilih untuk tidak melakukan apa pun dan membiarkan browser menerapkan default-nya, tetapi ini berisiko menyebabkan perilaku yang tidak konsisten di seluruh browser dan potensi peringatan konsol untuk setiap cookie.

Set-Cookie: first_party_var=value; SameSite=Lax

Untuk cookie yang diperlukan dalam konteks pihak ketiga, Anda harus memastikan cookie tersebut ditandai sebagai SameSite=None; Secure. Perhatikan bahwa Anda membutuhkan kedua atribut bersama-sama. Jika Anda hanya menetapkan None tanpa Secure, cookie akan ditolak. Namun, ada beberapa perbedaan yang tidak kompatibel satu sama lain dalam penerapan browser, jadi Anda mungkin perlu menggunakan beberapa strategi mitigasi yang dijelaskan dalam Menangani klien yang tidak kompatibel di bawah.

Set-Cookie: third_party_var=value; SameSite=None; Secure

Menangani klien yang tidak kompatibel

Karena perubahan untuk menyertakan None dan memperbarui perilaku default ini masih relatif baru, ada ketidakkonsistenan di antara browser mengenai cara penanganan perubahan ini. Anda dapat membuka halaman update di chromium.org untuk masalah yang saat ini diketahui, tetapi Anda tidak dapat memastikan apakah masalah ini sudah lengkap. Meskipun ini tidak ideal, ada solusi yang dapat Anda gunakan selama fase transisi ini. Aturan umumnya adalah memperlakukan klien yang tidak kompatibel sebagai kasus khusus. Jangan membuat pengecualian untuk browser yang menerapkan aturan baru.

Opsi pertama adalah menetapkan cookie gaya baru dan lama:

Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure

Browser yang menerapkan perilaku yang lebih baru akan menetapkan cookie dengan nilai SameSite, sementara browser lain mungkin mengabaikan atau salah menetapkannya. Namun, browser yang sama tersebut akan menetapkan cookie 3pcookie-legacy. Saat memproses cookie yang disertakan, situs harus terlebih dahulu memeriksa keberadaan cookie gaya baru dan jika cookie tersebut tidak ditemukan, selanjutnya kembali ke cookie lama.

Contoh di bawah menunjukkan cara melakukannya di Node.js, dengan menggunakan framework Express dan middleware cookie-parser-nya.

const express = require('express');
const cp = require('cookie-parser');
const app = express();
app.use(cp());

app.get('/set', (req, res) => {
  // Set the new style cookie
  res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true });
  // And set the same value in the legacy cookie
  res.cookie('3pcookie-legacy', 'value', { secure: true });
  res.end();
});

app.get('/', (req, res) => {
  let cookieVal = null;

  if (req.cookies['3pcookie']) {
    // check the new style cookie first
    cookieVal = req.cookies['3pcookie'];
  } else if (req.cookies['3pcookie-legacy']) {
    // otherwise fall back to the legacy cookie
    cookieVal = req.cookies['3pcookie-legacy'];
  }

  res.end();
});

app.listen(process.env.PORT);

Kelemahannya adalah, hal ini melibatkan penetapan cookie redundan untuk mencakup semua browser dan mengharuskan perubahan pada saat menetapkan dan membaca cookie. Namun, pendekatan ini harus mencakup semua browser terlepas dari perilakunya dan memastikan cookie pihak ketiga terus berfungsi seperti sebelumnya.

Atau, pada saat mengirim header Set-Cookie, Anda dapat memilih untuk mendeteksi klien melalui string agen pengguna. Lihat daftar klien yang tidak kompatibel, lalu manfaatkan library yang sesuai untuk platform Anda, misalnya library ua-parser-js di Node.js. Sebaiknya cari library untuk menangani deteksi agen pengguna karena Anda kemungkinan besar tidak ingin menulis ekspresi reguler tersebut sendiri.

Manfaat pendekatan ini adalah hanya perlu melakukan satu perubahan pada saat menetapkan cookie. Namun, peringatan yang diperlukan di sini adalah bahwa sniffing agen pengguna pada dasarnya rapuh dan mungkin tidak menangkap semua pengguna yang terpengaruh.

Dukungan untuk SameSite=None dalam bahasa, library, dan framework

Sebagian besar bahasa dan library mendukung atribut SameSite untuk cookie, tetapi penambahan SameSite=None masih relatif baru, sehingga Anda mungkin perlu mengatasi beberapa perilaku standar untuk saat ini. Hal ini didokumentasikan dalam repositori contoh SameSite di GitHub.

Mendapatkan bantuan

Cookie ada di mana-mana dan sangat jarang ada situs yang diaudit sepenuhnya di tempat cookie ditetapkan dan digunakan, terutama setelah Anda memasukkan kasus penggunaan lintas situs ke dalam kombinasi. Saat Anda mengalami masalah, mungkin itu adalah pertama kalinya siapa pun mengalaminya - jadi jangan ragu untuk menghubungi kami: