Soy un desarrollador junior y solo estoy trabajando para resolver una instancia de inyección ciega de sql que se me indicó en uno de mis proyectos.
Para empezar, aquí está mi código, luego lo explicaré un poco mejor.
for (const room of query.rooms) { roomQuery.push(`rooms.name = '${room}'`) } for (const category in categories) { categoryQuery.push(`categories.name = '${categories[category].name}'`) } let productsRoomAndCategories = (await db.query(`SELECT products.* FROM products WHERE products.room_id IN (SELECT DISTINCT rooms.id FROM rooms WHERE ${roomQuery.join(' OR ')}) AND products.category_id IN (SELECT DISTINCT categories.id FROM categories WHERE ${categoryQuery.join(' OR ')}) ORDER BY products.price`, )).rowsBásicamente, un usuario selecciona una lista de categorías y habitaciones que está buscando, se publica en el backend y luego le consulto para encontrar productos que coincidan con lo que está buscando.
Desafortunadamente, como un niño inocente, olvidé que simplemente puede editar encabezados, y no siempre obtendré lo que espero enviado al backend, y actualmente estoy sujeto a ataques ciegos de sql.
por lo que roomsQuery puede parecerse a:
[ 'rooms.name = \'common area\'', 'rooms.name = \'kitchen\'', 'rooms.name = \'bathroom\'', 'rooms.name = \'bedroom\'', 'rooms.name = \'laundryroom\'', 'rooms.name = \'entryway\'' ]y categoryQuery puede parecerse a:
[ 'categories.name = \'speakers\'', 'categories.name = \'hubs\'', 'categories.name = \'vaccumes\'', 'categories.name = \'refrigerators\'', 'categories.name = \'stoves\'', 'categories.name = \'dishwashers\'', 'categories.name = \'washers\'', 'categories.name = \'dryers\'', 'categories.name = \'coffee makers\'', 'categories.name = \'televisions\'', 'categories.name = \'thermostats\'', 'categories.name = \'yard cameras\'', 'categories.name = \'interior camears\'', 'categories.name = \'door locks\'', 'categories.name = \'door bells\'' ]Estoy usando NodeJS y PSQL para esto. Todo lo que he visto habla de implementar consultas parametrizadas, pero no sé cómo hacerlo en este sentido, el problema es que no quiero que el nombre de las habitaciones esté entre comillas, de lo contrario, la consulta fallará. Cualquier consejo es apreciado gracias :)
Puede usar el operador in lugar de una gran cadena de or .
where rooms.name in ('foo', 'bar')
Esto al menos evita tener que compilar SQL, pero debe colocar cada valor por separado y saber cuántos valores tendrá: where rooms.name in ($1, $2) .
En su lugar, use el operador any que toma una matriz de Postgres .
where rooms.name = any('{foo,bar}') .
Esto necesita solo un parámetro: where rooms.name = any($1) . Proporcionaría su consulta con una serie de nombres de habitaciones. node-postgres debería convertir esto en una matriz de Postgres.
category_names = [] for (const category in categories) { category_names.push(categories[category].name) } sql = ` SELECT products.* FROM products WHERE products.room_id IN ( SELECT DISTINCT rooms.id FROM rooms WHERE rooms.name = any($1) ) AND products.category_id IN ( SELECT DISTINCT categories.id FROM categories WHERE categories.name = any($2) ) ORDER BY products.price ` let productsRoomAndCategories = ( await db.query(sql, [query.rooms, category_names]) ).rowsAlgo como eso.
Tenga en cuenta que esto probablemente se puede hacer mejor con una combinación .
select products.* from products join rooms on products.room_id = rooms.id join categories on products.category_id = categories.id where rooms.name = any($1) and categories.name = any($2) order by products.price