动态 SQL - 搜索查询 - 可变数量的关键字
我们正在尝试更新我们的经典 asp 搜索引擎以保护它免受 SQL 注入。 我们有一个 VB 6 函数,它通过根据各种搜索参数将查询连接在一起来动态构建查询。 我们已将其转换为存储过程,对除关键字之外的所有参数使用动态 SQL。
关键字的问题在于用户提供的单词数量可变,我们希望为每个关键字搜索几列。 既然我们无法为每个关键字创建单独的参数,那么如何构建安全的查询呢?
示例:
@CustomerId AS INT
@Keywords AS NVARCHAR(MAX)
@sql = 'SELECT event_name FROM calendar WHERE customer_id = @CustomerId '
--(loop through each keyword passed in and concatenate)
@sql = @sql + 'AND (event_name LIKE ''%' + @Keywords + '%'' OR event_details LIKE ''%' + @Keywords + '%'')'
EXEC sp_executesql @sql N'@CustomerId INT, @CustomerId = @CustomerId
处理此问题并保持 SQL 注入保护的最佳方法是什么?
We are trying to update our classic asp search engine to protect it from SQL injection. We have a VB 6 function which builds a query dynamically by concatenating a query together based on the various search parameters. We have converted this to a stored procedure using dynamic sql for all parameters except for the keywords.
The problem with keywords is that there are a variable number words supplied by the user and we want to search several columns for each keyword. Since we cannot create a separate parameter for each keyword, how can we build a safe query?
Example:
@CustomerId AS INT
@Keywords AS NVARCHAR(MAX)
@sql = 'SELECT event_name FROM calendar WHERE customer_id = @CustomerId '
--(loop through each keyword passed in and concatenate)
@sql = @sql + 'AND (event_name LIKE ''%' + @Keywords + '%'' OR event_details LIKE ''%' + @Keywords + '%'')'
EXEC sp_executesql @sql N'@CustomerId INT, @CustomerId = @CustomerId
What is the best way to handle this and maintaining protection from SQL injection?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可能不喜欢听到这个,但在对数据库发出查询之前,最好返回到在代码中动态构建 SQL 查询。 如果您在 SQL 字符串中使用参数占位符,您将获得针对 SQL 注入攻击的保护。
示例:
您可以根据需要查询的列集构建 SQL 字符串,然后在字符串完成后添加参数值。 这样做有点痛苦,但我认为这比使用非常复杂的 TSQL 要容易得多,因为 TSQL 会取消许多可能输入的可能排列。
You may not like to hear this, but it might be better for you to go back to dynamically constructing your SQL query in code before issuing against the database. If you use parameter placeholders in the SQL string you get the protection against SQL injection attacks.
Example:
You can build the SQL string depending on the set of columns you need to query and then add the parameter values once the string is complete. This is a bit of a pain to do, but I think it is much easier than having really complicated TSQL which unpicks lots of possible permutations of possible inputs.
这里你有 3 个选择。
使用转换列表的函数并加入其中。 所以你会得到这样的东西。
<前><代码>选择 *
FROM 日历 c
JOIN dbo.fnListToTable(@Keywords) k
ON c.keyword = k.keyword
有一组固定的参数,并且最多只允许搜索N个关键字
在 TSQL 中编写转义字符串函数并转义您的关键字。
You have 3 options here.
Use a function that converts lists tables and join into it. So you will have something like this.
Have a fixed set of params, and only allow the maximum of N keywords to be searched on
Write an escaping string function in TSQL and escape your keywords.
除非您需要它,否则您可以简单地删除 [a-zA-Z ] 中不存在的任何字符 - 其中大多数内容不会出现在搜索中,并且您不应该能够以这种方式注入,也不应该这样做你必须担心关键字或类似的东西。 但是,如果您允许引号,则需要更加小心。
与 sambo99 的 #1 类似,您可以将关键字插入到临时表或表变量中并连接到它(甚至使用通配符),而没有注入的危险:
这并不是真正的动态:
您实际上可以生成具有大量参数的 SP,而不是手动编码(根据您在搜索编码中的偏好,将默认值设置为 '' 或 NULL)。 如果您发现需要更多参数,那么增加它生成的参数数量会很简单。
您可以将搜索移动到数据库外部的全文索引(例如 Lucene),然后使用 Lucene 结果拉取匹配的数据库行。
Unless you need it, you could simply strip out any character that's not in [a-zA-Z ] - most of those things won't be in searches and you should not be able to be injected that way, nor do you have to worry about keywords or anything like that. If you allow quotes, however, you will need to be more careful.
Similar to sambo99's #1, you can insert the keywords into a temporary table or table variable and join to it (even using wildcards) without danger of injection:
This isn't really dynamic:
You can actually generate an SP with a large number of parameters instead of coding it by hand (set the defaults to '' or NULL depending on your preference in coding your searches). If you found you needed more parameters, it would be simple to increase the number of parameters it generated.
You can move the search to a full-text index outside the database like Lucene and then use the Lucene results to pull the matching database rows.
你可以试试这个:
You can try this: