Saya mencoba memahami lebih lanjut tentang Fiksasi Sesi PHP & pembajakan dan bagaimana mencegah masalah ini. Saya telah membaca dua artikel berikut di situs web Chris Shiflett:
Namun, saya tidak yakin saya memahami hal-hal dengan benar.
Untuk membantu mencegah fiksasi sesi, cukup menelepon session_regenerate_id (true); setelah berhasil masuk? Saya rasa saya mengerti itu dengan benar.
Dia juga berbicara tentang menggunakan token yang diteruskan dalam url melalui $ _GET untuk mencegah pembajakan sesi. Bagaimana tepatnya ini dilakukan? Saya menduga ketika seseorang login Anda menghasilkan token mereka & menyimpannya dalam variabel sesi, maka pada setiap halaman Anda akan membandingkan variabel sesi itu dengan nilai variabel $ _GET?
Apakah token ini perlu diubah hanya sekali per sesi atau pada setiap memuat halaman?
Juga apakah mereka cara yang baik untuk mencegah pembajakan tanpa harus memberikan nilai tambah dalam url? ini akan jauh lebih mudah.
sumber
Jawaban:
Ok, ada dua masalah yang terpisah tetapi terkait, dan masing-masing ditangani secara berbeda.
Fiksasi Sesi
Di sinilah penyerang secara eksplisit menetapkan pengidentifikasi sesi untuk pengguna. Biasanya dalam PHP itu dilakukan dengan memberi mereka semacam url
http://www.example.com/index...?session_name=sessionid
. Setelah penyerang memberikan url kepada klien, serangan itu sama dengan sesi serangan pembajakan.Ada beberapa cara untuk mencegah fiksasi sesi (lakukan semuanya):
Ditetapkan
session.use_trans_sid = 0
dalamphp.ini
file Anda . Ini akan memberi tahu PHP untuk tidak memasukkan pengenal dalam URL, dan tidak membaca URL untuk pengidentifikasi.Ditetapkan
session.use_only_cookies = 1
dalamphp.ini
file Anda . Ini akan memberitahu PHP untuk tidak pernah menggunakan URL dengan pengidentifikasi sesi.Regenerasi ID sesi kapan saja status sesi berubah. Itu berarti salah satu dari yang berikut:
Pembajakan Sesi
Di sinilah penyerang memegang pengidentifikasi sesi dan dapat mengirim permintaan seolah-olah mereka pengguna itu. Itu berarti bahwa karena penyerang memiliki pengidentifikasi, mereka semua tidak dapat dibedakan dari pengguna yang valid sehubungan dengan server.
Anda tidak dapat secara langsung mencegah pembajakan sesi. Namun Anda dapat melakukan langkah-langkah untuk membuatnya sangat sulit dan sulit untuk digunakan.
Gunakan pengidentifikasi hash sesi yang kuat:
session.hash_function
diphp.ini
. Jika PHP <5.3, atur kesession.hash_function = 1
SHA1. Jika PHP> = 5.3, atur kesession.hash_function = sha256
atausession.hash_function = sha512
.Kirim hash yang kuat:
session.hash_bits_per_character
dalamphp.ini
. Setel ini menjadisession.hash_bits_per_character = 5
. Meskipun ini tidak membuat lebih sulit untuk retak, itu membuat perbedaan ketika penyerang mencoba menebak pengidentifikasi sesi. ID akan lebih pendek, tetapi menggunakan lebih banyak karakter.Atur entropi tambahan dengan
session.entropy_file
dansession.entropy_length
diphp.ini
file Anda . Tetapkan yang pertama kesession.entropy_file = /dev/urandom
dan yang terakhir ke jumlah byte yang akan dibaca dari file entropi, misalnyasession.entropy_length = 256
.Ubah nama sesi dari PHPSESSID default. Ini dilakukan dengan memanggil
session_name()
nama pengenal Anda sendiri sebagai parameter pertama sebelum meneleponsession_start
.Jika Anda benar - benar paranoid, Anda dapat memutar nama sesi juga, tetapi berhati-hatilah karena semua sesi secara otomatis akan batal jika Anda mengubah ini (misalnya, jika Anda membuatnya tergantung pada waktu). Tetapi tergantung pada kasus penggunaan Anda, itu mungkin pilihan ...
Putar pengidentifikasi sesi Anda sesering mungkin. Saya tidak akan melakukan ini setiap permintaan (kecuali Anda benar - benar membutuhkan tingkat keamanan itu), tetapi secara acak. Anda ingin sering mengubahnya karena jika seorang penyerang membajak suatu sesi, Anda tidak ingin mereka terlalu lama menggunakannya.
Sertakan agen pengguna dari
$_SERVER['HTTP_USER_AGENT']
dalam sesi. Pada dasarnya, ketika sesi dimulai, simpan dalam sesuatu seperti$_SESSION['user_agent']
. Kemudian, pada setiap permintaan berikutnya periksa apakah itu cocok. Perhatikan bahwa ini bisa dipalsukan sehingga tidak 100% andal, tetapi lebih baik daripada tidak.Masukkan alamat IP pengguna dari
$_SERVER['REMOTE_ADDR']
dalam sesi. Pada dasarnya, ketika sesi dimulai, simpan dalam sesuatu seperti$_SESSION['remote_ip']
. Ini mungkin bermasalah dari beberapa ISP yang menggunakan beberapa alamat IP untuk penggunanya (seperti AOL dulu). Tetapi jika Anda menggunakannya, itu akan jauh lebih aman. Satu-satunya cara bagi penyerang untuk memalsukan alamat IP adalah dengan kompromi jaringan di beberapa titik antara pengguna yang sebenarnya dan Anda. Dan jika mereka membahayakan jaringan, mereka dapat melakukan jauh lebih buruk daripada pembajakan (seperti serangan MITM, dll).Sertakan token di sesi dan di sisi browser yang sering Anda tambahkan dan bandingkan. Pada dasarnya, untuk setiap permintaan lakukan
$_SESSION['counter']++
di sisi server. Juga lakukan sesuatu di JS di sisi browser untuk melakukan hal yang sama (menggunakan penyimpanan lokal). Kemudian, ketika Anda mengirim permintaan, cukup ambil satu dari satu token, dan verifikasi bahwa nonce itu sama di server. Dengan melakukan ini, Anda harus dapat mendeteksi sesi yang dibajak karena penyerang tidak akan memiliki penghitung yang tepat, atau jika mereka melakukannya, Anda akan memiliki 2 sistem yang mentransmisikan jumlah yang sama dan dapat mengatakan bahwa ada yang dipalsukan. Ini tidak akan berfungsi untuk semua aplikasi, tetapi merupakan salah satu cara untuk mengatasi masalah tersebut.Sebuah catatan pada keduanya
Perbedaan antara Sesi Fiksasi dan Pembajakan hanya tentang bagaimana pengidentifikasi sesi dikompromikan. Dalam fiksasi, pengidentifikasi diatur ke nilai yang diketahui penyerang sebelumnya. Di Hijacking itu bisa ditebak atau dicuri dari pengguna. Kalau tidak, efek keduanya sama setelah pengidentifikasi dikompromikan.
Regenerasi ID Sesi
Setiap kali Anda membuat ulang pengidentifikasi sesi menggunakan
session_regenerate_id
sesi lama harus dihapus. Ini terjadi secara transparan dengan pengendali sesi inti. Namun beberapa penangan sesi kustom menggunakansession_set_save_handler()
tidak melakukan ini dan terbuka untuk menyerang pengidentifikasi sesi lama. Pastikan bahwa jika Anda menggunakan pengendali sesi khusus, Anda melacak pengenal yang Anda buka, dan jika itu tidak sama dengan yang Anda simpan yang Anda hapus secara eksplisit (atau ubah) pengenal pada yang lama.Menggunakan pengendali sesi default, Anda baik-baik saja hanya dengan menelepon
session_regenerate_id(true)
. Itu akan menghapus informasi sesi lama untuk Anda. ID lama tidak lagi valid dan akan menyebabkan sesi baru dibuat jika penyerang (atau orang lain dalam hal ini) mencoba menggunakannya. Berhati-hatilah dengan penangan sesi khusus ....Menghancurkan Sesi
Jika Anda akan menghancurkan suatu sesi (misalnya saat logout), pastikan Anda menghancurkannya secara menyeluruh. Ini termasuk membatalkan cookie. Menggunakan
session_destroy
:sumber
session_regenerate_id
tidak membatalkan sesi yang masih terkait dengan ID lama; hanya jika parameter delete_old_session disetel ke true, sesi akan dihancurkan. Tetapi bagaimana jika seorang penyerang memulai regenerasi ID ini?session.entropy_file = /dev/urandom
. Generasi entropi internal PHP terbukti sangat lemah dan kumpulan entropi yang disediakan oleh / dev / random atau / dev / uranom adalah yang terbaik yang bisa Anda dapatkan di server web tanpa rng perangkat keras.session.cookie_httponly
dansession.cookie_secure
. Yang pertama membantu menggagalkan xss (tetapi tidak sempurna). Yang ke-2 adalah cara terbaik untuk menghentikan OWASP A9 ...Kedua serangan sesi memiliki tujuan yang sama: Dapatkan akses ke sesi yang sah dari pengguna lain. Tetapi vektor serangannya berbeda:
Dalam serangan Fiksasi Sesi , penyerang sudah memiliki akses ke sesi yang valid dan mencoba untuk memaksa korban untuk menggunakan sesi khusus ini.
Dalam Sesi Pembajakan serangan , penyerang mencoba untuk mendapatkan ID sesi korban untuk menggunakan / nya sesinya.
Dalam kedua serangan, ID sesi adalah data sensitif yang menjadi fokus serangan ini. Jadi itu adalah ID sesi yang perlu dilindungi untuk akses baca (Pembajakan Sesi) dan akses tulis (Perbaikan Sesi).
Aturan umum melindungi data sensitif dengan menggunakan HTTPS juga berlaku dalam kasus ini. Selain itu, Anda harus melakukan hal berikut:
Untuk mencegah serangan Sesi Fiksasi , pastikan bahwa:
true
) dan buatlah untuk HTTPS hanya jika memungkinkan (set session.cookie_secure ketrue
); Anda dapat melakukan keduanya dengansession_set_cookie_params
.Untuk mencegah serangan Pembajakan Sesi , pastikan bahwa:
true
)Untuk mencegah kedua serangan sesi, pastikan bahwa:
session_regenerate_id(true)
setelah upaya otentikasi (true
hanya pada keberhasilan) atau perubahan hak istimewa dan menghancurkan sesi lama. (Pastikan untuk menyimpan perubahan$_SESSION
penggunaansession_write_close
sebelum membuat kembali ID jika Anda ingin mempertahankan sesi yang terkait dengan ID lama; jika tidak hanya sesi dengan ID baru yang akan terpengaruh oleh perubahan itu.)sumber
Token yang Anda sebutkan adalah "nonce" - nomor yang digunakan satu kali. Mereka tidak harus digunakan hanya sekali, tetapi semakin lama digunakan, semakin tinggi peluang bahwace dapat ditangkap dan digunakan untuk membajak sesi.
Kelemahan lain untuk nonces adalah sangat sulit untuk membangun sistem yang menggunakannya dan memungkinkan beberapa jendela paralel pada bentuk yang sama. mis. pengguna membuka dua jendela di forum, dan mulai mengerjakan dua posting:
Jika Anda tidak memiliki cara untuk melacak beberapa jendela, Anda hanya akan menyimpan satu jendela - jendela B / Q. Ketika pengguna kemudian mengirimkan posting mereka dari jendela A dan melewati di 'P', sistem akan menolak posting sebagai
P != Q
.sumber
Saya tidak membaca artikel Shiflett, tetapi saya pikir Anda telah salah mengerti sesuatu.
Secara default, PHP memberikan token sesi di URL setiap kali klien tidak menerima cookie. Sebaliknya dalam kasus yang paling umum token sesi disimpan sebagai cookie.
Ini berarti bahwa jika Anda meletakkan token sesi di URL, PHP akan mengenalinya dan mencoba menggunakannya selanjutnya. Fiksasi sesi terjadi ketika seseorang membuat sesi dan kemudian menipu pengguna lain untuk berbagi sesi yang sama dengan membuka URL yang berisi token sesi. Jika pengguna mengautentikasi dengan cara tertentu, pengguna yang jahat kemudian mengetahui token sesi sesi yang diautentikasi, yang mungkin memiliki hak istimewa berbeda.
Seperti yang saya yakin Shiflett menjelaskan, hal yang biasa dilakukan adalah membuat kembali token yang berbeda setiap kali hak pengguna berubah.
sumber
Ya, Anda dapat mencegah fiksasi sesi dengan membuat ulang id sesi sekali saat masuk. Dengan cara ini jika penyerang tidak akan tahu nilai cookie dari sesi yang baru diautentikasi. Pendekatan lain yang benar-benar menghentikan masalah diatur
session.use_only_cookies=True
dalam konfigurasi runtime Anda. Seorang penyerang tidak dapat menetapkan nilai cookie dalam konteks domain lain. Fiksasi sesi bergantung pada pengiriman nilai cookie sebagai GET atau POST.sumber