ฉันเพิ่งใช้ mybatis เมื่อเร็ว ๆ นี้ ฉันเคยใช้ Ibatis มาก่อน โดยรวมแล้วมันคล้ายกัน แต่ฉันก็ยังพบปัญหามากมาย ฉันจะบันทึกอีกครั้ง
ก่อนอื่นให้ฉันแนะนำความแตกต่างระหว่าง #{} และ $ {} ใน mybatis ดังต่อไปนี้:
1. # ปฏิบัติต่อข้อมูลที่เข้ามาทั้งหมดเป็นสตริงและเพิ่มคำพูดสองครั้งลงในข้อมูลขาเข้าโดยอัตโนมัติ ตัวอย่างเช่น: สั่งซื้อโดย #user_id #หากค่าที่ส่งผ่านคือ 111 จากนั้นค่าเมื่อการแยกวิเคราะห์เป็น SQL เป็นคำสั่งซื้อโดย "111" หากค่าที่ส่งผ่านคือ ID การแยกวิเคราะห์เป็น SQL จะเป็นคำสั่งซื้อโดย "ID"
2. $ แสดงข้อมูลที่ผ่านโดยตรงและสร้างใน SQL ตัวอย่างเช่น: สั่งซื้อโดย $ user_id $ หากค่าที่ส่งผ่านคือ 111 จากนั้นค่าเมื่อแยกวิเคราะห์ลงใน SQL เป็นคำสั่งซื้อโดย user_id หากค่าที่ส่งผ่านคือ ID การแยกวิเคราะห์เป็น SQL จะเป็นคำสั่งซื้อตาม ID
3. วิธี # สามารถป้องกันการฉีด SQL ได้อย่างมาก
4. วิธี $ ไม่สามารถป้องกันการฉีด SQL
5. โดยทั่วไปวิธี $ จะใช้ในการส่งผ่านในวัตถุฐานข้อมูลเช่นการส่งผ่านในชื่อตาราง
6. โดยทั่วไปถ้าคุณสามารถใช้ #อย่าใช้ $
เมื่อใช้คำสั่งซื้อโดยพารามิเตอร์แบบไดนามิกเมื่อเรียงลำดับ mybatis คุณต้องให้ความสนใจกับการใช้ $ แทน #
เปลี่ยนสตริง
โดยค่าเริ่มต้นการใช้ไวยากรณ์รูปแบบ #{} ทำให้ MyBatis สร้างคุณสมบัติคำสั่งที่ประมวลผลล่วงหน้าและตั้งค่าความปลอดภัยด้วยเป็นพื้นหลัง (เช่น?) สิ่งนี้ปลอดภัยและรวดเร็วและบางครั้งคุณก็ต้องการแทรกสตริงที่ไม่เปลี่ยนเป็นคำสั่ง SQL โดยตรง ตัวอย่างเช่นการสั่งซื้อโดยคุณสามารถใช้เช่นนี้:
สั่งซื้อโดย $ {columnName}
ที่นี่ mybatis จะไม่แก้ไขหรือหลบหนีสตริง
สำคัญ: ไม่ปลอดภัยที่จะรับเอาต์พุตเนื้อหาจากผู้ใช้และมอบให้กับสตริงที่ไม่เปลี่ยนแปลงในคำสั่ง สิ่งนี้สามารถนำไปสู่การโจมตีการฉีด SQL ที่มีศักยภาพดังนั้นคุณไม่ควรอนุญาตให้ผู้ใช้เข้าสู่ฟิลด์เหล่านี้หรือมักจะหลบหนีและตรวจสอบด้วยตัวเอง
คำอธิบายของ mybatis เอง:
สตริงการแทนที่โดยเริ่มต้นโดยใช้ไวยากรณ์ #{} จะทำให้ mybatis สร้างคุณสมบัติการเตรียมการและตั้งค่าอย่างปลอดภัยกับพารามิเตอร์ที่เตรียมไว้ (เช่น?) ในขณะที่สิ่งนี้ปลอดภัยกว่าเร็วขึ้นและเป็นที่ต้องการเกือบตลอดเวลาบางครั้งคุณแค่ต้องการฉีดสตริงที่ไม่ได้แก้ไขลงในคำสั่ง SQL โดยตรง ตัวอย่างเช่นสำหรับการสั่งซื้อโดยคุณอาจใช้สิ่งนี้: สั่งซื้อโดย $ {columnName} ที่นี่ mybatis จะไม่แก้ไขหรือหลบหนีสตริงหมายเหตุไม่ปลอดภัยที่จะรับอินพุตจากผู้ใช้และจัดหาให้กับคำสั่งที่ไม่ได้แก้ไขด้วยวิธีนี้ สิ่งนี้นำไปสู่การโจมตีการฉีด SQL ที่มีศักยภาพดังนั้นคุณควรไม่อนุญาตให้ผู้ใช้ป้อนข้อมูลในฟิลด์เหล่านี้หรือทำการหลบหนีและตรวจสอบของคุณเองเสมอ จากด้านบนเราจะเห็น:
1. ใช้ไวยากรณ์รูปแบบ #{} เพื่อใช้คำสั่งการเตรียมการใน myBatis เพื่อตั้งค่าอย่างปลอดภัยและดำเนินการ SQL คล้ายกับต่อไปนี้:
PreparedStatement ps = conn.preparestatement (SQL); ps.setint (1, id);
ประโยชน์ของสิ่งนี้คือ: ปลอดภัยกว่าเร็วขึ้นและมักจะเป็นแนวปฏิบัติที่ต้องการ
2. แต่บางครั้งคุณก็ต้องการแทรกสตริงที่ไม่เปลี่ยนแปลงลงในคำสั่ง SQL โดยตรง ตัวอย่างเช่นการสั่งซื้อโดยคุณสามารถใช้เช่นนี้:
สั่งซื้อโดย $ {columnName} ในเวลานี้ MyBatis จะไม่แก้ไขหรือหลบหนีสตริง
วิธีนี้คล้ายกับ:
คำสั่ง st = conn.createstatement (); Resultset rs = stexecuteQuery (SQL);
ข้อเสียของวิธีนี้คือ:
ไม่ปลอดภัยที่จะรับเอาต์พุตเนื้อหาจากผู้ใช้และให้สตริงที่ไม่เปลี่ยนแปลงในคำสั่งในลักษณะนี้ส่งผลให้เกิดการโจมตี SQL ฉีดที่อาจเกิดขึ้นดังนั้นผู้ใช้จึงไม่ได้รับอนุญาตให้เข้าสู่ฟิลด์เหล่านี้หรือหลบหนีและตรวจสอบด้วยตนเอง