Bagaimana cara mencegah XSS (skrip lintas situs) hanya menggunakan HTML dan PHP?
Saya telah melihat banyak posting lain tentang topik ini tetapi saya belum menemukan artikel yang jelas dan singkat menyatakan bagaimana sebenarnya mencegah XSS.
Hanya catatan bahwa ini tidak akan menyelesaikan kasus di mana Anda mungkin ingin menggunakan input pengguna sebagai atribut HTML. Misalnya, URL sumber suatu gambar. Bukan kasus yang umum, tetapi yang mudah untuk dilupakan.
@ TimTim: Untuk sebagian besar kasus, ya. Namun, ketika Anda perlu mengizinkan hal-hal input HTML menjadi sedikit rumit dan jika ini masalahnya saya sarankan Anda menggunakan sesuatu seperti htmlpurifier.org
Alix Axel
@Alix Axel, jadi apakah jawaban Anda untuk menggunakan htmlspecialchars atau menggunakan htmlpurifier.org ?
TimTim
3
Jika Anda perlu menerima input HTML gunakan HTML Purifier, jika tidak digunakan htmlspecialchars().
Sebagian besar waktu itu benar, tetapi tidak sesederhana itu. Anda harus mempertimbangkan memasukkan string yang tidak tepercaya ke dalam HTML, Js, Css, dan mempertimbangkan memasukkan HTML yang tidak tepercaya ke dalam HTML. Lihat ini: owasp.org/index.php/…
orang perunggu
41
Salah satu referensi OWASP favorit saya adalah penjelasan Cross-Site Scripting karena walaupun ada sejumlah besar vektor serangan XSS, beberapa aturan berikut dapat mempertahankan sebagian besar dari mereka!
Salah satu langkah paling penting adalah membersihkan setiap input pengguna sebelum diproses dan / atau dirender kembali ke browser. PHP memiliki beberapa " filter fungsi " " yang dapat digunakan.
Bentuk serangan XSS biasanya adalah untuk menyisipkan tautan ke beberapa javascript luar-situs yang berisi niat jahat bagi pengguna. Baca lebih lanjut tentang itu sini .
Anda juga ingin menguji situs Anda - Saya dapat merekomendasikan add-on Firefox XSS Me .
Apa yang saya perlukan untuk memastikan saya membersihkan input dengan tepat. Apakah ada satu karakter / string tertentu yang harus saya perhatikan?
TimTim
27
@TimTim - no. Semua input pengguna harus selalu dianggap bermusuhan secara inheren.
zombat
Selain itu, data internal (karyawan, sysadmin, dll.) Bisa tidak aman. Anda harus mengidentifikasi dan memantau data (dengan tanggal log dan pengguna) yang ditampilkan dengan interpretasi.
Samuel Dauzon
9
Dalam urutan pilihan:
Jika Anda menggunakan mesin templating (mis. Twig, Smarty, Blade), periksa apakah ia menawarkan pelolosan konteks-sensitif. Saya tahu dari pengalaman yang dilakukan Ranting.{{ var|e('html_attr') }}
Jika Anda ingin mengizinkan HTML, gunakan HTML Purifier . Bahkan jika Anda berpikir Anda hanya menerima Markdown atau ReStructuredText, Anda masih ingin memurnikan HTML output bahasa markup ini.
Jika tidak, gunakan htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)dan pastikan sisa dokumen Anda menggunakan karakter yang sama dengan $charset. Dalam kebanyakan kasus, 'UTF-8'adalah rangkaian karakter yang diinginkan.
Posting silang ini sebagai referensi gabungan dari beta Dokumentasi SO yang sedang offline.
Masalah
Skrip lintas situs adalah eksekusi kode jarak jauh yang tidak disengaja oleh klien web. Aplikasi web apa pun dapat membuka dirinya ke XSS jika mengambil input dari pengguna dan mengeluarkannya langsung di halaman web. Jika input menyertakan HTML atau JavaScript, kode jarak jauh dapat dijalankan ketika konten ini diberikan oleh klien web.
JavaScript pihak ke-3 akan berjalan dan pengguna akan melihat "Saya sedang menjalankan" di halaman web.
Larutan
Sebagai aturan umum, jangan pernah percaya input yang datang dari klien. Setiap nilai GET, POST, dan cookie dapat berupa apa saja, dan karenanya harus divalidasi. Saat mengeluarkan salah satu dari nilai-nilai ini, lepas dari nilai-nilai ini sehingga tidak akan dievaluasi secara tak terduga.
Perlu diingat bahwa bahkan dalam aplikasi yang paling sederhana pun data dapat dipindahkan dan akan sulit untuk melacak semua sumber. Karena itu merupakan praktik terbaik untuk selalu keluar dari hasil.
PHP menyediakan beberapa cara untuk menghindari output tergantung pada konteksnya.
htmlspecialcharsakan mengonversi "karakter khusus HTML" apa pun ke penyandian HTML mereka, yang berarti mereka tidak akan diproses sebagai HTML standar. Untuk memperbaiki contoh kami sebelumnya menggunakan metode ini:
<?php
echo '<div>'. htmlspecialchars($_GET['input']).'</div>';// or
echo '<div>'. filter_input(INPUT_GET,'input', FILTER_SANITIZE_SPECIAL_CHARS).'</div>';
Segala sesuatu di dalam <div>tag tidak akan diartikan sebagai tag JavaScript oleh browser, tetapi sebagai simpul teks sederhana. Pengguna akan melihat:
Saat mengeluarkan URL yang dihasilkan secara dinamis, PHP menyediakan urlencodefungsi untuk menghasilkan URL yang valid dengan aman. Jadi, misalnya, jika pengguna dapat memasukkan data yang menjadi bagian dari parameter GET lain:
Setiap input jahat akan dikonversi ke parameter URL yang disandikan.
Menggunakan perpustakaan eksternal khusus atau daftar AntiSamy OWASP
Terkadang Anda ingin mengirim HTML atau input kode jenis lain. Anda perlu mempertahankan daftar kata yang diotorisasi (daftar putih) dan tidak resmi (daftar hitam).
Anda dapat mengunduh daftar standar yang tersedia di situs web OWASP AntiSamy . Setiap daftar cocok untuk jenis interaksi tertentu (ebay api, tinyMCE, dll ...). Dan itu open source.
Ada perpustakaan yang ada untuk menyaring HTML dan mencegah serangan XSS untuk kasus umum dan melakukan setidaknya serta daftar AntiSamy dengan penggunaan yang sangat mudah. Misalnya Anda memiliki Pemurni HTML
Banyak kerangka kerja membantu menangani XSS dengan berbagai cara. Saat menggulirkan Anda sendiri atau jika ada kekhawatiran XSS, kami dapat memanfaatkan filter_input_array (tersedia dalam PHP 5> = 5.2.0, PHP 7.) Saya biasanya akan menambahkan cuplikan ini ke SessionController saya, karena semua panggilan masuk ke sana sebelum pengontrol lain berinteraksi dengan data. Dengan cara ini, semua input pengguna dibersihkan di 1 lokasi pusat. Jika ini dilakukan pada awal proyek atau sebelum database Anda diracuni, Anda seharusnya tidak memiliki masalah pada saat output ... berhenti sampah masuk, sampah keluar.
/* Prevent XSS input */
$_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);/* I prefer not to use $_REQUEST...but for those who do: */
$_REQUEST =(array)$_POST +(array)$_GET +(array)$_REQUEST;
Di atas akan menghapus SEMUA tag HTML & skrip. Jika Anda membutuhkan solusi yang memungkinkan tag aman, berdasarkan daftar putih, lihat Pemurni HTML .
Jika database Anda sudah diracuni atau Anda ingin berurusan dengan XSS pada saat output, OWASP merekomendasikan membuat fungsi pembungkus kustom untuk echo, dan menggunakannya di mana saja Anda menghasilkan nilai yang disediakan pengguna:
untuk mengaktifkan keamanan konten sisi browser. Lihat yang satu ini untuk perincian Kebijakan Keamanan Konten (CSP): http://content-security-policy.com/
Terutama menyiapkan CSP untuk memblokir skrip inline dan sumber skrip eksternal sangat membantu terhadap XSS.
Juga jelas mencoba menghindari eval(var), jika Anda harus menggunakan salah satu dari mereka kemudian mencoba JS melarikan diri dari mereka, HTML melarikan diri dari mereka dan Anda mungkin harus melakukan lebih tetapi untuk dasar-dasar ini sudah cukup.
href
atausrc
atribut HTML: stackoverflow.com/questions/19047119/…Jawaban:
Pada dasarnya Anda perlu menggunakan fungsi
htmlspecialchars()
kapan pun Anda ingin menampilkan sesuatu ke browser yang berasal dari input pengguna.Cara yang benar untuk menggunakan fungsi ini adalah sesuatu seperti ini:
Universitas Kode Google juga memiliki video yang sangat mendidik ini tentang Keamanan Web:
How To Break Web Software - Melihat kerentanan keamanan dalam perangkat lunak web
Apa yang Harus Diketahui Setiap Insinyur Tentang Keamanan dan Di Mana Harus Dipelajarinya
sumber
htmlspecialchars()
.Salah satu referensi OWASP favorit saya adalah penjelasan Cross-Site Scripting karena walaupun ada sejumlah besar vektor serangan XSS, beberapa aturan berikut dapat mempertahankan sebagian besar dari mereka!
Ini adalah Lembar Curang Keamanan PHP
sumber
Salah satu langkah paling penting adalah membersihkan setiap input pengguna sebelum diproses dan / atau dirender kembali ke browser. PHP memiliki beberapa " filter fungsi " " yang dapat digunakan.
Bentuk serangan XSS biasanya adalah untuk menyisipkan tautan ke beberapa javascript luar-situs yang berisi niat jahat bagi pengguna. Baca lebih lanjut tentang itu sini .
Anda juga ingin menguji situs Anda - Saya dapat merekomendasikan add-on Firefox XSS Me .
sumber
Dalam urutan pilihan:
{{ var|e('html_attr') }}
htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)
dan pastikan sisa dokumen Anda menggunakan karakter yang sama dengan$charset
. Dalam kebanyakan kasus,'UTF-8'
adalah rangkaian karakter yang diinginkan.Juga, pastikan Anda melarikan diri pada output, bukan pada input .
sumber
Posting silang ini sebagai referensi gabungan dari beta Dokumentasi SO yang sedang offline.
Masalah
Skrip lintas situs adalah eksekusi kode jarak jauh yang tidak disengaja oleh klien web. Aplikasi web apa pun dapat membuka dirinya ke XSS jika mengambil input dari pengguna dan mengeluarkannya langsung di halaman web. Jika input menyertakan HTML atau JavaScript, kode jarak jauh dapat dijalankan ketika konten ini diberikan oleh klien web.
Misalnya, jika pihak ke-3 berisi file JavaScript:
Dan aplikasi PHP langsung mengeluarkan string yang dilewatkan ke dalamnya:
Jika parameter GET yang tidak dicentang mengandung
<script src="http://example.com/runme.js"></script>
maka output dari skrip PHP adalah:JavaScript pihak ke-3 akan berjalan dan pengguna akan melihat "Saya sedang menjalankan" di halaman web.
Larutan
Sebagai aturan umum, jangan pernah percaya input yang datang dari klien. Setiap nilai GET, POST, dan cookie dapat berupa apa saja, dan karenanya harus divalidasi. Saat mengeluarkan salah satu dari nilai-nilai ini, lepas dari nilai-nilai ini sehingga tidak akan dievaluasi secara tak terduga.
Perlu diingat bahwa bahkan dalam aplikasi yang paling sederhana pun data dapat dipindahkan dan akan sulit untuk melacak semua sumber. Karena itu merupakan praktik terbaik untuk selalu keluar dari hasil.
PHP menyediakan beberapa cara untuk menghindari output tergantung pada konteksnya.
Fungsi Filter
Fungsi Filter PHP memungkinkan input data ke skrip php untuk disanitasi atau divalidasi dalam banyak cara . Mereka berguna saat menyimpan atau mengeluarkan input klien.
Pengkodean HTML
htmlspecialchars
akan mengonversi "karakter khusus HTML" apa pun ke penyandian HTML mereka, yang berarti mereka tidak akan diproses sebagai HTML standar. Untuk memperbaiki contoh kami sebelumnya menggunakan metode ini:Akan menghasilkan:
Segala sesuatu di dalam
<div>
tag tidak akan diartikan sebagai tag JavaScript oleh browser, tetapi sebagai simpul teks sederhana. Pengguna akan melihat:Pengkodean URL
Saat mengeluarkan URL yang dihasilkan secara dinamis, PHP menyediakan
urlencode
fungsi untuk menghasilkan URL yang valid dengan aman. Jadi, misalnya, jika pengguna dapat memasukkan data yang menjadi bagian dari parameter GET lain:Setiap input jahat akan dikonversi ke parameter URL yang disandikan.
Menggunakan perpustakaan eksternal khusus atau daftar AntiSamy OWASP
Terkadang Anda ingin mengirim HTML atau input kode jenis lain. Anda perlu mempertahankan daftar kata yang diotorisasi (daftar putih) dan tidak resmi (daftar hitam).
Anda dapat mengunduh daftar standar yang tersedia di situs web OWASP AntiSamy . Setiap daftar cocok untuk jenis interaksi tertentu (ebay api, tinyMCE, dll ...). Dan itu open source.
Ada perpustakaan yang ada untuk menyaring HTML dan mencegah serangan XSS untuk kasus umum dan melakukan setidaknya serta daftar AntiSamy dengan penggunaan yang sangat mudah. Misalnya Anda memiliki Pemurni HTML
sumber
Banyak kerangka kerja membantu menangani XSS dengan berbagai cara. Saat menggulirkan Anda sendiri atau jika ada kekhawatiran XSS, kami dapat memanfaatkan filter_input_array (tersedia dalam PHP 5> = 5.2.0, PHP 7.) Saya biasanya akan menambahkan cuplikan ini ke SessionController saya, karena semua panggilan masuk ke sana sebelum pengontrol lain berinteraksi dengan data. Dengan cara ini, semua input pengguna dibersihkan di 1 lokasi pusat. Jika ini dilakukan pada awal proyek atau sebelum database Anda diracuni, Anda seharusnya tidak memiliki masalah pada saat output ... berhenti sampah masuk, sampah keluar.
Di atas akan menghapus SEMUA tag HTML & skrip. Jika Anda membutuhkan solusi yang memungkinkan tag aman, berdasarkan daftar putih, lihat Pemurni HTML .
Jika database Anda sudah diracuni atau Anda ingin berurusan dengan XSS pada saat output, OWASP merekomendasikan membuat fungsi pembungkus kustom untuk
echo
, dan menggunakannya di mana saja Anda menghasilkan nilai yang disediakan pengguna:sumber
Anda juga dapat mengatur beberapa header respons HTTP terkait XSS melalui
header(...)
untuk memastikan, mode perlindungan browser XSS diaktifkan.
untuk mengaktifkan keamanan konten sisi browser. Lihat yang satu ini untuk perincian Kebijakan Keamanan Konten (CSP): http://content-security-policy.com/ Terutama menyiapkan CSP untuk memblokir skrip inline dan sumber skrip eksternal sangat membantu terhadap XSS.
untuk kumpulan umum header tanggapan HTTP yang bermanfaat mengenai keamanan webapp Anda, lihat OWASP: https://www.owasp.org/index.php/List_of_useful_HTTP_headers
sumber
sumber
preg_replace
seperti yang digunakaneval
pada input Anda. owasp.org/index.php/PHP_Security_Cheat_Sheet#Code_InjectionGunakan
htmlspecialchars
padaPHP
. Pada HTML cobalah untuk menghindari menggunakan:element.innerHTML = “…”; element.outerHTML = “…”; document.write(…); document.writeln(…);
mana
var
yang dikendalikan oleh pengguna .Juga jelas mencoba menghindari
eval(var)
, jika Anda harus menggunakan salah satu dari mereka kemudian mencoba JS melarikan diri dari mereka, HTML melarikan diri dari mereka dan Anda mungkin harus melakukan lebih tetapi untuk dasar-dasar ini sudah cukup.sumber
Cara terbaik untuk melindungi input Anda menggunakan
htmlentities
fungsinya. Contoh:Anda dapat memperoleh informasi lebih lanjut di sini .
sumber