Validasi input data - Di mana? Berapa banyak? [Tutup]

28

Validasi input data selalu merupakan perjuangan internal bagi saya.

Di ambang menambahkan kerangka kerja dan kode keamanan nyata ke proyek penulisan ulang aplikasi lawas kami (yang sejauh ini cukup banyak menyimpan kode keamanan warisan-kartu yang kuat dan validasi data), saya bertanya-tanya lagi tentang berapa banyak yang harus saya validasikan, dimana, dll.

Selama 5 tahun saya sebagai pengembang Java profesional, saya membuat dan menyempurnakan aturan pribadi saya untuk validasi input data dan langkah-langkah keamanan. Karena saya ingin meningkatkan metode saya, saya ingin mendengar beberapa ide dari kalian. Aturan dan prosedur umum baik-baik saja, dan yang khusus Java juga.

Ringkasnya, ini adalah pedoman saya (terbuka pada gaya aplikasi web 3-tier), dengan penjelasan singkat:

  • Sisi klien tingkat pertama (browser): validasi minimal, hanya aturan yang tidak berubah-ubah (bidang email wajib, harus memilih satu item, dan sejenisnya); penggunaan validasi tambahan seperti "antara 6 dan 20 karakter" lebih jarang, karena ini meningkatkan pekerjaan pemeliharaan pada perubahan (dapat ditambahkan setelah kode bisnis stabil);

  • Sisi server tingkat 1 (penanganan komunikasi web, "pengontrol"): Saya tidak memiliki aturan untuk yang ini, tetapi saya percaya hanya manipulasi data dan kesalahan perakitan / penguraian yang harus ditangani di sini (bidang ulang tahun bukan tanggal yang valid); menambahkan validasi lebih lanjut di sini dengan mudah membuatnya menjadi proses yang sangat membosankan;

  • 2nd tier (lapisan bisnis): validasi solid, tidak kurang; input format data, rentang, nilai, pemeriksaan keadaan internal jika metode tidak dapat dipanggil kapan saja, peran / izin pengguna, dan sebagainya; gunakan sesedikit mungkin input data pengguna, ambil kembali dari database jika diperlukan; jika kita mempertimbangkan mengambil data basis data sebagai input juga, saya hanya akan memvalidasinya jika beberapa data spesifik diketahui tidak cukup dapat diandalkan atau rusak pada DB - pengetikan yang kuat melakukan sebagian besar pekerjaan di sini, IMHO;

  • Tingkat 3 (lapisan data / DAL / DAO): tidak pernah percaya banyak validasi diperlukan di sini, karena hanya lapisan bisnis yang seharusnya mengakses data (validasi mungkin pada beberapa kasus seperti "param2 tidak boleh nol jika param1 benar"); Namun perhatikan, bahwa ketika saya maksudkan "di sini" maksud saya "kode yang mengakses database" atau "metode pelaksana SQL", database itu sendiri benar-benar kebalikannya;

  • database (model data): perlu dipikirkan dengan baik, kuat dan dapat diterapkan sendiri untuk menghindari data yang salah dan korup pada DB sebanyak mungkin, dengan kunci primer yang baik, kunci asing, kendala, tipe data / panjang / ukuran / presisi dan sebagainya - Saya akan meninggalkan pemicu ini, karena mereka memiliki diskusi pribadi mereka sendiri.

Saya tahu validasi data awal itu bagus dan dari segi kinerja, tetapi validasi data berulang adalah proses yang membosankan, dan saya akui bahwa validasi data itu sendiri cukup menjengkelkan. Itu sebabnya begitu banyak coders melewatkannya atau melakukannya di tengah jalan. Selain itu, setiap validasi duplikat adalah bug yang mungkin terjadi jika tidak disinkronkan setiap saat. Itulah alasan utama saya saat ini lebih suka membiarkan sebagian besar validasi naik ke lapisan bisnis, dengan mengorbankan waktu, bandwidth dan CPU, pengecualian ditangani berdasarkan kasus per kasus.

Jadi, apa pendapat Anda tentang ini? Opini yang berlawanan? Apakah Anda memiliki prosedur lain? Referensi ke topik seperti itu? Setiap kontribusi adalah valid.

Catatan: jika Anda memikirkan cara Java untuk melakukan sesuatu, aplikasi kami berbasis pada Spring MVC dan MyBatis (kinerja dan model basis data yang buruk mengesampingkan solusi ORM); Saya berencana untuk menambahkan Spring Security sebagai penyedia keamanan kami ditambah JSR 303 (Hibernate Validator?)

