我希望用戶能夠選擇顯示結果的順序,例如按年齡),並且我不想在從數據庫中獲得它們之後對它們進行分類。我該如何參數化pysqlite中的列名以避免SQL注入
顯然,如果用戶能夠指定影響SQL命令的輸入,那麼需要對它進行消毒處理,而且我通常會使用參數化,但pysqlite似乎忽略除參數以外的任何參數。
示例代碼如下顯示參數化不適用於ORDER BY
,也是一種使用字符串格式化的解決方法,但容易受SQL注入影響。
什麼是推薦的解決方案,允許用戶輸入影響排序順序而不暴露SQLi漏洞?我必須使用字符串格式並手動檢查每個用戶輸入嗎?
#!/user/bin/env python3
import sqlite3
con = sqlite3.connect(':memory:')
cur = con.cursor()
cur.execute('CREATE TABLE test (name, age)')
cur.execute('INSERT INTO test VALUES (:name, :age)', {'name': 'Aaron', 'age': 75})
cur.execute('INSERT INTO test VALUES (:name, :age)', {'name': 'Zebedee', 'age': 5})
cur.execute('SELECT * FROM test ORDER BY age ASC')
results = cur.fetchall()
print('\nGood, but hard coded:\n', results)
# Good, but hard coded:
# [('Zebedee', 5), ('Aaron', 75)]
cur.execute('SELECT * FROM test ORDER BY :order_by ASC', {'order_by': 'age'})
results = cur.fetchall()
print('\norder_by parameter ignored:\n', results)
# order_by parameter ignored:
# [('Aaron', 75), ('Zebedee', 5)]
cur.execute('SELECT * FROM test ORDER BY {order_by} ASC'.format(order_by='age'))
results = cur.fetchall()
print('\nRight order, but vulnerable to SQL injection:\n', results)
# Right order, but vulnerable to SQL injection:
# [('Zebedee', 5), ('Aaron', 75)]
con.close()
順便說一句,我只是用SQLI與該輸入嘗試''年齡; DROP TABLE測試;''到第三個SQL命令和pysqlite引發一個異常說'sqlite3.Warning:你一次只能執行一個語句.',所以也許我不應該擔心?在我看來,使用字符串格式仍然很危險,但... – Grezzo
用戶是否可以以任何方式影響字符串的實際內容? (在這個問題中,你使用了'age'這個常量字符串,這是沒有道理的。) –
它來自http請求。如果他們使用正確的客戶端(網頁),它應該是6列名稱中的任何一個,但如果有人決定是惡意的,它可能是他們選擇的任何東西。 – Grezzo