如何在搜索数组时修复盲目 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注入漏洞修复 漏洞存在场景分析和修复示例(代码片段

sql注入漏洞如何修复

sql注入漏洞如何修复

如何修复SQL注入漏洞

sql注入漏洞如何修复

从搜索表单动态构建 WHERE 子句时如何防止 SQL 注入?