2012-08-06 21 views
8

這個查詢工作,但就是SQL注入完全開放:Rails的ActiveRecord的逃避變量中加入條款

products = Product.find(pids, 
    :select => 'products.*, P.code', 
    :joins => "left join product_dist_match P on 
    (P.pid = products.pid and P.cid = #{cid})", 
) 

我怎樣才能正確地逃脫CID變量? conditions參數允許用於此目的的格式['foo = ?', bar],但joins不允許。

我不想使用find_by_sql,因爲那時我需要添加屬於模型默認範圍(不會幹的)的部分的連接和條件。

編輯:我的表結構基本上是這樣的:

products: pid (primary key) 
product_dist_match: pid, cid, code 
customers (not used in the query): cid (primary key) 

注意,這是一個只讀數據庫,導軌和只有有限參與。我不打算爲所有表格建立模型;我只想做一個如上所述的簡單查詢,而不會將自己暴露給SQL注入攻擊。

+1

你能描述一下你的表結構嗎?這可能是通過使用哈希條件 – davidrac 2012-08-06 16:00:26

回答

14

我找到了答案是使用.sanitize方法型號:

products = Product.find(pids, 
    :select => 'products.*, P.code', 
    :joins => 'left join product_dist_match P on 
    (P.pid = products.pid and P.cid = ' + Product.sanitize(cid) + ')', 
) 

如果你找到一個更好的解決方案,請發表吧!

+5

我以同樣的方式實現了這一點 - 看起來ActiveRecord的一個缺點是假設一個人不想在連接中添加條件,並以安全的方式這樣做! – DaveStephens 2012-08-27 23:44:42

+0

爲什麼我們不能在where子句中使用P.cid = cid功能? – Ari53nN3o 2013-08-05 14:40:08

+0

@parallelRails如果您知道使用'where'而不是'left join'重寫上述查詢的方法,並獲得相同的結果,請將其作爲答案發布! – 2013-08-06 16:58:28

2

這似乎是你想要做的更多。

products = Product.find(pids, 
    :select => 'products.*, P.code', 
    :joins => sanitize_sql_array [ 
     'left join product_dist_match P on P.pid = products.pid and P.cid = ?', 
     cid 
    ]