การตรวจสอบการป้อนข้อมูล - ที่ไหน? เท่าไหร่ [ปิด]


28

การตรวจสอบการป้อนข้อมูลเป็นเรื่องยากสำหรับฉัน

ในการเพิ่มกรอบความปลอดภัยและรหัสจริงลงในโครงการเขียนแอปพลิเคชันดั้งเดิมของเรา (ซึ่งตอนนี้ค่อนข้างจะรักษารหัสรักษาความปลอดภัยดั้งเดิมและการตรวจสอบความถูกต้องของข้อมูล) ฉันสงสัยอีกครั้งว่าควรจะตรวจสอบมากแค่ไหน ที่ไหน ฯลฯ

ตลอด 5 ปีที่ฉันเป็นนักพัฒนา Java มืออาชีพฉันได้สร้างและปรับปรุงกฎส่วนบุคคลของฉันสำหรับการตรวจสอบความถูกต้องของข้อมูลและมาตรการรักษาความปลอดภัย เมื่อฉันต้องการปรับปรุงวิธีการของฉันฉันอยากได้ยินความคิดเห็นจากพวกคุณ กฎและโพรซีเดอร์ทั่วไปนั้นใช้ได้ดีและจาวาเฉพาะก็เช่นกัน

สรุปนี่คือแนวทางของฉัน (เปิดเผยในรูปแบบเว็บแอปพลิเคชัน 3 ระดับ) พร้อมคำอธิบายสั้น ๆ :

  • ฝั่งไคลเอ็นต์ชั้นที่ 1 (เบราว์เซอร์): การตรวจสอบความถูกต้องน้อยที่สุด, กฎที่ไม่เปลี่ยนแปลงเท่านั้น (ฟิลด์อีเมลบังคับ, ต้องเลือกหนึ่งรายการ, และอื่น ๆ ที่คล้ายกัน); การใช้การตรวจสอบเพิ่มเติมเช่น "ระหว่าง 6 ถึง 20 ตัวอักษร" น้อยลงเนื่องจากจะเป็นการเพิ่มการบำรุงรักษาในการเปลี่ยนแปลง (อาจเพิ่มเมื่อรหัสธุรกิจมีเสถียรภาพ);

  • ฝั่งเซิร์ฟเวอร์ระดับที่ 1 (การจัดการการสื่อสารผ่านเว็บ "ตัวควบคุม"): ฉันไม่มีกฎสำหรับอันนี้ แต่ฉันเชื่อว่าควรจัดการเฉพาะการจัดการข้อมูลและข้อผิดพลาดการประกอบ / การแยกวิเคราะห์ที่นี่ (ฟิลด์วันเกิดไม่ใช่วันที่ที่ถูกต้อง) การเพิ่มการตรวจสอบเพิ่มเติมที่นี่ทำให้กระบวนการนั้นน่าเบื่อจริงๆ

  • ชั้นที่ 2 (ชั้นธุรกิจ): การรับรองความถูกต้องที่แข็งแกร่งของหินไม่น้อยกว่า; รูปแบบข้อมูลอินพุต, ช่วง, ค่า, การตรวจสอบสถานะภายในหากวิธีการไม่สามารถเรียกได้ทุกเวลา, บทบาท / สิทธิ์ของผู้ใช้และอื่น ๆ ; ใช้ข้อมูลอินพุตของผู้ใช้เพียงเล็กน้อยเท่าที่จะทำได้ดึงข้อมูลอีกครั้งจากฐานข้อมูลหากจำเป็น ถ้าเราพิจารณาดึงข้อมูลฐานข้อมูลเป็นอินพุตด้วยฉันจะตรวจสอบเฉพาะถ้าข้อมูลบางอย่างไม่น่าเชื่อถือหรือเสียหายเพียงพอในฐานข้อมูล - การพิมพ์ที่รัดกุมทำให้งานส่วนใหญ่ที่นี่ IMHO;

  • ชั้นที่ 3 (ชั้นข้อมูล / DAL / DAO): ไม่เคยเชื่อว่าจำเป็นต้องมีการตรวจสอบความถูกต้องเนื่องจากชั้นธุรกิจเท่านั้นที่ควรเข้าถึงข้อมูล (ตรวจสอบความถูกต้องในบางกรณีเช่น "param2 ต้องไม่เป็นโมฆะถ้า param1 เป็นจริง") โปรดสังเกตว่าเมื่อฉันหมายถึง "ที่นี่" ฉันหมายถึง "รหัสที่เข้าถึงฐานข้อมูล" หรือ "วิธีการประมวลผล SQL" ฐานข้อมูลนั้นตรงกันข้ามอย่างสมบูรณ์;

  • ฐานข้อมูล (ตัวแบบข้อมูล): ต้องมีความคิดที่ดีมีความแข็งแรงและบังคับใช้เองเพื่อหลีกเลี่ยงข้อมูลที่ไม่ถูกต้องและเสียหายในฐานข้อมูลให้มากที่สุดเท่าที่จะเป็นไปได้ด้วยคีย์หลักที่ดีคีย์ต่างประเทศข้อ จำกัด ประเภทข้อมูล / ความยาว / ขนาด / แม่นยำเป็นต้น - ฉันปล่อยให้สิ่งกระตุ้นเกิดขึ้นเพราะพวกเขามีการพูดคุยส่วนตัว

