为SQL生成安全更新语句

时间:2014-08-25 14:53:28

标签: c# sql-server ado.net

我可能在这里遗漏了一些东西,但我搜索了几个小时,我要么找不到我需要的东西,要么就是我没有按照正确的条件搜索。从来没有,这就是我想要做的。

我正在探索从EF迁移到普通的ADO。我很高兴虽然这样做有所发展,但ADO的所有当前测试点仍然比EF快许多倍(因为EF建立在ADO上是有意义的)。

我有点难过,正在为表行生成更新语句,并且是一个有效的表。任何更新语句都可能会更改1或10个字段中的值,但仅发布需要更改的数据显然更有效。

我的问题是,生成更新语句以保持免受SQL注入的最佳方法是什么?

例如,一个列值更新将是

update Table1 set Column2 = 'somevalue' WHERE Column1 = @id;

两列是

update Table1 set Column2 = 'somevalue', Column 3 = 'some other value' WHERE Column1 = @id;

有没有人对他们如何处理这个问题有任何最佳做法?

其他信息:

我已经对此进行了投票,但老实说,我认为这是因为我没有明确表达自己想要的内容。

让我开始确认我理解我可以选择直接的SQL命令(我非常称职)或将所述命令放在存储过程中并从ADO调用。我还完全理解在放置用户输入的任何SQL语句中使用参数的重要性。

想象一下下表:

DECLARE @example TABLE
(
Id INT IDENTITY NOT NULL,
Name VARCHAR(50) NOT NULL,
Description VARCHAR(1000) NOT NULL
);
-- Indexes omitted for simplicity

现在假设我有一个API,允许用户更新此表中的一行。只需传递Id,用户就可以更新Name,Description或两列。该调用与任何“结果集”完全断开,因此我必须手动(或通过存储过程)向数据库发出UPDATE命令。

为了将数据传输保持在最低限度(因此有助于最大限度地提高性能),我希望能够满足以下情况:

  • 用户更新名称

    UPDATE @example SET [Name] = @name WHERE [Id] = @id;
    
  • 用户更新仅描述

    UPDATE @example SET [Description] = @description WHERE [Id] = @id;
    
  • 用户更新

    UPDATE @example SET [Name] = @name, [Description] = @description WHERE [Id] = @id;
    

毕竟,每次通话,我都不知道来电者希望更新什么。

实际上,表可以包含许多列,并且为每种可能的组合创建相关的SQL语句是完全荒谬的 - 更不用说保持更新所需的荒谬努力。

我正在寻找(因为我似乎在搜索中缺少)是如何生成一个安全的SQL语句,根据用户提供的内容和使用参数来满足每个选项并生成可能的最小查询 - 需要因为如果用户没有为其传递值,我们无法更新列值。

我希望这有助于更好地澄清要求。

1 个答案:

答案 0 :(得分:1)

在所有情况下参数化所有值。这将确保您避免SQL注入攻击。至于跟踪哪些字段已经改变并因此需要更新的模式,这是一个更大的练习,在互联网上提供了许多示例供您阅读享受。

update Table1
set Column2 = @Column2,
  Column3 = @Column3
where Column1 = @Column1