Terima kasih!


Sunting: beberapa klarifikasi tambahan pada layer ke-3.

mdrg
sumber
Saran saya adalah mempelajari cara kerja Hibernate Validator. Saya belum menemukan JSR 303 berguna, karena validasi dimulai selama kegigihan, sedangkan beberapa aturan saya harus ditegakkan jauh sebelum kegigihan, karena saya memiliki aturan bisnis yang mengandalkan validasi dasar. Menurut pendapat saya, ini bekerja untuk model yang sangat tertutup; mungkin saya salah menggunakannya, tetapi saya tidak pernah menemukan orang dengan pengalaman berbeda dari saya.
Vineet Reynolds
@Vineet Reynolds Saya sudah menggunakannya untuk validasi formulir dengan Spring MVC, kombinasi yang sangat bagus. Saya mendapatkan validasi sisi server dengan pesan berbutir halus dengan sedikit atau tanpa usaha, kesalahan yang sesuai ditampilkan kepada pengguna. Saya masih mengujinya sepenuhnya pada objek sisi server, tidak yakin keuntungannya. Lihatlah contoh tulisan ini, begitulah cara saya menggunakannya: codemunchies.com/2010/07/…
mdrg
2
berikan terlalu banyak validasi. Dimana mana sialan itu input pengguna @ #! ! @@!
Chani

Jawaban:

17

Validasi Anda harus konsisten. Jadi, jika pengguna memasukkan beberapa data di formulir web yang dianggap valid, ia tidak boleh ditolak oleh lapisan basis data karena beberapa kriteria yang tidak Anda terapkan di sisi klien.

Sebagai pengguna, tidak ada yang lebih menyebalkan dengan memasukkan satu halaman data yang tampaknya benar hanya untuk diberitahu setelah perjalanan pulang-pergi yang signifikan ke database bahwa ada sesuatu yang salah. Ini akan benar terutama jika saya telah melakukan beberapa validasi klien dalam proses.

Anda perlu memiliki validasi di berbagai level saat Anda mengeksposnya dan berpotensi tidak memiliki kendali atas siapa yang memanggil mereka. Jadi, Anda perlu mengatur (sejauh mungkin) untuk validasi Anda untuk didefinisikan di satu tempat dan menelepon dari mana pun itu diperlukan. Bagaimana ini diatur akan tergantung pada bahasa dan kerangka kerja Anda. Di Silverlight (misalnya) Anda dapat mendefinisikannya di sisi server dan dengan atribut yang sesuai, ia akan disalin ke sisi klien untuk digunakan di sana.

ChrisF
sumber
2
+1 Benar-benar. Saya akan mengatakan hal yang sama tentang ASP.NET MVC, tetapi Anda mengalahkan saya untuk itu. :) Sungguh, kami hanya PERLU validasi di tempat untuk memastikan sistem tetap dalam keadaan valid. Sisa validasi seperti sisi klien adalah untuk meningkatkan kegunaan dan waktu yang terbuang untuk pengguna, sehingga harus menjadi fokus utama. Konsistensi adalah kuncinya.
Ryan Hayes
2
Tentang "perjalanan pulang-pergi", saya tidak melihat masalah selama halaman dimuat ulang dengan pesan kesalahan yang tepat dan semua bidang diisi dengan apa pun yang Anda ketik sebelumnya (sebagian besar antarmuka gagal dalam detail terakhir ini). Jika terlalu lama untuk kembali dengan kesalahan, maka itu adalah kandidat untuk validasi sisi klien tambahan.
mdrg
Dan tentu saja, jika validasi dapat direplikasi dengan mudah di seluruh aplikasi, tidak ada alasan untuk menyia-nyiakannya. Di sisi server itu mudah, tetapi di sisi klien, tanpa alat validasi seperti yang Anda sebutkan, menjadi sangat frustasi (yaitu: menulis banyak kode validasi JS, sama seperti yang Anda tulis di server) .
mdrg
10

