SQL 使用 SqlBuilder 在 FROM 子句中注入
SQL Injection in FROM clause with SqlBuilder
我们有一个 SQL 语句,它使用 SqlBuilder
在 from 子句中设置 table 名称。数据库是 SQL Server 2008 及更高版本。
var sqlBuilder = new SqlBuilder();
sqlBuilder.Select("*").From(tableName);
sqlBuilder.Where("...");
Connection.BuilderQuery<dynamic>(sqlBulder).Select(Map);
我想知道这是否存在 SQL 注入风险?我怎样才能减轻这种风险?或者 SqlBuilder
会处理这些事情吗?
我可以通过将 table 名称括在方括号中来降低风险吗?例如
sqlBuilder.From("[" + tableName + "]");
此外,如果有人可以在 FROM
子句中提供一些 SQL 注入攻击的示例,以便我了解它的工作原理并创建测试,我们将不胜感激。
我以前不得不做类似的事情,虽然我不知道 SqlBuilder,但我通过检查以下查询的 ExecuteScalar() 结果解决了这个问题
select count(*) from information_Schema.tables where table_name = @tbl
如果结果 > 0,我将使用以下操作(如果结果为 0,则必须脱离)
string sql = "Select a, b, c from ["+tblName+"]"
它很脏,但是使用信息模式应该保证 table 名称存在于数据库中并且变量不包含任何讨厌的东西。
我不知道 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
并且您失去了整个 table...显然,可以通过这种方式实现更多破坏性的命令...
从问题中的信息中不清楚代码是否易受攻击。 SqlBuilder
对象不太可能以安全的方式处理 table 名称,但在我们了解 SqlBuilder 的确切细节之前我们无法确定,这不是 .净框架。我们还需要了解更多关于 tableName
变量的信息,因为即使是不安全的 SqlBuilder 实现也可以使用 table 名称的安全来源。
顺便提一下,我可以肯定地说使用方括号的建议修复 不会 解决问题。鉴于此代码:
sqlBuilder.From("[" + tableName + "]");
我仍然可以像这样提供输入:
information_schema.columns];DROP TABLE x;SELECT * FROM [y
中间的部分仍然会被注入并执行。
另外,您可能正在使用这个:
https://github.com/maxtoroq/DbExtensions/blob/master/docs/SqlBuilder.md
如果是这样,在查看该类型的文档后,您应该知道这绝对不是参数安全的 table 名称,并且很可能考虑到 MySql 编写(它使用 LIMIT
子句,这是 SQL 的非标准 MySql 扩展)。
Or does the SqlBuilder
take care of these things?
没有。您必须正确使用该技术来保护自己。就像有安全带的汽车一样,只有正确使用它才能得到保护。
I am wondering if this is a SQL injection risk?
也许吧。如果您在 end-user 数据上使用任何类型,那么很可能是。如果您必须询问您的最终用户他们想要填充哪个 table,我会推荐一个枚举。带有字符串标题和 int 值的下拉框;
public enum WhitelistTable
{
Undefined = 0,
MyTable1,
MyTable2
}
如果用户数据不是 int,则它是无效的。您可以在每个枚举值上放置一个 DescriptionAttribute
或简单地 .ToString()
枚举值 并插入它。实施白名单优于黑名单。
var myTable = WhitelistTable.MyTable1;
sqlBuilder.From(myTable.ToString());
Could I mitigate the risk simply by wrapping the table name in square brackets?
我不这么认为,一般不会(我不是 100% 确定 SqlBuilder)。我什至不会依靠第三方来源来冒险。示例值:
SomeTable]; Drop Table SomeTable; --
产量:
sqlBuilder.From("[SomeTable]; Drop Table SomeTable; --]");
sqlBuilder.Select("*").From(tableName);
如果 tableName
数据来自用户输入,用户可以在键盘上键入或上传到文件中 = 您很容易受到 Sql 注入
sqlBuilder.Where("...");
同样的事情。 Where
通常来自用户输入。用户键入内容,然后您在 where 子句中使用该值。 SqlBuilder
是否进行参数化? - 如果答案是 NO 你很脆弱。
Quote: 或者 SqlBuilder 会处理这些事情吗?
答:你告诉我们。这里的大多数人即将结束您的问题,因为不清楚什么是 SqlBuilder
以及它是如何工作的。虽然,我至少理解它是什么,因为我们使用了相似的概念。我们的 Table 名称是常量,我们的 sql 生成器参数化值被添加到 where 子句。
我们有一个 SQL 语句,它使用 SqlBuilder
在 from 子句中设置 table 名称。数据库是 SQL Server 2008 及更高版本。
var sqlBuilder = new SqlBuilder();
sqlBuilder.Select("*").From(tableName);
sqlBuilder.Where("...");
Connection.BuilderQuery<dynamic>(sqlBulder).Select(Map);
我想知道这是否存在 SQL 注入风险?我怎样才能减轻这种风险?或者 SqlBuilder
会处理这些事情吗?
我可以通过将 table 名称括在方括号中来降低风险吗?例如
sqlBuilder.From("[" + tableName + "]");
此外,如果有人可以在 FROM
子句中提供一些 SQL 注入攻击的示例,以便我了解它的工作原理并创建测试,我们将不胜感激。
我以前不得不做类似的事情,虽然我不知道 SqlBuilder,但我通过检查以下查询的 ExecuteScalar() 结果解决了这个问题
select count(*) from information_Schema.tables where table_name = @tbl
如果结果 > 0,我将使用以下操作(如果结果为 0,则必须脱离)
string sql = "Select a, b, c from ["+tblName+"]"
它很脏,但是使用信息模式应该保证 table 名称存在于数据库中并且变量不包含任何讨厌的东西。
我不知道 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
并且您失去了整个 table...显然,可以通过这种方式实现更多破坏性的命令...
从问题中的信息中不清楚代码是否易受攻击。 SqlBuilder
对象不太可能以安全的方式处理 table 名称,但在我们了解 SqlBuilder 的确切细节之前我们无法确定,这不是 .净框架。我们还需要了解更多关于 tableName
变量的信息,因为即使是不安全的 SqlBuilder 实现也可以使用 table 名称的安全来源。
顺便提一下,我可以肯定地说使用方括号的建议修复 不会 解决问题。鉴于此代码:
sqlBuilder.From("[" + tableName + "]");
我仍然可以像这样提供输入:
information_schema.columns];DROP TABLE x;SELECT * FROM [y
中间的部分仍然会被注入并执行。
另外,您可能正在使用这个:
https://github.com/maxtoroq/DbExtensions/blob/master/docs/SqlBuilder.md
如果是这样,在查看该类型的文档后,您应该知道这绝对不是参数安全的 table 名称,并且很可能考虑到 MySql 编写(它使用 LIMIT
子句,这是 SQL 的非标准 MySql 扩展)。
Or does the
SqlBuilder
take care of these things?
没有。您必须正确使用该技术来保护自己。就像有安全带的汽车一样,只有正确使用它才能得到保护。
I am wondering if this is a SQL injection risk?
也许吧。如果您在 end-user 数据上使用任何类型,那么很可能是。如果您必须询问您的最终用户他们想要填充哪个 table,我会推荐一个枚举。带有字符串标题和 int 值的下拉框;
public enum WhitelistTable
{
Undefined = 0,
MyTable1,
MyTable2
}
如果用户数据不是 int,则它是无效的。您可以在每个枚举值上放置一个 DescriptionAttribute
或简单地 .ToString()
枚举值 并插入它。实施白名单优于黑名单。
var myTable = WhitelistTable.MyTable1;
sqlBuilder.From(myTable.ToString());
Could I mitigate the risk simply by wrapping the table name in square brackets?
我不这么认为,一般不会(我不是 100% 确定 SqlBuilder)。我什至不会依靠第三方来源来冒险。示例值:
SomeTable]; Drop Table SomeTable; --
产量:
sqlBuilder.From("[SomeTable]; Drop Table SomeTable; --]");
sqlBuilder.Select("*").From(tableName);
如果 tableName
数据来自用户输入,用户可以在键盘上键入或上传到文件中 = 您很容易受到 Sql 注入
sqlBuilder.Where("...");
同样的事情。 Where
通常来自用户输入。用户键入内容,然后您在 where 子句中使用该值。 SqlBuilder
是否进行参数化? - 如果答案是 NO 你很脆弱。
Quote: 或者 SqlBuilder 会处理这些事情吗?
答:你告诉我们。这里的大多数人即将结束您的问题,因为不清楚什么是 SqlBuilder
以及它是如何工作的。虽然,我至少理解它是什么,因为我们使用了相似的概念。我们的 Table 名称是常量,我们的 sql 生成器参数化值被添加到 where 子句。