5

我必须修复一个容易受到 SQL 注入攻击的项目。

项目中每一页的所有表单都没有使用参数化查询,而是简单的字符串查询。

例如,我有搜索页面,查看后面的代码,我发现有一种方法可以基于文本字段创建查询,例如CreateQuery()

string sQuery = "";
sQuery += "b.name like '%" + txtName.Text + "%'";

然后在btnSearch_Click()我有执行查询的方法:

query = CreateQuery();
var totalList = GetAllBlaBla(query);

我的问题是:

由于我有数百个表格和数千个formTextFIX 值,是否有一个“快速”的解决方案来实现,例如

  1. 以某种方式参数化查询或处理情况的全局函数?
  2. 由于在每个类中查询都是在SubmitButton_Click()方法后面的代码中执行的,我可以在这里处理这种情况,当然是在每个类中吗?
  3. 我是否应该修改表单代码隐藏中的每个表单和每个条目以参数化 SQL 字符串,这将需要一百万年?
  4. (编辑)编码/解码输入值呢?所以上面的例子将是:

    string sQuery = "";
    var txt = var txt = HttpUtility.HtmlEncode(txtName.Text);
    sQuery += "b.name like '%" + txt + "%'";
    

    这是一个可能的临时补丁吗?

5-(编辑)这是一个可能的解决方案,还是根本没有改变任何东西?

        cmd.Parameters.Add("@txtNameParameter", SqlDbType.VarChar);
        cmd.Parameters["@txtNameParameter"].Value = txtName.Text;
        sQuery += "b.name like '%" + (string)cmd.Parameters["@txtNameParameter"].Value + "%'";

问题是我必须返回一个字符串,因为处理查询的逻辑是在另一个将字符串作为查询的业务类中定义的,我不能给它一个 CommandType 或 SqlDataAdapter ...

建议?

提前致谢。

4

6 回答 6

4

你已经知道有问题了;IMO,这里的任何“快速”修复都可能减少攻击面,但不太可能防止确定的滥用;简而言之,列入黑名单确实很难,而且在黑帽(以及作为示例,在白帽)网站上很容易获得一些非常奇怪的输入。这些并不总是很容易被识别为滥用。这还不是全部' drop table Customers --;p

无论您做什么,我都建议您正确地做;参数。不过,像dapper这样的工具可能会减少您需要的代码:

sQuery += "b.name like '%'+@text+'%'"
...
conn.Execute(sQuery, new {text=txtName.Text});

(这比手动处理所有参数等更容易)

于 2011-07-04T12:23:18.113 回答
1

修改每个查询 + 验证每个输入。

需要时间,但请考虑将维护该“大型 Web 应用程序”并为其添加功能的人(可能是您)。

于 2011-07-04T12:22:17.917 回答
1
<customErrors mode="On"/> 

这将阻止用户看到错误,因此潜在的黑客将很少有线索如何利用此安全门,基于他/她看到的错误消息
添加 Elmah 以记录错误。
重写每个查询以使用参数或使用 ORM。
任何基于 javascript 的解决方案都是无用的,因为“黑客”肯定知道如何禁用它。

于 2011-07-04T12:29:02.150 回答
1

朴素的方式

通过在项目中搜索 来估计替换的数量string sQuery = "。将它乘以您计划花费在修复单个查询上的时间(例如,在 5 分钟内修复一次,加上每 10 次修复的茶歇时间)。

添加时间来测试整个网站。

然后告诉管理层修复将是巨大的,给他们估计然后去做
你肯定会头疼几天,但至少你会让事情正常工作。

创意之道

如果您的字面意思是成百上千个具有几乎相同代码的此类表单(例如,查询总是在 中创建,在 中CreateQuery执行SubmitButton_Click),我会考虑学习使用 Visual Studio 正则表达式语法并制作几个非常准确的搜索和替换模式。

这节省了我在一个项目中的工作时间,但是您需要非常精确地使用正则表达式并确保您了解自己在做什么。

同样,当您确定值得时,另一种选择是编写一个可以重写 C# 源代码的工具。
如果您只需要像 Marc 提到的那样进行简单的转换,则可能需要几个小时的工作。
但是你可能会在这里惨遭失败,所以这是一条危险的路线。

于 2011-07-04T12:33:52.030 回答
1
  1. 减少应用程序用于访问数据的数据库帐户的权限。希望它没有系统管理员。删除删除表的权限。如果该帐户仅用于数据检索,请删除所有更新数据的权限。您甚至可以考虑设置视图、锁定它们并使用它们而不是直接访问表。

  2. 打开此处描​​述的 ASP.NET 请求验证。这会自动检查所有流量是否存在恶意字符序列。

  3. 如果可能,请考虑为 OnBeginRequest 向 Global 添加一个事件处理程序,以检查传入数据并对所有输入执行白名单检查。不确定这对您的问题的映射程度,但好处是您只需在一次地方执行此操作,它将影响整个站点。

  4. 确保所有页面都调用 Page.Validate 以确保客户端验证也在服务器端强制执行。

  5. 开始为每个控件添加特定于字段的白名单验证的长期艰苦工作,并制定一个长期计划以转移到参数化数据库调用。

于 2013-10-09T16:52:28.490 回答
-1

在页面加载期间查找每个页面上的所有文本框控件并禁用特殊按键处理

于 2011-07-04T12:27:17.603 回答