我是一名初级开发人员,正在解决一个在我的一个项目中向我指出的盲sql注入实例。
对于初学者来说,这是我的代码,稍后我会更好地解释。
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`,
)).rows
因此,本质上,用户选择他们正在寻找的类别和房间的列表,并将其发布到后端,然后我查询他们,以找到与他们正在寻找相匹配的产品。
不幸的是,就像一个无辜的孩子一样,我忘记了你可以简单地编辑标题,我不会总是得到我期望的发送到后端的东西,并且目前受到了盲目的sql攻击。
所以roomsQuery可能看起来像:
[ 'rooms.name = 'common area'',
'rooms.name = 'kitchen'',
'rooms.name = 'bathroom'',
'rooms.name = 'bedroom'',
'rooms.name = 'laundryroom'',
'rooms.name = 'entryway'' ]
和categoryQuery可能看起来像:
[ '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'' ]
为此,我使用NodeJS和PSQL。我所看到的一切都在谈论实现参数化查询,但我不知道如何从这个意义上做到这一点,问题是,我不希望rooms.name用引号括起来,否则查询就会失败。如有任何建议,不胜感激。谢谢:)
您可以使用in
运算符,而不是or
的大链。
where rooms.name in ('foo', 'bar')
这至少避免了构建SQL,但您需要将每个值分别放入,并知道您将有多少个值:where rooms.name in ($1, $2)
。
相反,使用any
运算符,它接受Postgres数组。
where rooms.name = any('{foo,bar}')
。
这只需要一个参数:where rooms.name = any($1)
。您可以为查询提供一组房间名称。nodepostgres应该将其转换为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])
).rows
类似的东西。
请注意,使用联接可能会做得更好。
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