ke3
Kamis, 30 November 2017
Senin, 20 November 2017
OWASP dan dosa dalam Web Application Security
OWASP dan dosa dalam Web Application
Security
Materi oleh Satria Ady Pradana
Satria Ady Pradana akan sharing tentang
OWASP dan dosa-dosa yang sering programmer lakukan terkait dalam security
terutama web.
apa itu OWASP?
apa dosa yang sering dilakukan?
apakah kita juga termasuk sering
berdosa?
Disini akan dibahas OWASP terlebih dahulu.
OWASP atau Open Web Application Security
Project adalah komunitas yang berinisiatif untuk menghimpun resource dan
mencerahkan orang lain terkait web application security. Yang paling terkenal
dari OWASP adalah OWASP Top 10 project, dimana setiap beberapa tahun sekali
mereka merilis 10 common security risks yang ada direntang waktu itu. Misal
yang mau rilis bentar lagi adalah OWASP Top 10 2017, sebelumnya OWASP Top 10
2013. Di OWASP Top 10 2017 kita akan bisa melihat kira-kira apa aja sih yang
menjadi tren security risk di dunia.
OWASP Top 10 bisa dilihat di sini:
https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project
Untuk saat ini, versi 2017 mencapai RC2
yang bisa diunduh di sini:
https://github.com/OWASP/Top10/blob/master/2017/OWASP%20Top%2010%202017%20RC2%20Final.pdf
10 peringkat ini sering menjadi acuan
pentester untuk melakukan security awareness sekaligus juga panduan dalam
pentesting.
1. Injection
2. Broken Authentication
3. Sensitive Data Exposure
4. XML External Entities (XXE)
5. Broken Access Control
6. Security Msiconfiguration
7. Cross-Site Scripting
8. Insecure Deserialization
9. Using COmponents with Known
Vulnerabilities
10. Insufficient Logging & Monitoring
Tapi...
Kalau bisa kita rangkum dan ambil inti sarinya
kita bisa berpedoman pada satu mantra:
“Jangan sembarang percaya kepada apa
yang user berikan”.
Selain merilis 10 common security risk
tadi, OWASP juga memberikan guideline juga bagaimana mengetes aplikasi dan
bagaimana mendesain aplikasi web yang secure.
Misalnya disini, secure coding:
https://www.owasp.org/index.php/OWASP_Secure_Coding_Practices_-_Quick_Reference_Guide
Code review:
https://www.owasp.org/index.php/Category:OWASP_Code_Review_Project
Testing (pentesting juga):
https://www.owasp.org/index.php/OWASP_Testing_Project
Ada banyak sebenarnya tapi kita bahas
yang umum saja dan yang sering menjadi dosa, karena programmer mengabaikan itu.
Seperti yang disinggung tadi, ada satu mantra yang perlu diingat: “Jangan
sembarang percaya kepada apa yang user berikan”. Most of vulnerability yang
terjadi akibat programmer tidak melakukan sanitasi atau filtrasi terhadap
inputan user.
Ini bukan hanya tentang SQL injection,
jenis vulnerability yang paling sering terdengar, tapi in general di security,
pengamanan itu ada di 3 fase: data yang dikirim (transmit), data yang diproses,
dan data yang disimpan.
Mungkin sebagian dari kita sering
mendengar yang namanya SQL injection, tapi sebenernya bukan hanya itu saja
injection yang ada. Point 1 di OWASP Top 10 merangkum banyak sekali injection
seperti SQL query, LDAP query, dsb yang menjadi inputan user jika suatu input
menjadi bagian / komponen suatu query maka kita harus melakukan sanitasi
terhadap input tersebut. Hal-hal yang perlu diperhatikan adalah adanya komponen
pembentuk query didalam inputan user, sehingga user bisa memanipulasi query
sesuka hati. Masih ada yang melakukan pembentukan query seperti ini (misal
disederhanakan):
sql = "SELECT kolom1, kolom2 FROM
tabel WHERE userid='" + $id + "' ";
Dosa pertama dari programmer adalah
seperti ini:
Dengan $id tanpa disanitasi terlebih
dahulu, untuk fungsi sanitasi bisa ke bahasa masing-masing.
Tapi model yang lebih baik adalah dengan
melakukan parameterized untuk pembentukan query tak hanya SQL query, inputan
user pun harus disanitasi untuk komponen-komponen yang bisa membuat script
seperti kode-kode javascript. Harus di-escape terlebih dahulu.
Yang cukup jarang ada dan kadang terlupa
adalah LDAP atau Directory protocol seperti query Active Directory. Ada juga
model pengembangan aplikasi menggunakan ORM. Kadang juga tetap ada yang berdosa
dengan lalai melakukan sanitasi ini.
Di OWASP Testing Guide v4 juga terdapat
panduan untuk mengetes SQL Injection pada ORM, jadi jika dalam pikiran kita
"tinggal pake ORM udah aman" maka sebaiknya segera bertobat. Tadi
dijelaskan juga, input bisa berupa javascript maupun html tag. Biasanya inputan
yang rentan terhadap ini bisa dimanfaatkan untuk menginjeksi kode javascript
sehingga mentrigger yang namanya Cross-Side Scripting. Inti dari kelemahan ini
adalah user korban bisa menjalankan script yang diberikan oleh attacker. Dampaknya
apa?
Yang klasik adalah mencuri session korban
tersebut (mendapatkan session aktif = attacker bisa masuk ke sistem sebagai
korban). Ada pula kemungkinan kedua, melakukan phising, misalnya menggunakan
script untuk membuat layer, membuat halaman palsu untuk menjebak korban dan bisa
juga sekedar me-redirect korban ke suatu tempat yang lain dan menyuruhnya untuk
"login" untuk bertobat dari ini, lakukan sanitasi untuk inputan yang
akan ditampilkan ke user, baik inputan yang akan disimpan di database, maupun
yang lain.
Selanjutnya adalah mengenai sesi.
Jika dibeberapa kondisi diatas bisa
diatasi dengan penggunaan fasilitas yang disediakan oleh platform maupun
framework, kerentanan ini cukup banyak terjadi karena penerapan logic yang
kurang. Beberapa aplikasi yang Satri uji sudah menerapkan user management,
dimana setiap user punya kewenangan dan resource tertentu yang harusnya hanya
dia dan orang-orang yang setingkat dengannya yang bisa memproses.
Ada beberapa dosa disini:
Pertama, tidak memeriksa / memvalidasi
privilege yang sudah diterapkan.
Misal, setiap user memiliki id. Setiap
user dapat membuat dan mengedit task, yang direpresentasikan dengan id pula.
Terkadang ketika kita mau mengedit task / dokumen / apapun kita hanya melihat
id dokumen tersebut. Mungkin diawal ketika kita menampilkan daftar dokumen kita
sudah memfilter "hanya dokumen yang dimiliki oleh si A" yang dapat
tampil. Tapi kemudian ketika request untuk edit dengan seperti ini:
GET /GetDokumen.php?id=1654
Dengan melakukan perubahan nilai id aku
bisa mengedit dokumen milik orang lain. Katakanlah bukan GET tapi POST, tidak
akan berpengaruh. Selama tidak ada pengecekan, maka aku akan bisa mengeditnya.
Dulu kerentanan ini disebut sebagai IDOR (InDirect Object Reference), sekarang
bernama Broken Access Control, modifikasi URL, state internal HTML, atau
request yang dikirimkan adalah proses standard yang biasanya dilakukan.
Kedua, tidak memvalidasi apakah benar
request ini berasal dari user yang sesungguhnya.
Pernah dengar CSRF? Cross-Site Request
Forgery. Secara singkat, user akan ditipu untuk melakukan sesuatu / mengirimkan
request, tanpa sepengetahuannya. Biasanya ini dilakukan dengan kombo XSS.
Misalnya ketika mengunjungi suatu
halaman, user yang terjebak akan mengirimkan request ke endpoint tertentu untuk
melakukan transfer dana. Untuk mengatasi hal ini, diperlukan suatu yang unik
yang hanya valid untuk individual request yang memang dikirimkan oleh user,
bukan hasil kerja script. Dan ini disebut CSRF token, sebuah token unik yang
di-generate dan dikirimkan oleh system ke user, dan harus dikirimkan oleh user
ketika dia melakukan request pada saat itu.
Ketiga, mengeluarkan semua data yang gak
"penting". Maksudnya tidak penting ini bagaimana?
Misal kita hanya butuh kolom nama dan
segala riwayat dalam operasi "cek profil", tapi kita mengeluarkan semua
kolum dalam baris itu dan misal dalam baris tersebut ada juga kolom yang ikut
dikeluarkan seperti "kategori user". Isi kolom-kolom ini diberikan
begitu saja, dan akan dikembalikan ke sistem. Secara tampilan user hanya bisa
mengedit kolom nama dan biodata saja, tapi request yang terkirim adalah semua
kolom. Dan pernah kejadian, Satria mengedit kolom role ini bisa membuat berubah
role dari pegawai biasa menjadi administrator (setelah menganalisis sistem
penamaan role), kadang kita memaklumi bahwa untuk mendapatkan data terkadang
kita gak ambil pusing dan lempar saja 1 objek (1 baris database) dan simpan perubahannya.
Tapi ini cukup fatal, untuk mengatasinya adalah dengan mengeluarkan apa yang
kita butuhkan. Jika tidak memungkinkan, hanya proses apa yang kita butuhkan.
Ketiga dosa diatas tidak bisa diatasi
dengan solusi WAF atau parameterized query. Karena itu pure logic. Jadi selalu
lakukan validasi.
Dosa yang berikutnya adalah terlalu
mengandalkan validasi di sisi client.
Beberapa aplikasi yang Satria uji berupa
web service dengan front-end adalah sebuah mobile application (android).
Validasi input cukup bagus di mobile app, kami tidak bisa input macam-macam.
Tapi ternyata setelah kami dapatkan endpoint, kami bisa tembak langsung request
ke sana. File upload yang harusnya dibatasi hanya bisa png ternyata hanya bisa
divalidasi di sisi app, ketika di sisi server tidak ada validasi. Akhirnya kami
bisa upload shell ke sana dan btw, itu server bank yang gak bisa Satria sebutkan.
Ini dosa yang cukup berat, hanya melakukan validasi di sisi client dan ada
beragam dosa yang sudah dicontohkan diatas.
Intinya adalah jangan percaya begitu
saja apa yang diberikan oleh client. Sebenarnya akan ada banyak sekali
dosa-dosa yang bisa disampaikan, tapi Satria harap dengan beberapa contoh di
atas kita bisa mengambil hikmah untuk "tetap memvalidasi inputan
user" dan setelah ini, periksa code kita lagi, apakah ada dosa-dosa
seperti itu.
Ada banyak sekali jenis-jenis
vulnerability dan Satria menyarankan untuk baca-baca OWASP baik dari OWASP Top
10, OWASP Secure Coding Guide, dan OWASP Testing Guide. Masing-masing
memberikan pemahaman berbeda tentang security, dari sisi pengembang dan sisi
penyerang.
“Ngeri ya, sekelas Bank bisa seceroboh
itu. Itu bank lokal Kak?”
“Kebetulan local.”
Kadang kita "memaklumi" bahwa
deadline yang singkat membuat orang lebih fokus ke fungsionalitas. Yang penting
jalan dulu. Oh ya, dampaknya kalo Satria bisa tanam webshell tadi, Satria bisa
remote server-nya, jalankan command, hingga bisa gerak untuk manipulasi server
dan kalau mau sebutin semua dosa mah banyak amat, batasi aja dengan
contoh-contoh diatas. Yang penting kudu paham mantranya aja.
Satria pernah liat di HackerOne, tentang
XSS. Kalau secara awam seperti XSS tidak terlalu parah. Tapi kenapa XSS banyak
reward yang didapat dari XSS vuln. Sebenernya seberapa parah XSS itu efeknya?
Nah, ini yang menarik. Kadang report XSS
cuman sekedar bisa nampilin alert('1') tapi jika diolah dengan benar, kita bisa
melakukan apapun. Secara, javascript itu jalan di sisi client.
Misal Satria sisipin kode untuk download
malware, bagaimana? Download malware dan jalankan. Terus nanti ada report bahwa
situs X menyebarkan malware, bakal hilang tidak trust-nya? atau finansial ya
tadi, kita membuat tampilan yang mengecoh, batas akhir hanyalah kreatifitas
Oh, ada satu quote (?) menarik.
“Orang yang lebih memahami sistem adalah
developer atau pembuatnya, semua logic yang ada adalah buatan para developer.
Jadi harusnya developer lebih tahu daripada penyerang. Tinggal bagaimana kita
bisa mengetahui kesalahan yang umum terjadi.”
Pertanyaan:
Halo kak, mau tanya tentang sanitasi
user input untuk mencegah xss misal studi kasusnya blog, yang ada kolom
komentar. User kan bisa aja input kode js disitu kolom komentar. Lalu memblok
kode js saja apakah cukup?
aku kasih reference deh, yang cukup
bagus: The Web Application hacker's Handbook" in most case, cukup. Escape
aja semua karakter pembentuk kodenya.
Wah berarti tag lain selain
<script> tidak akan menyebabkan masalah xss?
Kalau tag html yang lain namanya bukan
XSS tapi HTML injection jadinya. Dan ya harus disanitasi juga. Baiknya semua
tag di-escape prevention XSS bisa dilihat di OWASP.
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
Utk ngehash password, md5 kan udah
broken ya.
Penggantinya banyak, tapi yang
direkomendasikan pakai apa ya kak?
Lalu, kan ada yang implementasi salt juga
ya di password??
Sebenarnya sebaiknya kita simpan salt
dimana kak? Di database kah atau di kode (hardcoded / conf file?)
Kalau di db, kena sql injection, bubar
ketauan salt nya, best practice nya gimana yah kak?
*maaf klo pertanyaan nya trlalu cupu
Jadi gini, perlu dipahami dulu goal kita
apa, kita perlu memproteksi password, jangan disimpan dalam bentuk plaintext
atau terbaca begitu saja. Kenapa "hanya menggunakan hash saja" itu
tidak disarankan? karena ada:
1. kemungkinan collision
2. ada banyak bertebaran kamus pasangan
antara text dengan bentuk hash-nya
Nah yang dimaksud broken lebih ke arah
"dimungkinkan untuk mencari A sedemikian hingga hash(A) = hash(password)
dengan A != B". Jadi bukan nilai hash didapatkan kembali password-nya.
Ohh gitu, I see password yang berbeda
hash nya bisa sama
Collision itu apa kak?
Collision itu tubrukan.
In this case kita perlu salt sehingga
nilai yang akan di-hash bukanlah password doang tapi kombinasi antara salt dan
password.
Misal, kalo cuman 1 salt dan 1 password
bisa diperoleh kombinasi cara seperti ini:
salt+password
password+salt
pass+salt+word
Tapi salt ini tidak boleh statis atau
sama terhadap semua user, kita harus bikin mekanisme generation salt yang cukup
random tapi cukup mudah dibikin ulang menyimpan ke database juga gak aman,
kenapa? ada kemungkinan ketika sudah berhasil SQL injection maka database
di-dump termasuk salt. Nah kuncinya adalah "generate salt yang random tapi
bisa didapatkan berulang-ulang" alais pseudorandom. Jadi gak perlu
disimpan -> gak perlu khawatir kalo data jebol maka salt ketebak. Ya, selama
aplikasi gak di-reverse sih.
Misal ada password, kita sebut B, ketika
dioperasikan fungsi hash jadi hash(B). Kita berusaha menemukan tubrukan atau
kondisi dimana sesuatu A di hash menjadi hash(A) memiliki nilai yang sama
dengan hash(B). Padahal A dan B bukanlah nilai yang sama
https://en.wikipedia.org/wiki/Collision_attack
Selama ini aku bingung karena kalau orang
tahu salt nya, nanti tahu password nya juga kan, kayak tubrukan motor lah,
motor berbeda tapi mereka berada di lintasan yang sama, tempat yang sama, dan
waktu yang sama maka tabrakan dong.
Abis ini aku baca2 dulu ttg pseudorandom
itu.
Ini juga, hash(A) dan hash(B) nilainya
sama, padahal A dan B beda
Oh ya, saran juga!! jangan pake
encryption buat menyimpan password.
Selalu gunakan hash + salt
Password udah di hash+salt
Salt digenerate random. Tapi, Ketika
login, gimana cara kirim "username+password" yg aman ya?
Kalau di sniff bukan kah ketauan juga
"password" nya apa?
Semua hash pasti akan ada collision.
Ingat prinsip pigeonhole aja di kuliah.
Hash itu kan nilai hasilnya selalu sama
panjangnya. Dari data input yang tak terbatas panjangnya direduksi hasilnya
jadi sekian bit, pasti akan ada input beda yang menghasilkan output sama, cuman
yang jadi pertanyaan, bisa gak kita cari pattern supaya membuat collision itu
practically happen. Ada beberapa yang mengandalkan komunikasi HTTPS ketika
login sehingga jalur dienkripsi.
Ada yang mengandalkan transformasi dulu
di sisi client sebelum dikirim ke server, regardless ada atau tidaknya saluran
HTTPS. Idenya adalah server mengirimkan semacam "key" dan password
ini diproses macam apapun dengan key itu sebelum dikirim. Pendekatan ini
mencegah si pengendus atau orang ketiga untuk membaca password terang-terangan.
Minimal dia harus tau bagaimana cara password itu dibentuk. But, selalu ada
cara untuk mengakali sih.
Salah satu caranya yaitu enkripsi.
Misalnya kalau pakai php deh yang umum,
tidak kebayang transformasi di client nya gimana
Javascript. Kebayangnya kirim data Nya
ke server dulu, terus transformasi disana.
Javascript enkrip dulu sebelum dikirim,
baru ketemu.
Salah satunya:
https://code.google.com/archive/p/crypto-js/
Inilah materi dari Kak Satria tentang OWASP
dan dosa-dosa yang sering programmer lakukan terkait dalam security terutama web.
Saya akan kasih materi lain yang InsyaAllah bermanfaat untuk kalian semua.
Tunggu Blogku SELANJUTNYA……………….
Langganan:
Postingan (Atom)
Metode Perancangan Basis Data
Metode perancangan basis data secara umum dikelompokkan kedalam: 1. Preliminary Design 2. Scratching Methode 1. Preliminary Design, Cirinya...
-
Materi Mata Kuliah Bahasa Indonesia: 1. Bahasa Sebuah Pemahaman 2. Ejaan 3. Penalaran 4. Kalimat 5. ...
-
Diskusi - WBS 1. Berikan contoh Gant Chart pada sistem informasi ! Jawab: Salah satu contoh PIC, pada kegiat...