4

我们正在尝试更新我们的经典 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 注入保护的最佳方法是什么?

4

4 回答 4

3

您可能不喜欢听到这个,但在针对数据库发出之前,您最好返回到在代码中动态构建 SQL 查询。如果您在 SQL 字符串中使用参数占位符,您将获得针对 SQL 注入攻击的保护。

例子:

string sql  = "SELECT Name, Title FROM Staff WHERE UserName=@UserId";
using (SqlCommand cmd = new SqlCommand(sql))
{
  cmd.Parameters.Add("@UserId", SqlType.VarChar).Value = "smithj";

您可以根据需要查询的列集构建 SQL 字符串,然后在字符串完成后添加参数值。这样做有点痛苦,但我认为这比使用真正复杂的 TSQL 要容易得多,因为 TSQL 会取消选择可能输入的许多可能排列。

于 2008-09-30T22:12:20.570 回答
1

这里有 3 个选项。

  1. 使用转换列表表并加入其中的函数。所以你会有这样的东西。

    SELECT * 
    FROM calendar c
       JOIN dbo.fnListToTable(@Keywords) k 
           ON c.keyword = k.keyword  
    
  2. 有一组固定的参数,并且只允许搜索最多 N 个关键字

    CREATE PROC spTest
    @Keyword1 varchar(100),
    @Keyword2 varchar(100),
    .... 
    
  3. 在 TSQL 中编写转义字符串函数并转义关键字。

于 2008-09-30T22:22:58.860 回答
0
  • 除非你需要它,否则你可以简单地删除任何不在 [a-zA-Z] 中的字符 - 大多数这些东西不会在搜索中,你不应该以这种方式被注入,你也不必担心关键字或类似的东西。但是,如果您允许引用,则需要更加小心。

  • 与 sambo99 的 #1 类似,您可以将关键字插入到临时表或表变量中并加入它(甚至使用通配符),而不会存在注入的危险:

这不是真正的动态:

SELECT DISTINCT event_name
FROM calendar
INNER JOIN #keywords
    ON event_name LIKE '%' + #keywords.keyword + '%'
    OR event_description LIKE '%' + #keywords.keyword + '%'
  • 您实际上可以生成具有大量参数的 SP,而不是手动对其进行编码(根据您对搜索编码的偏好,将默认值设置为 '' 或 NULL)。如果您发现需要更多参数,那么增加它生成的参数数量会很简单。

  • 您可以将搜索移至数据库外部的全文索引(如 Lucene),然后使用 Lucene 结果提取匹配的数据库行。

于 2008-10-01T05:13:49.340 回答
0

你可以试试这个:

SELECT * FROM [tablename] WHERE LIKE % +keyword%
于 2010-10-17T23:02:07.610 回答