在大型asp.net C#Web应用程序中修复SQL注入表单

时间:2011-07-04 12:14:02

标签: c# asp.net sql-injection parameterized-query

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

项目中每个页面中的所有表单都不使用参数化查询,而只使用字符串查询。

对于示例,我有搜索页面,查看背后的代码,我看到有一个方法CreateQuery()根据文本字段创建查询,例如:

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

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

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

我的问题是:

由于我有数百个表单和数千个formText以及FIX的值,是否有一个“快速”解决方案可以实现,如

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

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

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

  5. 5-(编辑)这是一个可能的解决方案,还是只是不改变任何东西?

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

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

    建议?

    提前致谢。

6 个答案:

答案 0 :(得分:4)

你已经知道有问题; IMO,这里的任何“快速”修复都可能减少攻击面,但不太可能阻止确定的滥用行为;简单地说,黑名单真的很难,并且有一些 非常奇怪的 输入可以在黑帽(以及样本,白帽)网站上随时可用。这些总是容易被识别为滥用。这不是全部' drop table Customers --; p

无论你做什么,我都会建议你做得好;参数。像dapper这样的工具可能会减少您需要的代码,但是:

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

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

答案 1 :(得分:1)

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

需要时间,但想想那个将为“大型网络应用程序”维护和添加功能的人 (可能是你)。

答案 2 :(得分:1)

<customErrors mode="On"/> 

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

答案 3 :(得分:1)

平原道

通过搜索项目string sQuery = "来估算替换次数。将您计划用于修复单个查询的时间乘以它(例如,5分钟内的一次修复,以及每10次修复的咖啡休息)。

为测试整个网站增加时间。

然后告诉管理层,解决方案将是巨大的,给他们估计,就这样做
当然,你会有几天的头痛,但至少你会有事情发生。

创意方式

如果字面意思意味着成百上千的此类表单具有几乎相同的代码(例如,查询始终在CreateQuery中创建,在SubmitButton_Click中执行),我会考虑learning to use Visual Studio regular expression语法并制作一些非常准确的搜索&amp;替换模式。

这节省了我在一个项目中工作的时间,但你需要非常准确地使用regexp并确保你理解你正在做的事情。

另一个选择,当你确定它值得时,就是编写一个可以重写C#源的工具。
如果您只需要simple transform like the one Marc mentioned,则可能需要几个小时的工作 但你可能会在这里悲惨地失败,所以这是一条冒险的路线。

答案 4 :(得分:1)

  1. 降低应用程序用于访问数据的数据库帐户的权限。希望它没有sysadmin。删除删除表的权限。如果该帐户仅用于数据检索,请删除更新数据的所有权限。您甚至可以考虑设置视图,将其锁定,然后使用它们而不是直接表访问。

  2. 启用ASP.NET请求验证,描述为here。这会自动检查所有流量是否存在恶意字符序列。

  3. 如果可能,请考虑向Global for OnBeginRequest添加一个事件处理程序,用于检查传入数据并对所有输入执行白名单检查。不确定这是如何映射到你的问题,但好的是你只需要在一个地方做它,它会影响整个网站。

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

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

答案 5 :(得分:-1)

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