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
是什么,但这里有一个利用注入的例子:假设你有一个这样的代码:
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子句中的值参数化。