如何在搜索数组时修复盲目 SQL 注入,该注入可能会根据用户输入而改变
Posted
技术标签:
【中文标题】如何在搜索数组时修复盲目 SQL 注入,该注入可能会根据用户输入而改变【英文标题】:How can I fix a blind SQL injection, when searching for an array, that can change depending on a users input 【发布时间】:2021-11-13 04:08:35 【问题描述】:我是一名初级开发人员,正在解决我的一个项目中向我指出的盲目 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。我所看到的一切都在谈论实现参数化查询,但我不知道如何在这个意义上做到这一点,问题是,我不希望 room.name 用引号引起来,否则查询将失败。感谢您的任何建议谢谢:)
【问题讨论】:
ORDER BY products.price``,
真的应该使用参数化查询。
所以我在我的程序中对所有其他内容使用参数化查询,只是不知道如何在这里使用它这就是问题的重点:p,是的,对不起,逗号是我玩的使用参数化查询
【参考方案1】:
您可以使用in
operator 代替or
的大链。
where rooms.name in ('foo', 'bar')
这至少避免了构建 SQL,但您需要将每个值分别放入并知道您将拥有多少个值:where rooms.name in ($1, $2)
。
改为使用any
运算符,该运算符采用Postgres array。
where rooms.name = any('foo,bar')
.
这只需要一个参数:where rooms.name = any($1)
。您将为查询提供一组房间名称。 node-postgres 应该将其转换为 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
类似的东西。
请注意,使用join 可能会做得更好。
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
【讨论】:
以上是关于如何在搜索数组时修复盲目 SQL 注入,该注入可能会根据用户输入而改变的主要内容,如果未能解决你的问题,请参考以下文章
安全测试 web安全测试 常规安全漏洞 可能存在SQL和JS注入漏洞场景分析。为什么自己没有找到漏洞,哪么可能存在漏洞场景是?SQL注入漏洞修复 JS注入漏洞修复 漏洞存在场景分析和修复示例(代码片段