flawopen.com/Java में SQL Injection/MyBatis
MyBatis ${} बनाम #{}: SQL Injection से बचाव
#{value} को prepared statement के सुरक्षित value slot की तरह समझें: database इसे data मानता है। ${value} तैयारी से पहले SQL में text जोड़ता है।
Bound values बनाम raw SQL text
<select id="getUser">
SELECT * FROM users
WHERE id = ${id}
</select>
// Raw substitution: the SQL text changes
<select id="getUser">
SELECT * FROM users
WHERE id = #{id}
</select>
// MyBatis creates a PreparedStatement parameter
MyBatis में दोनों syntaxes क्यों हैं
#{} JDBC PreparedStatement parameter से मान bind करता है। Parameter table, column या sort direction जैसी SQL syntax नहीं बन सकता। ${} text सीधे बदलता है और escape नहीं करता। Static statements या <choose> branches चुनें; अन्यथा पूरा identifier server allowlist से लें, arbitrary request text न जोड़ें।
जब dynamic identifiers जरूरी हों
Bound parameter identifier की जगह नहीं लेता। Sorting choice को server के fixed SQL fragments से map करें या <choose> लें। Client का column, table या ASC/DESC सीधे ${} में न दें। Escaping arbitrary SQL को सुरक्षित नहीं बनाता।
MyBatis mapper की जाँच
rg -n -F '${' --glob '*.xml' --glob '*.java' .अक्सर पूछे जाने वाले प्रश्न
हाँ। वही नियम हैं। @Select में ${column} raw text जोड़ता है; मान #{value} से bind करें और identifier allowlist करें।
नहीं। परिणामों की समीक्षा करें; SQL दूसरी जगह बन सकता है। XML और annotations जाँचें और test करें कि sorting केवल तय fragments चुने।