SqlBuilder的FROM子句中的SQL注入

本文关键字:SQL 注入 子句 FROM SqlBuilder | 更新日期: 2023-09-27 17:50:08

我们有一个SQL语句,它使用SqlBuilder设置from子句中的表名。数据库为SQL Server 2008及更高版本。

var sqlBuilder = new SqlBuilder();
sqlBuilder.Select("*").From(tableName);
sqlBuilder.Where("...");
Connection.BuilderQuery<dynamic>(sqlBulder).Select(Map);

我想知道这是否存在SQL注入风险?我该如何减轻这种风险?还是SqlBuilder负责这些事情?

我可以通过将表名括在方括号中来减轻风险吗?例如

sqlBuilder.From("[" + tableName + "]");

此外,如果有人能在FROM子句中提供一些SQL注入攻击的例子,让我了解它是如何工作和创建测试的,我将不胜感激。

SqlBuilder的FROM子句中的SQL注入

我不知道SqlBuilder是什么,但这里有一个利用注入的例子:假设你有一个这样的代码:

var myFullQuery = string.Format("SELECT * FROM {0} WHERE A = 1", externalInput);

然后对数据库执行该操作。如果恶意用户发送此字符串作为输入:ValidTableName; DELETE FROM ValidTableName; SELECT * FROM ValidTableName

myFullQuery变量将被设置为:SELECT * FROM ValidTableName; DELETE FROM ValidTableName; SELECT * FROM ValidTableName WHERE A = 1,并且您已经丢失了整个表。。。显然,通过这种方式可以实现更多的开发命令。。。

从问题中的信息中不清楚代码是否易受攻击。SqlBuilder对象不太可能以安全的方式处理表名,但在了解SqlBuilder的确切细节之前,我们无法确定,SqlBuilder不是.Net框架的标准部分。我们还需要了解更多关于tableName变量的信息,因为即使是不安全的SqlBuilder实现也可以使用表名的安全源。

顺便说一句,我可以肯定地说,使用方括号的拟议修复并不能解决问题。给定此代码:

sqlBuilder.From("[" + tableName + "]");

我仍然可以提供这样的输入:

information_schema.columns];下拉表x;从[y 中选择*

并且中间的部分仍将被注入和执行。

此外,看起来你可能正在使用这个:

https://github.com/maxtoroq/DbExtensions/blob/master/docs/SqlBuilder.md

如果是这样的话,在查看了该类型的文档后,您应该意识到这对于表名来说肯定是而不是参数安全的,并且很可能是在考虑MySql的情况下编写的(它使用了LIMIT子句,这是SQL的非标准MySql扩展(。

还是SqlBuilder负责这些事情?

没有。你必须正确使用这项技术来保护自己。就像有一辆带安全带的汽车一样,只有正确使用它,你才能得到保护。

我想知道这是否存在SQL注入风险?

也许吧。如果您对最终用户数据使用任何类型,那么很可能是的。如果您必须询问最终用户要填充哪个表,我建议使用枚举。带有字符串标题和int值的下拉框;

public enum WhitelistTable
{
  Undefined = 0,
  MyTable1,
  MyTable2
}

如果用户数据不是int,那么它就是无效的。您可以在每个枚举值上放置一个DescriptionAttribute,也可以简单地在枚举值上放置.ToString()并插入它。推进白名单比黑名单更好。

var myTable = WhitelistTable.MyTable1;
sqlBuilder.From(myTable.ToString());

我可以通过将表名括在方括号中来减轻风险吗?

我不这么认为,一般来说也不这么认为(我对SqlBuilder不是100%确定(。我甚至不会依靠第三方消息来源来冒险。示例值:

SomeTable];Drop Table SomeTable;--

收益率:

sqlBuilder.From("[SomeTable]; Drop Table SomeTable; --]");

我以前也做过类似的事情,虽然我不知道SqlBuilder,但我通过检查以下查询的ExecuteScalar((结果来解决它

select count(*) from information_Schema.tables where table_name = @tbl

如果结果>0,我会使用做以下操作(如果结果是0,那么你必须脱离(

string sql = "Select a, b, c from ["+tblName+"]"

它是脏的,但使用信息模式应该确保表名存在于数据库中,并且变量不包含任何脏的内容。

sqlBuilder.Select("*").From(tableName);

如果tableName数据来自用户输入,则用户可以在键盘上键入或上传到文件中=您容易受到Sql Injection 的攻击

sqlBuilder.Where("...");

同样的事情。CCD_ 15通常来自用户输入。用户键入一些内容,然后在where子句中使用该值。SqlBuilder能进行参数化吗?-如果答案是,那么您很容易受到攻击。

引用:或者SqlBuilder会处理这些事情吗?

答:你告诉我们。这里的大多数人都将结束你的问题,因为不清楚什么是SqlBuilder以及它是如何工作的。尽管如此,我至少理解它是什么,因为我们使用了类似的概念。我们的表名是常量,我们的sql生成器将添加到where子句中的值参数化。