ฉันรู้ว่าการตรวจสอบความถูกต้องของข้อมูลในช่วงแรกนั้นดีและมีประสิทธิภาพ แต่การตรวจสอบความถูกต้องของข้อมูลเป็นกระบวนการที่น่าเบื่อและฉันยอมรับว่าการตรวจสอบความถูกต้องของข้อมูลนั้นค่อนข้างน่ารำคาญ นั่นเป็นสาเหตุที่โคเดอร์จำนวนมากข้ามไปหรือทำครึ่งทาง นอกจากนี้การตรวจสอบซ้ำทุกครั้งจะเป็นข้อผิดพลาดที่เป็นไปได้หากไม่มีการซิงโครไนซ์ตลอดเวลา นี่คือเหตุผลหลักที่ปัจจุบันฉันเลือกที่จะให้การตรวจสอบส่วนใหญ่ขึ้นอยู่กับเลเยอร์ธุรกิจโดยเสียเวลาแบนด์วิดท์และ CPU ยกเว้นการจัดการเป็นกรณีไป

แล้วคุณคิดอย่างไรเกี่ยวกับเรื่องนี้? ตรงข้ามกับความคิดเห็น? คุณมีวิธีการอื่นหรือไม่? การอ้างอิงถึงหัวข้อดังกล่าว? ผลงานใด ๆ ที่ถูกต้อง

หมายเหตุ: หากคุณกำลังคิดวิธีการทำ Java แอปของเราคือ Spring โดยใช้ Spring MVC และ MyBatis (ประสิทธิภาพและรูปแบบฐานข้อมูลที่ไม่ดีออกกฎ ORM) ฉันวางแผนที่จะเพิ่ม Spring Security เป็นผู้ให้บริการด้านความปลอดภัยของเราบวก JSR 303 (Hibernate Validator?)

ขอบคุณ!


แก้ไข: ชี้แจงพิเศษบางอย่างในชั้นที่ 3


คำแนะนำของฉันคือการศึกษาว่าตัวตรวจสอบความถูกต้องของ Hibernate ทำงานอย่างไร ฉันไม่พบ JSR 303 ว่ามีประโยชน์สำหรับการตรวจสอบความถูกต้องในระหว่างการคงอยู่ในขณะที่กฎบางอย่างของฉันจะต้องมีการบังคับใช้มากก่อนที่จะคงอยู่เพราะฉันมีกฎธุรกิจที่ต้องอาศัยการตรวจสอบขั้นพื้นฐาน ในความคิดของฉันมันใช้งานได้กับโมเดลที่ปิดมาก บางทีฉันอาจใช้มันไม่ถูกต้อง แต่ฉันไม่เคยพบใครที่มีประสบการณ์แตกต่างจากของฉัน
Vineet Reynolds

