ทุกคนคุ้นเคยกับการฉีด SQL มันเป็นวิธีการโจมตีทั่วไป ผู้โจมตีป้อนชิ้นส่วน SQL แปลก ๆ บางส่วนบนข้อมูลแบบฟอร์มหรือ URL ของอินเทอร์เฟซเช่นคำสั่ง "หรือ '1' = '1'" ซึ่งอาจบุกรุกแอปพลิเคชันด้วยการตรวจสอบพารามิเตอร์ไม่เพียงพอ ดังนั้นเราต้องทำงานบางอย่างในแอปพลิเคชันของเราเพื่อป้องกันวิธีการโจมตีดังกล่าว ในบางแอพพลิเคชั่นที่มีความปลอดภัยสูงเช่นซอฟต์แวร์ธนาคารเรามักจะใช้วิธีการเปลี่ยนคำสั่ง SQL ทั้งหมดด้วยขั้นตอนที่เก็บไว้เพื่อป้องกันการฉีด SQL แน่นอนว่านี่เป็นวิธีที่ปลอดภัยมาก แต่เราอาจไม่ต้องการวิธีการที่เข้มงวดในการพัฒนาประจำวันของเรา
ในฐานะที่เป็นกรอบการคงอยู่ของเลเยอร์กึ่งอัตโนมัติกรอบ MyBatis จะต้องเขียนด้วยตนเองด้วยตนเอง ในเวลานี้แน่นอนว่าจำเป็นต้องป้องกันการฉีด SQL อันที่จริง SQL ของ MyBatis เป็นโครงสร้างที่มีฟังก์ชั่น "อินพุต + เอาต์พุต" คล้ายกับฟังก์ชันดังนี้:
<select id = "getBlogById" resultType = "blog" parameterType = "int"> <br> เลือก ID, ชื่อเรื่อง, ผู้แต่ง, เนื้อหาจากบล็อกที่ id =#{id} </select> ที่นี่ ParameterType ระบุประเภทพารามิเตอร์อินพุตและ ResultType หมายถึงประเภทพารามิเตอร์เอาต์พุต ในการตอบสนองต่อข้างต้นหากเราต้องการป้องกันการฉีด SQL เราจะต้องทำงานอย่างหนักในการป้อนพารามิเตอร์ ส่วนที่ไฮไลต์ในรหัสด้านบนเป็นส่วนที่พารามิเตอร์อินพุตถูกเชื่อมต่อใน SQL หลังจากผ่านพารามิเตอร์ให้พิมพ์คำสั่ง SQL ที่ดำเนินการแล้วคุณจะเห็นว่า SQL มีลักษณะเช่นนี้:
เลือก ID, ชื่อเรื่อง, ผู้แต่ง, เนื้อหาจากบล็อกที่ id =?
ไม่ว่าจะป้อนพารามิเตอร์ใด SQL ที่พิมพ์ออกมาก็เป็นเช่นนี้ นี่เป็นเพราะ MyBatis เปิดใช้งานฟังก์ชันการรวบรวมล่วงหน้า ก่อนที่จะดำเนินการ SQL SQL ข้างต้นจะถูกส่งไปยังฐานข้อมูลสำหรับการรวบรวม ในระหว่างการดำเนินการคุณสามารถใช้ SQL ที่รวบรวมได้โดยตรงและแทนที่ตัวยึดตำแหน่ง "?" เนื่องจากการฉีด SQL สามารถทำงานกับกระบวนการรวบรวมได้วิธีนี้สามารถหลีกเลี่ยงปัญหาการฉีด SQL ได้
mybatis บรรลุการคอมไพล์ SQL ล่วงหน้าได้อย่างไร? ในความเป็นจริงที่ด้านล่างของเฟรมเวิร์กคลาสที่เตรียมไว้ใน JDBC อยู่ในที่ทำงาน PreparedStatement เป็นคลาสย่อยของคำแถลงที่เราคุ้นเคยมาก วัตถุของมันมีคำสั่ง SQL ที่รวบรวม วิธีการ "พร้อม" นี้ไม่เพียง แต่ปรับปรุงความปลอดภัย แต่ยังปรับปรุงประสิทธิภาพเมื่อดำเนินการ SQL หนึ่งครั้งหลายครั้งเนื่องจาก SQL ได้รับการรวบรวมและไม่จำเป็นต้องรวบรวมเมื่อดำเนินการอีกครั้ง
ต้องบอกว่าเราสามารถป้องกันการฉีด SQL โดยใช้ mybatis ได้หรือไม่? ไม่แน่นอนโปรดดูรหัสต่อไปนี้:
<select id = "orderblog" resultType = "blog" parameterType = "แผนที่"> เลือก ID ชื่อผู้แต่งเนื้อหาจากการสั่งซื้อบล็อกโดย $ {orderParam} </select> หลังจากการสังเกตอย่างระมัดระวังรูปแบบของพารามิเตอร์อินไลน์ได้เปลี่ยนจาก "#{xxx}" เป็น $ {xxx} หากเรากำหนดพารามิเตอร์ "orderparam" เป็น "id" และพิมพ์ SQL ดูเหมือนว่า:
เลือก ID, ชื่อเรื่อง, ผู้แต่ง, เนื้อหาจากการสั่งซื้อบล็อกโดย ID
เห็นได้ชัดว่าสิ่งนี้ไม่สามารถป้องกันการฉีด SQL ได้ ใน myBatis พารามิเตอร์ในรูปแบบ "$ {xxx}" จะเข้าร่วมโดยตรงในการรวบรวม SQL ซึ่งเป็นการป้องกันการโจมตีแบบฉีด อย่างไรก็ตามเมื่อพูดถึงชื่อตารางไดนามิกและชื่อคอลัมน์เราสามารถใช้รูปแบบพารามิเตอร์เช่น "$ {xxx}" ดังนั้นเราจึงต้องประมวลผลพารามิเตอร์ดังกล่าวด้วยตนเองในรหัสเพื่อป้องกันการฉีด
สรุป: เมื่อเขียนคำสั่งการแมป mybatis ลองใช้รูปแบบ "#{xxx}" หากคุณต้องใช้พารามิเตอร์เช่น "$ {xxx}" คุณต้องทำงานกรองได้ดีด้วยตนเองเพื่อป้องกันการโจมตีการฉีด SQL
ข้างต้นเป็นเนื้อหาเต็มรูปแบบของกรอบการคงอยู่ของ Java MyBatis ป้องกันการฉีด SQL ที่บรรณาธิการนำมาให้คุณ ฉันหวังว่าทุกคนจะสนับสนุน wulin.com เพิ่มเติม ~