2012-08-06 12 views
8

Esta consulta funciona, pero es totalmente abierto a la inyección SQL:rieles ActiveRecord escapar variable en unirse a la cláusula

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

¿Cómo puedo escapar adecuadamente la variable cid? El parámetro conditions permite el formato ['foo = ?', bar] para este propósito, pero joins no.

No quiero usar find_by_sql porque entonces necesitaría agregar las uniones y condiciones que son parte del alcance predeterminado del modelo (que no sería SECO).

Editar: Mi estructura de la tabla es esencialmente esto:

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

Tenga en cuenta que esta es una base de datos de sólo lectura, que Rieles participación sólo se ha limitado a. No estoy planeando configurar modelos para todas las tablas; Solo quiero hacer una consulta simple como se describe arriba, sin exponerme a ataques de inyección SQL.

+1

¿Puedes describir la estructura de tu tabla? esto podría ser posible mediante el uso de condiciones de hash – davidrac

Respuesta

14

La respuesta que he encontrado es utilizar el método .sanitize en el modelo:

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) + ')', 
) 

Si encuentra una solución mejor, publicarlo!

+5

Lo logré de la misma manera: parece una deficiencia de ActiveRecord suponer que no se desean agregar condiciones a la unión, ¡y hacerlo de manera segura! – DaveStephens

+0

¿por qué no podemos usar la funcionalidad P.cid = cid en una cláusula where? – Ari53nN3o

+0

@parallelRails Si conoce una forma de reescribir la consulta anterior usando 'where' en lugar de' left join', y obtenga resultados idénticos, ¡por favor publíquelo como una respuesta! –

2

Esto parece ser más de lo que intentabas hacer.

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 
    ] 
Cuestiones relacionadas