2012/06/11

MySQL 如何避免 SQL injection

遇到這個問題,大部分的人應該會說:用 ORM (Object-relational mapping) 呀!但我就沒有打算多學一套 >< 一方面也是不清楚它欄位的屬性、資料形態是否完全支援 mysql,加上我執行的 query 也蠻複雜的。

先前有找了幾套:
  • SQLAlchemy - 大家比較推薦的
  • Quick ORM - fully compatible with the newest SQLAlchemy

ORM 的好處是你只要設定一次 mapping,之後 select、update、insert 都很方便,但我實在是沒有必要為了一個 injection protect 就用了這麼強大的東西。


除了 ORM 以外...
Search 了一下發現 MySQLdb 本身就有支援以參數的方式來執行 query:
cursor.execute('SELECT * FROM `user` WHERE user=%s AND password=%s;', usr, pwd)
所有的參數都會根據其資料型態來取代 format string,特殊字元自然就會被跳脫了。

要注意的是 statement 內的引號 " 要去掉,format string 通通使用 %s,像下面兩個語法就會有問題:
cursor.execute('SELECT * FROM `user` WHERE username="%s";', username)
cursor.execute('SELECT * FROM `user` WHERE id=%d;', my_id)

另外,也不要把 format string 串起來才傳過去,這樣就會真的發生 SQL injection了:
cursor.execute('SELECT * FROM `user` WHERE user=%s AND password=%s;' % (usr, pwd))

至於其他的 database 可以找看看有沒有 prepared statement 可以使用。


參考資料


沒有留言:

張貼留言