Dalam sistem relasional, saya melihatnya sebagai pendekatan tiga lapis. Setiap lapisan dibatasi oleh yang di bawah ini:

  • Presentasi / UI
    • validasi input sederhana
    • jangan melanjutkan jika input dalam format yang salah
    • "gate" permintaan klien ke server untuk mengurangi round-trip, untuk kegunaan yang lebih baik dan mengurangi bandwidth / waktu
  • Logika
    • logika dan otorisasi bisnis
    • jangan biarkan pengguna melakukan hal-hal yang tidak boleh mereka lakukan
    • menangani properti "turunan" dan menyatakan di sini (hal-hal yang akan didenormalisasi dalam database)
  • Data
    • lapisan integritas data penting
    • benar-benar menolak untuk menyimpan barang bekas
    • DB itu sendiri memberlakukan format data (int, tanggal, dll.)
    • menggunakan batasan basis data untuk memastikan hubungan yang tepat

Yang ideal Jawaban untuk ini akan menjadi sebuah sistem yang memungkinkan Anda menentukan kendala sama sekali tiga lapisan di satu tempat. Ini akan melibatkan beberapa pembuatan kode untuk SQL, dan setidaknya beberapa validasi berbasis data untuk klien dan server.

Saya tidak tahu apakah ada peluru perak di sini ... tetapi karena Anda berada di JVM saya sarankan melihat Rhino untuk setidaknya berbagi kode validasi JavaScript antara klien dan server. Jangan tulis validasi input Anda dua kali.

John Cromartie
sumber
Saya akan melihat Badak. Jika itu bisa diintegrasikan dengan validasi form Spring MVC, jauh lebih baik.
mdrg
8

• Tingkat 3 (lapisan data / DAL / DAO): tidak pernah percaya banyak validasi diperlukan di sini, karena hanya lapisan bisnis yang seharusnya mengakses data (validasi mungkin pada beberapa kasus seperti "param2 tidak boleh nol jika param1 benar") .

Ini sangat salah. Tempat paling penting untuk memiliki validasi adalah di dalam database itu sendiri. Data hampir selalu dipengaruhi oleh lebih dari aplikasi (bahkan ketika Anda pikir itu tidak akan terjadi) dan itu tidak bertanggung jawab untuk tidak menempatkan kontrol yang tepat ke dalam database. Ada lebih banyak kehilangan integritas data dari keputusan untuk tidak melakukan ini daripada faktor lainnya. Integritas data sangat penting untuk penggunaan jangka panjang dari database. Saya belum pernah melihat database yang gagal menegakkan aturan integritas di level database yang berisi data yang baik (dan saya telah melihat data dalam ribuan database).

Dia mengatakan itu lebih baik daripada saya: http://softarch.97things.oreilly.com/wiki/index.php/Database_as_a_Fortress

HLGEM
sumber
Saya setuju dengan bagian terakhir dari artikel ini, saya kira saya belum menjelaskan bagian ini. Saya memperbarui pertanyaan dengan rincian lebih lanjut. Terima kasih!
mdrg
2

Semua hal di atas membuat asumsi bahwa pengembang dan pengelola adalah sempurna dan menulis kode sempurna yang selalu berjalan dengan sempurna. Rilis perangkat lunak masa depan tahu tentang semua asumsi yang Anda buat dan tidak pernah didokumentasikan, dan pengguna dan peretas yang memasukkan data ke dalam sistem dengan cara yang tidak pernah Anda bayangkan.

Tentu, terlalu banyak validasi adalah hal yang buruk, tetapi dengan asumsi program, jaringan dan OS sempurna, peretas tidak akan bisa menembus firewall Anda, DBA tidak akan secara manual "mengubah" database mungkin lebih buruk.

Gambarlah lingkaran batas di sekeliling benda-benda, identifikasi mode kegagalan yang dilindunginya dan terapkan tingkat pemeriksaan yang sesuai untuk batas itu. Misalnya, basis data Anda seharusnya tidak pernah melihat data yang tidak valid, tetapi bagaimana itu bisa terjadi dan bagaimana jika itu terjadi? Siapa pengguna Anda, berapa biaya kegagalan?

Mempelajari model keamanan dunia fisik, keamanan harus berlapis-lapis, seperti bawang. Satu tembok tebal dianggap keamanannya buruk. Validasi data harus dipertimbangkan dengan cara yang sama.

mattnz
sumber
1

Dua pendek, aturan umum untuk validasi:

Jika Anda akan memanggil apa pun yang tidak menjamin itu akan mengembalikan sesuatu (kesalahan, pengecualian) untuk memberi tahu Anda tentang input yang tidak valid dengan cara yang dapat Anda sampaikan kembali ke pemanggil Anda, validasikanlah.

Jika Anda akan melakukan hal lain dengan data (membuat keputusan, menghitung, menyimpan, dll.), Validasikan.

Blrfl
sumber