代码之家  ›  专栏  ›  技术社区  ›  Tony_Henrich

即使在.NET中使用sqlparameter,SQL注入的示例是什么?

  •  4
  • Tony_Henrich  · 技术社区  · 15 年前

    我听说在为SQL Server使用ado.net sqlparameter(参数化查询)时,仍然可以进行SQL注入。

    我正在寻找C/VB代码中的真实示例作为证据。

    编辑: 我正在寻找具体的工作实例。不介绍SQL注入或如何防止它。

    5 回复  |  直到 14 年前
        1
  •  3
  •   Austin Salonen    14 年前

    如果要在存储过程中创建语句并使用sp_executesql,则参数化查询是一个错误的安全网。

        2
  •  3
  •   Community Egal    7 年前

    这里还有一个问题,关于SQL注入有一些很好的答案…

    Are Parameters really enough to prevent Sql injections?

    这个例子直接来自上面StevenA.Lowe的链接。

    例如,其中参数@p1是表名

    create procedure dbo.uspBeAfraidBeVeryAfraid ( @p1 varchar(64) ) 
    AS
        SET NOCOUNT ON
        declare @sql varchar(512)
        set @sql = 'select * from ' + @p1
        exec(@sql)
    GO
    

    下面是一些进一步的阅读…

        3
  •  2
  •   Mayo    15 年前

    一个具体的例子…

    create procedure dbo.spVulnerable
    @firstname varchar(200)
    as
    exec ('select id from tblPerson where firstname = ''' + @firstname + '''')
    go
    

    我可能把语法搞错了,但是不管您如何参数化@firstname,它仍然容易受到如下的攻击:

    "Joe' or 1=1"
    

    只要使用动态SQL,就可能容易受到SQL注入的攻击。除了使用参数化SQL之外,唯一的解决方案是将输入白名单(或者,如果您感到勇敢,尝试删除危险字符的输入)。

        4
  •  0
  •   Cem Kalyoncu    15 年前

    尝试在ADO.NET中搜索漏洞,可能存在安全缺陷。

        5
  •  0
  •   Remus Rusanu    15 年前

    假设你有一个网站大小的产品目录,你的搜索页面允许按产品名称、描述、颜色和大小搜索(假设你卖胸罩):

    create table [products] (
        product_id int identity(1,1) not null primary key
        , name varchar(256)
        , description varchar(max)
        , color varchar(256)
        , size varchar(256));
    GO  
    
    create procedure usp_dynamicSearch
        @product varchar(256) = NULL
        , @description varchar(256) = NULL
        , @color varchar(256) = NULL
        , @size varchar(256) = NULL
    as
    begin
        set nocount on;
        declare @sql nvarchar(max)
            , @and nvarchar(5);
        set @sql = N'SELECT 
            product_id, name, description, color, size 
            FROM products
            WHERE ';
        set @and = N'';
        if (@product is not null) 
        begin
            set @sql = @sql + N'name LIKE ''' + @product + N'''';
            set @and = N' AND ';
        end
        if (@description is not null) 
        begin
            set @sql = @sql + @and + N'description LIKE ''' + @description + N'''';
            set @and = N' AND ';
        end
        if (@color is not null) 
        begin
            set @sql = @sql + @and + N'color = ''' + @color + N'''';
            set @and = N' AND ';
        end
        if (@size is not null) 
        begin
            set @sql = @sql + @and + N'size = ''' + @size + N'''';
        end 
        exec sp_executesql @sql;
    end
    GO
    

    您可以使用一个存储过程来动态构造用于搜索的SQL应用程序。通过传递参数来调用它:

    exec usp_dynamicSearch @color = N'Red', @size = N'58-DD';
    

    由于该过程以一种粗心的方式构造动态SQL,因此仍然对SQL注入开放:

    exec usp_dynamicSearch @color = N'Red', @size = N''';
    INSERT INTO products (name, description) 
    values (''31337'', ''haxorz!''); 
    --';
    

    不需要的产品被列入了目录(使这成为一种有益的攻击…)。在这种情况下,适当的修复方法是在动态SQL中使用参数,并进一步将参数传递给 sp_executesql 调用:

    alter procedure usp_dynamicSearch
        @product varchar(256) = NULL
        , @description varchar(256) = NULL
        , @color varchar(256) = NULL
        , @size varchar(256) = NULL
    as
    begin
        set nocount on;
        declare @sql nvarchar(max)
            , @and nvarchar(5);
        set @sql = N'SELECT 
            product_id, name, description, color, size 
            FROM products
            WHERE ';
        set @and = N'';
        if (@product is not null) 
        begin
            set @sql = @sql + N'name LIKE @product';
            set @and = N' AND ';
        end
        if (@description is not null) 
        begin
            set @sql = @sql + @and + N'description LIKE @description';
            set @and = N' AND ';
        end
        if (@color is not null) 
        begin
            set @sql = @sql + @and + N'color = @color';
            set @and = N' AND ';
        end
        if (@size is not null) 
        begin
            set @sql = @sql + @and + N'size = @size';
        end 
        exec sp_executesql @sql , N'@product varchar(256)
            , @description varchar(256)
            , @color varchar(256)
            , @size varchar(256)'
            , @product, @description, @color, @size;
    end
    GO
    

    因此,sp_executesql和动态SQL是主要关注的问题。除此之外,还有各种各样的系统过程可以在底层构建动态SQL,而且历史证明有些过程是易受攻击的,特别是在SQL 2000上。