2016-11-19 27 views
2

我最初發現這是一個問題,當我試圖搜索前綴爲hashtag的術語時,結果證明它是SQL中的註釋分隔符。搜索沒有返回任何內容,因爲它忽略了標籤後面出現的#term。如何編寫參數化的sql查詢以防止SQL注入?

所以現在我很難找到逃避用戶輸入的正確方法。在我看來,這將解決hashtag問題,並解決更大的問題,SQL注入。

這裏是我與具體工作的片段:

function (term) { 
    term = term.toLowerCase() 
    return db('ticket') 
    .select('*') 
    .where(db.raw('lower(question)'), 'like', `%${term}%`) 
    .orWhere(db.raw('lower(note)'), 'like', `%${term}%`) 
    .orWhere(db.raw('lower(user_name)'), 'like', `%${term}%`) 
} 

我發現thisthis SO文章,似乎接近,以及其他幾件事情。此外,Knex的文檔和其他資源建議將參數化綁定作爲防範SQL注入的一種方法。

我只是無法找到一個清晰的例子,可以通過JavaScript或使用Knex向我解釋。

+0

您的數據庫整理是否區分大小寫?您不需要在'LIKE'運算符中使用'LOWER' - 這也意味着您的查詢將運行得非常緩慢,因爲它不能使用索引。 – Dai

+0

IMO。 「SQL注入」就像「問題2000」:很多噪音,但沒有嚴重。有兩條簡單規則可以避免任何「SQL注入」:1)在前端/中端使用參數化查詢和2)在DB對象上設置適當的DB級安全性。 – Abelisto

+0

感謝您的回覆。 @Dai我嘗試了你的建議,但似乎區分大小寫。我對db land比較陌生,你能推薦一些資源來學習使用你提到的索引和排序規則嗎?從未聽過這些條款。 –

回答

6

我不是Knex.js用戶,但在看文檔時,似乎Knex使用JavaScript對象語法來定義謂詞是它如何實現參數化。

但是,當您使用內置函數時,您需要使用whereRaw

望着文檔(http://knexjs.org/#Builder-whereRaw)和(http://knexjs.org/#Raw-Bindings)我想你想這樣做:

.whereRaw('question LIKE :term OR note LIKE :term OR user_name LIKE :term', { term: '%' + term + '%' ] }) 

Knex不具有​​,所以你如果要在邏輯上應使用手寫版分開謂詞:

term = '%' + term + '%'; 

.orWhere(knex.raw('question LIKE ?', [ term ])) 
.orWhere(knex.raw('note  LIKE ?', [ term ])) 
.orWhere(knex.raw('user_name LIKE ?', [ term ])) 

?是位置參數,並:term是命名參數。

+0

感謝您的回覆。是的,你提出的這兩種選擇都很完美。即使如此,我覺得我錯過了他們與我已經做的根本不同的地方。我在我的orWhere裏有一個用%裝飾的模板字符串。將術語設置爲第一個示例中的對象還是第二個中的數組實現了參數化綁定?編輯:還應該指出,我仍然無法從數據庫中檢索hashtags,儘管我可以插入它們。 –

1

看來,你真的需要擔心sql注入的唯一時間是如果你使用knex.raw()或任何其他純粹的sql命令。換句話說,Knex會自動爲您輸入輸入內容。

至於標籤問題,在搞亂PG指揮官之後,我發現我可以搜索#就好了。在將它們發送到我的後端之前,我只需要對它們進行網址編碼......有點令人尷尬,但我今天學到了一些新東西。