@Vineet Reynolds ฉันใช้ไปแล้วสำหรับการตรวจสอบแบบฟอร์มกับ Spring MVC มันเป็นการผสมผสานที่ยอดเยี่ยมจริงๆ ฉันได้รับการตรวจสอบความถูกต้องของฝั่งเซิร์ฟเวอร์พร้อมข้อความที่ละเอียดโดยไม่ต้องใช้ความพยายามเพียงใดถึงจะแสดงข้อผิดพลาดที่เหมาะสมแก่ผู้ใช้ ฉันยังคงทดสอบกับวัตถุฝั่งเซิร์ฟเวอร์ทั้งหมดไม่แน่ใจในข้อดี ลองดูที่โพสต์ตัวอย่างนี้เป็นเพียงวิธีที่ฉันใช้มัน: codemunchies.com/2010/07/…
mdrg

2
ใส่การตรวจสอบมากเกินไป ทุกที่ที่ผู้ใช้เหล่านั้นใส่ @ #! ! @@!
Chani

คำตอบ:


17

การตรวจสอบของคุณควรสอดคล้อง ดังนั้นหากผู้ใช้ป้อนข้อมูลบางอย่างบนเว็บฟอร์มซึ่งพิจารณาแล้วว่าถูกต้องมันไม่ควรถูกปฏิเสธโดยเลเยอร์ฐานข้อมูลเนื่องจากเกณฑ์บางอย่างที่คุณไม่ได้นำไปใช้กับฝั่งไคลเอ็นต์

ในฐานะที่เป็นผู้ใช้คงไม่มีอะไรน่ารำคาญไปกว่านี้ที่การป้อนข้อมูลหน้าเพจอย่างถูกต้องจะบอกได้หลังจากการเดินทางไปยังฐานข้อมูลที่สำคัญว่ามีบางอย่างผิดปกติ นี่จะเป็นจริงโดยเฉพาะอย่างยิ่งหากฉันเพิ่มจำนวนการตรวจสอบความถูกต้องของลูกค้าในกระบวนการ

คุณจำเป็นต้องมีการตรวจสอบความถูกต้องในระดับต่าง ๆ เมื่อคุณเปิดเผยสิ่งเหล่านี้และอาจไม่มีการควบคุมว่าใครเป็นคนเรียก ดังนั้นคุณต้องจัดเรียง (เท่าที่จะทำได้) เพื่อให้การตรวจสอบของคุณถูกกำหนดไว้ในที่เดียวและโทรจากที่ไหนก็ได้ที่จำเป็น วิธีการจัดเรียงนี้จะขึ้นอยู่กับภาษาและกรอบงานของคุณ ใน Silverlight (ตัวอย่าง) คุณสามารถกำหนดไว้ที่ฝั่งเซิร์ฟเวอร์และด้วยคุณสมบัติที่เหมาะสมมันจะถูกคัดลอกไปยังฝั่งไคลเอ็นต์เพื่อใช้ที่นั่น


2
+1 แน่นอน ฉันกำลังจะพูดในสิ่งเดียวกันเกี่ยวกับ ASP.NET MVC แต่คุณเอาชนะฉันมัน :) จริงๆแล้วเราต้องทำการตรวจสอบความถูกต้องเท่านั้นเพื่อให้แน่ใจว่าระบบอยู่ในสถานะที่ถูกต้อง ส่วนที่เหลือของการตรวจสอบเช่นด้านลูกค้าคือการเพิ่มการใช้งานและเสียเวลาสำหรับผู้ใช้ดังนั้นควรเน้นหลัก ความสอดคล้องเป็นกุญแจสำคัญ
Ryan Hayes

2
เกี่ยวกับ "การเดินทางไปกลับ" ฉันเห็นว่าไม่มีปัญหาตราบใดที่หน้าเว็บได้รับการโหลดซ้ำพร้อมข้อความแสดงข้อผิดพลาดที่เหมาะสมและฟิลด์ทั้งหมดที่กรอกข้อมูลด้วยสิ่งที่คุณพิมพ์มาก่อน (อินเทอร์เฟซส่วนใหญ่ขาดรายละเอียดสุดท้าย) หากใช้เวลานานเกินไปในการรับข้อผิดพลาดแสดงว่าเป็นตัวเลือกสำหรับการตรวจสอบความถูกต้องของฝั่งไคลเอ็นต์เพิ่มเติม
mdrg

