有没有办法访问ADO.net参数化查询?

时间:2019-06-25 16:03:13

标签: sql-server ado.net ado parameterized-query

简短版

如何访问将发送到SQL Server的RPC命令文本

长版

我们都知道您应该防御SQL注入。这意味着要使用一个清理输入的框架,以确保输入不会被误解为SQL语句本身。

通常是

ADO.net,尤其是 SqlCommand

  

注意:除了提供防止SQL注入的附带保护之外,参数化查询的优点还在于查询计划重用-节省了千兆字节的内存,否则这些内存将被临时查询计划缓存占用

例如,而不是运行:

String szQuery = 
@"DECLARE @Username varchar(255) = 'boy'; RAISERROR('https://youtu.be/dQw4w9WgXcQ', 16, 1); --';

DECLARE @UsernameLike varchar(255) = '%'+@Username+'%';

SELECT TOP(100) * FROM Users
WHERE Username = @username
OR FullName LIKE @UsernameLike";

DbCommand cmd = conn.CreateCommand();
cmd.CommandText = szQuery;
IDataReader rdr = cmd.ExecuteReader();

您应该运行:

String szQuery = 
@"DECLARE @Username varchar(255) = @Username;

DECLARE @UsernameLike varchar(255) = '%'+@Username+'%';

SELECT TOP(100) * FROM Users
WHERE Username = @username
OR FullName LIKE @UsernameLike";

// Run the query
DbCommand cmd = conn.CreateCommand();
cmd.CommandText = szQuery;
cmd.Parameters.Add("@Username", SqlDbType.VarChar).Value = "boy'; RAISERROR('https://youtu.be/dQw4w9WgXcQ', 16, 1); --';";
IDataReader rdr = cmd.ExecuteReader();

ADO与托管对象一样,可以执行相同的操作:

String szQuery = 
@"DECLARE @Username varchar(255) = ?;

DECLARE @UsernameLike varchar(255) = '%'+@Username+'%';

SELECT TOP(100) * FROM Users
WHERE Username = @username
OR FullName LIKE @UsernameLike";

// Run the query
Command cmd = new Command();
cmd.CommandText = szQuery;
cmd.Parameters.Append(cmd.CreateParamter("Username", adVarChar, adParamInput, "boy'; RAISERROR('https://youtu.be/dQw4w9WgXcQ', 16, 1); --"));
cmd.ActiveConnection = conn;
Recordset rs = cmd.Execute();

参数化查询

在ADO.net和ADO中,它都会生成一个新查询。使用SQL Server提供程序时:

它生成一个查询,该查询调用仅SQL Server存储过程:

exec sp_executesql N'DECLARE @Username varchar(255) = @P1;

DECLARE @UsernameLike varchar(255) = ''%''+@Username+''%'';

SELECT TOP(100) * FROM Users
WHERE Username = @username
OR FullName LIKE @UsernameLike',N'@P1 varchar(200)','boy''; raiserror(''https://youtu.be/dQw4w9WgXcQ'', 16, 1); --'''

我可以访问该查询吗?

多年来,我一直在使用不同的SQL Server参数化查询库:

SqlHelper的优点在于您可以访问最终生成的查询。这在调试和诊断问题时有很大帮助。

使用ADO.net和ADO可以运行查询,并且不知道实际向服务器发送了什么SQL。似乎无法访问发送到服务器的T-SQL

是否可以访问发送到服务器的T-SQL?

对于步行者

对于步行者:“批处理” 变为“ RPC”

  • 远程过程调用
    • 存储过程ID:10(sp_executesql)
    • 参数
      • 类型:0x63(ntext)
      • 值:DECLARE @Username varchar(255) = @P1;
           DECLARE @UsernameLike varchar(255) = '%'+@Username+'%';
           SELECT TOP(100) * FROM Users
           WHERE Username = @username
           OR FullName LIKE @UsernameLike
    • 参数
      • 类型:0x63(ntext)
      • 值:@P1 varchar(200)
    • 参数
      • 类型:0xa7(varchar)
      • 值:boy''; raiserror(''https://youtu.be/dQw4w9WgXcQ'', 16, 1); --''

我想这足够有趣。但是我们都可以看到我想要访问的修改后的SQL和参数。

慢一点

我想要什么:

  • DECLARE @Username varchar(255) = @P1;
               DECLARE @UsernameLike varchar(255) = '%'+@Username+'%';
               SELECT TOP(100) * FROM Users
               WHERE Username = @username
               OR FullName LIKE @UsernameLike
  • @P1 varchar(200)
  • boy''; raiserror(''https://youtu.be/dQw4w9WgXcQ'', 16, 1); --''

0 个答案:

没有答案