2017-01-25 26 views
2

我希望用戶能夠選擇顯示結果的順序,例如按年齡),並且我不想在從數據庫中獲得它們之後對它們進行分類。我該如何參數化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() 
+0

順便說一句,我只是用SQLI與該輸入嘗試''年齡; DROP TABLE測試;''到第三個SQL命令和pysqlite引發一個異常說'sqlite3.Warning:你一次只能執行一個語句.',所以也許我不應該擔心?在我看來,使用字符串格式仍然很危險,但... – Grezzo

+0

用戶是否可以以任何方式影響字符串的實際內容? (在這個問題中,你使用了'age'這個常量字符串,這是沒有道理的。) –

+0

它來自http請求。如果他們使用正確的客戶端(網頁),它應該是6列名稱中的任何一個,但如果有人決定是惡意的,它可能是他們選擇的任何東西。 – Grezzo

回答

3

SQL參數僅用於值;其他任何內容都可能會改變查詢的含義。 (例如,ORDER BY password可以離開的暗示,如能ORDER BY (SELECT ... FROM OtherTable ...)。)

爲了確保來自客戶端的列名是有效的,你可以使用白名單:

if order_by not in ['name', 'age']: 
    raise ... 
execute('... ORDER BY {}'.format(order_by)) 

但它仍然是一個壞主意將該字符串集成到查詢中,因爲驗證和實際表可能不同步,或者您可能會忘記檢查。從客戶更好的回報列索引,讓您使用的實際字符串始終是你自己的,任何錯誤可以正常在測試過程中很容易被發現:

order_by = ['name', 'age'][order_index] 
execute('... ORDER BY {}'.format(order_by)) 
+0

使用常數給出'order_index'名稱的值(如'NAME_COLUMN = 0')。這樣,您可以輕鬆添加更多列或移動它們,並可以查看您想要的訂購類型。 –

+0

還要注意,通過給它們自己的索引,你可以很容易地創建更復雜的排序,比如'name ASC,age DESC'。 –

+0

很好的答案,特別是按列排序的示例可以提供密碼提示。謝謝。然後是白名單。 – Grezzo

相關問題