และแน่นอนว่าหากการตรวจสอบสามารถทำซ้ำได้อย่างง่ายดายทั่วทั้งแอปไม่มีเหตุผลที่จะต้องเสียสิ่งนั้น ในฝั่งเซิร์ฟเวอร์นั้นง่าย แต่ในฝั่งไคลเอ็นต์หากไม่มีเครื่องมือตรวจสอบความถูกต้องเช่นที่คุณพูดถึงมันจะทำให้หงุดหงิดมาก (เช่น: การเขียนรหัสตรวจสอบ JS จำนวนมากเหมือนกับที่คุณเขียนที่เซิร์ฟเวอร์) .
mdrg

10

ในระบบสัมพันธ์ฉันเห็นว่ามันเป็นแนวทางสามชั้น แต่ละเลเยอร์ถูก จำกัด โดยเลเยอร์ด้านล่าง:

  • การนำเสนอ / UI
    • การตรวจสอบอินพุตอย่างง่าย
    • อย่าดำเนินการหากอินพุตอยู่ในรูปแบบที่ไม่ถูกต้อง
    • ลูกค้า "gate" ร้องขอไปยังเซิร์ฟเวอร์เพื่อลดการเดินทางไปกลับเพื่อการใช้งานที่ดีขึ้นและลดแบนด์วิดท์ / เวลา
  • ตรรกะ
    • ตรรกะทางธุรกิจและการอนุญาต
    • อย่าให้ผู้ใช้ทำสิ่งที่ไม่ได้รับอนุญาต
    • จัดการคุณสมบัติ "ที่ได้รับ" และสถานะที่นี่ (สิ่งที่จะ denormalized ในฐานข้อมูล)
  • ข้อมูล
    • ชั้นความสมบูรณ์ของข้อมูลที่สำคัญ
    • ปฏิเสธที่จะเก็บขยะอย่างแน่นอน
    • ฐานข้อมูลเองบังคับใช้รูปแบบข้อมูล (int, date, etc. )
    • ใช้ข้อ จำกัด ของฐานข้อมูลเพื่อให้แน่ใจว่าความสัมพันธ์ที่เหมาะสม

เหมาะคำตอบนี้จะเป็นระบบที่ช่วยให้คุณสามารถกำหนดข้อ จำกัด ที่ทั้งสามชั้นในสถานที่หนึ่ง สิ่งนี้จะเกี่ยวข้องกับการสร้างรหัสบางอย่างสำหรับ SQL และอย่างน้อยก็มีการตรวจสอบความถูกต้องของข้อมูลสำหรับลูกค้าและเซิร์ฟเวอร์

ฉันไม่รู้ว่ามี bullet เงินที่นี่หรือไม่… แต่เนื่องจากคุณอยู่ใน JVM ฉันขอแนะนำให้ดู Rhino เพื่อแบ่งปันรหัสการตรวจสอบ JavaScript อย่างน้อยระหว่างไคลเอนต์และเซิร์ฟเวอร์ อย่าเขียนการตรวจสอบอินพุตของคุณสองครั้ง


ฉันจะดูแรด ถ้ามันสามารถบูรณาการอย่างใดอย่างหนึ่งกับการตรวจสอบรูปแบบ Spring MVC ดีขึ้นมาก
mdrg

8

•ชั้นที่ 3 (ชั้นข้อมูล / DAL / DAO): ไม่เคยเชื่อว่าจำเป็นต้องมีการตรวจสอบความถูกต้องเนื่องจากชั้นธุรกิจเท่านั้นที่ควรเข้าถึงข้อมูล (ตรวจสอบความถูกต้องในบางกรณีเช่น "param2 ต้องไม่เป็นโมฆะถ้า param1 เป็นจริง") .

