看了網上文章,說的都挺好的,給cursor.execute傳遞格式串和參數,就能防止注入,但是我寫了代碼,卻死活跑不通,懷疑自己用了一個假的python
最后,發現原因可能是不同的數據庫,對於字符串的占位定義不同,這段話:
Note that the placeholder syntax depends on the database you are using 'qmark' Question mark style, e.g. '...WHERE name=?' 'numeric' Numeric, positional style, e.g. '...WHERE name=:1' 'named' Named style, e.g. '...WHERE name=:name' 'format' ANSI C printf format codes, e.g. '...WHERE name=%s' 'pyformat' Python extended format codes, e.g. '...WHERE name=%(name)s'
我理解,就是有多種占位方式,而我一棵樹上吊死,光試驗%s了,所以每次都報這個錯:
rs=c.execute("select * from log where f_UserName=%s","jetz")
OperationalError: near "%": syntax error
換一個試試,
rs=c.execute("select * from log where f_UserName=:usr",{"usr":"jetz"})
可以
再試:
rs=c.execute("select * from log where f_UserName=:1 ",["jetz"])
也可以
看了sqlite對%比較過敏
對於sql注入的測試效果。
1)用構造串的方式,傳遞用戶名
getData("select * from log where f_UserName='%s'"%("jetz"))
如果傳遞的是測試表名存在的串,可以執行
getData("select * from log where f_UserName='%s'"%("jetz' And (Select count(*) from user)<>0 and '1'='1"))
但是,如果改用參數方式,則不能執行
getData("select * from log where f_UserName=:1","jetz' And (Select count(*) from user)<>0 and '1'='1")
這種近乎“原生”的防止注入手段,比對傳入參數進行檢測來說,實在好太多了。