MVC: Mass Assignment Vulnerability

Soeleman 25 Januari 2017

MVC: Mass Assignment Vulnerability

Kadang kala bug bukan terjadi karena kesalahan kode saja. Loose-Coupling seperti pada HTTP protokol kadang dapat dimanfaatkan untuk inject informasi ke dalam server. Dan itu yang terjadi pada Mass Aassignment Vulnerability.

Karena framework seperti ASP.Net MVC, Ruby-on-Rails dan Java Play memberikan fitur untuk me-mapping http-form-collection ke dalam Model secara automatis. Kadang kebersihan http-form-collection itu jadi kurang diperhatikan.

App

Sekarang kita akan buat sebuah Form dengan 2 project, ASP.Net (VB.Net) dan ASP.Net-Core (C#). Dengan begitu kita bisa lihat Mass Aassignment Vulnerability ini masih dapat terjadi pada 2 projek yang berbeda.

Model

Dalam demo kali ini, kita buat Model Member. Ada beberapa property di sana, tapi yang kita pakai adalah Id, UserName dan IsAdmin.

< VB.Net >
alt text

< C# >
alt text

Controller

Dalam Controller Member hanya ada 2 method. Satu untuk Get dan Post. Tidak banyak berbeda di sini kecuali di ASP.Net-Core menggunakan IActionResult.

Dalam Get kita buat object-member dengan Id yang berisi 1. Ini hanya untuk mencegah sebuah div terlihat, detailnya lihat di-View-nya.

Sedangkan Post sebaliknya, kita buat Id menjadi 0. Yang perlu diperhatikan adalah ketika di Post apa nilai dari property IsAdmin.

< VB.Net >
alt text

< C# >
alt text

Razor

Dalam view-nya, ada 2 class css(cssAdminBackground dan cssAdmin) yang di gunakan memberikan penegasan atas status. Dan kita hanya menggunakan property UserName agar lebih sederhana.

Kalau di perhatikan view ASP.Net-Core ada yang berbeda. Terutama adanya penggunaan tag-helper tapi secara keseluruhan tidak banyak bedanya.

< VB.Net >
alt text

< C# >
alt text

Form-Member

Kita pastikan dahulu ini berjalan seperti yang di harapkan. Terlihat pada gambar di bawah, sebuah Form.

alt text

Yang terjadi apa bila kita menekan submit adalah muncul informasi UserName dan IsAdmin. Dan ini yang kita harapkan terjadi.

alt text

Exploit

Sekarang kita coba melihat apakah Mass Aassignment Vulnerability ini masih ada. Seperti yang dikatakan di atas kita mencoba lewat ASP.Net (VB.Net) dan ASP.Net-Core (C#).

Http-Get

Caranya melakukan ini sederhana sekali, cukup kita gunakan query-string. Jadi kita memanggil halaman Member dengan query-string IsAdmin dengan nilai True. Dengan begitu, form-nya akan meng-ingat alamat itu ketika Submit.

alt text

Dan ini yang terjadi. Muncul-nya warna biru itu menunjukkan bahwa kita bisa memodifikasi property IsAdmin hanya dengan Http-Get. Di sini terlihat Mass Aassignment Vulnerability masih berlaku.

alt text

Http-Post

Sekarang kita coba lewat Http-Post. Kita buka halaman Member seperti biasa. Setelah itu kita gunakan developer-tool yang disertakan dalam browser. Biasanya disertakan juga untuk merubah dom yang ada.

alt text

Kita masukkan element seperti pada gambar di bawah. Yang kita taruh itu hampir sama dengan cara Http-Get, bedanya ini di anggap sebagai bagian form-nya.

alt text

Dan seperti yang kita perkirakan, Mass Aassignment Vulnerability tetap terjadi. Yang terjadi pada saat submit adalah element yang kita masukkan akan terkirim sebagai bagian dari form tersebut.

alt text

Solusi

Secara architektural kita bisa membuat class member baru yang isinya hanya property yang kita butuhkan saja. Tentu saja ada beberapa alternatif lainnya seperti membuat custom attribute, membuat filter atau menggunakan AutoMapper. Sekarang kita akan coba lihat solusi umum yang lebih sederhana untuk mengatasi ini.

BindAttribute

Dengan BindAttribute biasanya digunakan untuk memberitahukan pada binding-model untuk mem-filter pada saat mengubah http-form-data ke dalam Model di MVC. Ada dua cara untuk melakukan filter, baik Include maupun exclude. Dengan begitu kita bisa mempertahankan informasi yang masuk kedalam controller.

< VB.Net >
alt text

< VB.Net >
alt text

Untuk ASP.Net-Core BindAttribute berbeda. Hanya satu opsi saja dan parameter untuk include saja. Caranya kerjanya saja saja.

< C# >
alt text

Bisa saja BindAttribute ini digunakan pada Model di level class. Tentu ini akan bereffek pada semua yang menggunakan Model ini.

< VB.Net >
alt text

Sama juga terhadap BindAttribute di ASP.Net-Core. Bedanya hanya parameter saja dan cara kerjanya seperti yang digunakan pada method parameter.

< C# >
alt text

UpdateModel

Kita bisa juga memanfaatkan TryUpdateModel yang ada di Controller. Dan akan seperti pada gambar di bawah.

< VB.Net >
alt text

Sayang tersebut tidak berlaku di Controller pada ASP.Net-Core. Oleh karena itu kita buat interface seperti di bawah. Kita hanya menggunakan property Id dan property UserName.

< VB.Net >
alt text

< C# >
alt text

Dan itu di-implementasi-kan pada Model-nya.

< VB.Net >
alt text

< C# >
alt text

Bila kita mempunyai Model yang memiliki interface seperti ini. Maka kita bisa menggunakan override dari TryUpdateModel method.

< VB.Net >
alt text

ASP.Net-Core tidak memiliki method tersebut. Tapi ada persamaan untuk itu yang ada didalam Controller-nya. Method tersebut adalah TryUpdateModelAsync. Caranya hampir sama dengan yang di ASP.Net.

< C# >
alt text

Penutup

Demo ini hanya menggunakan Form saja, tapi kekreatifitasan cara kerja Mass Aassignment Vulnerability bisa beragam. Seperti pada tahun 2012, di mana GitHub (Ruby-on-Rails) terbukti memiliki kelemahan ini. Lebih parah lagi, yang dimasukkan berupa SSH-public-key yang menyebabkan repository dapat dikendalikan.

Mass Aassignment Vulnerability sudah lama ada dan seperti SQL-Injection masih saja programmer suka melupakan hal seperti ini. Tulisan ini dibuat sebagai pengingat, keamanan adalah fitur juga selain kecepatan dan kestabilan aplikasi.

Referensi

Perhatian! Code yang ditampilkan dalam tulisan ini merupakan ilustrasi dari yang ingin dipaparkan dan bukan production ready code.
Sudah banyak kejadian karena asal meng-copy-and-paste tanpa mengerti code yang diambil itu ke dalam production.
Selain itu perlu ada tambahan code dan test sebelum siap untuk digunakan secara utuh.