นี่มันผิดมาก สถานที่สำคัญที่สุดในการตรวจสอบความถูกต้องอยู่ในฐานข้อมูล ข้อมูลได้รับผลกระทบจากแอปพลิเคชั่นเกือบทุกครั้ง (แม้ว่าคุณจะคิดว่ามันไม่ได้เป็น) และมันจะไม่รับผิดชอบที่ดีที่สุดที่จะไม่ทำการควบคุมที่เหมาะสมลงในฐานข้อมูล มีการสูญเสียความสมบูรณ์ของข้อมูลจากการตัดสินใจที่จะไม่ทำสิ่งนี้มากกว่าปัจจัยอื่น ๆ ความถูกต้องของข้อมูลมีความสำคัญต่อการใช้ฐานข้อมูลในระยะยาว ฉันไม่เคยเห็นฐานข้อมูลใด ๆ ที่ล้มเหลวในการบังคับใช้กฎความสมบูรณ์ในระดับฐานข้อมูลที่มีข้อมูลที่ดี (และฉันได้เห็นข้อมูลในฐานข้อมูลหลายพันตัว)

เขาบอกว่าดีกว่าที่ฉันทำได้: http://softarch.97things.oreilly.com/wiki/index.php/Database_as_a_Fortress


ฉันเห็นด้วยกับข้อสุดท้ายของบทความนี้ฉันเดาว่าฉันไม่ได้ทำให้ชัดเจนในส่วนนี้ ฉันอัพเดตคำถามพร้อมรายละเอียดเพิ่มเติม ขอบคุณ!
mdrg

2

ทั้งหมดข้างต้นทำให้สมมติฐานที่ว่านักพัฒนาและผู้ดูแลระบบนั้นสมบูรณ์แบบและเขียนโค้ดที่สมบูรณ์แบบที่ทำงานได้อย่างสมบูรณ์แบบเสมอ การเปิดตัวซอฟต์แวร์ในอนาคตรู้เกี่ยวกับสมมติฐานทั้งหมดที่คุณทำและไม่เคยบันทึกไว้และผู้ใช้และแฮ็กเกอร์ที่นำข้อมูลเข้าสู่ระบบในแบบที่คุณไม่เคยคาดคิดมาก่อน

แน่นอนว่าการตรวจสอบมากเกินไปนั้นเป็นสิ่งที่ไม่ดี แต่สมมติว่าโปรแกรมเครือข่ายและระบบปฏิบัติการนั้นสมบูรณ์แบบแฮกเกอร์จะไม่ผ่านไฟร์วอลล์ของคุณ DBAs จะไม่ทำการ "ปรับแต่ง" ฐานข้อมูลด้วยตนเอง

วาดวงกลมขอบเขตรอบสิ่งต่าง ๆ ระบุโหมดความล้มเหลวที่ป้องกันและใช้ระดับการตรวจสอบที่เหมาะสมสำหรับขอบเขตนั้น ตัวอย่างเช่นฐานข้อมูลของคุณไม่ควรเห็นข้อมูลที่ไม่ถูกต้อง แต่จะเกิดอะไรขึ้นและจะเกิดอะไรขึ้น? ใครคือผู้ใช้ของคุณค่าใช้จ่ายของความล้มเหลวคือเท่าไร

ศึกษารูปแบบความปลอดภัยทางกายภาพของโลกความปลอดภัยควรอยู่ในเลเยอร์เหมือนหัวหอม กำแพงหนาหนึ่งหลังถือว่าปลอดภัย การตรวจสอบข้อมูลควรพิจารณาในลักษณะเดียวกัน


1

กฎทั่วไปสั้น ๆ สองข้อสำหรับการตรวจสอบ:

หากคุณกำลังจะโทรหาสิ่งที่ไม่รับประกันว่ามันจะส่งคืนบางสิ่ง (ข้อผิดพลาดข้อยกเว้น) เพื่อบอกคุณเกี่ยวกับการป้อนข้อมูลที่ไม่ถูกต้องในวิธีที่คุณสามารถส่งกลับไปยังผู้โทรของคุณตรวจสอบได้

หากคุณกำลังจะทำอะไรกับข้อมูล (ทำการตัดสินใจทำคณิตศาสตร์เก็บไว้ ฯลฯ ) ตรวจสอบความถูกต้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.