我正在生成一些动态 SQL,并希望确保我的代码是安全的SQL注入 http://en.wikipedia.org/wiki/SQL_injection.
为了便于论证,这里是一个关于如何生成它的最小示例:
var sql = string.Format("INSERT INTO {0} ({1}) VALUES (@value)",
tableName, columnName);
在上文中,tableName
, columnName
,以及任何必然的@value
来自不受信任的来源。由于正在使用占位符@value
不受 SQL 注入攻击,可以忽略。 (该命令通过 SqlCommand 执行。)
然而,tableName
and columnName
cannot被绑定为占位符,因此易受伤害的注入攻击。由于这是一个“真正动态”的场景,因此没有白名单tableName
or columnName
可用的。
问题是:
有没有标准型、内置型检查和/或消毒的方式tableName
and columnName
? (SqlConnection,或辅助类等)如果没有,执行此任务的好方法是什么without使用第三方库?
Notes:
- 所有 SQL 标识符,包括模式,都应该被接受:例如
[schema].[My Table].column
和一样“安全”table1
.
- 也可以sanitize标识符或detect无效的标识符。 (它不需要确保表/列在上下文中实际上有效;生成的 SQL 可以是无效的,但必须是“安全的”。)
Update:
刚刚发现这个,觉得有点有趣:有一个SqlFunctions.QuoteName http://msdn.microsoft.com/en-us/library/dd466153.aspx.NET4(EF4?)中的函数。好吧,事实并非如此really在这里帮我...
我不确定你是否仍在研究这个问题,但是DbCommandBuilder
类提供了一个方法QuoteIdentifier
以此目的。这样做的主要好处是它独立于数据库并且不涉及任何正则表达式混乱。
从 .NET 4.5 开始,您只需使用 DbConnection 对象就拥有清理表和列名称所需的一切:
DbConnection connection = GetMyConnection(); // Could be SqlConnection
DbProviderFactory factory = DbProviderFactories.GetFactory(connection);
// Sanitize the table name
DbCommandBuilder commandBuilder = factory.CreateCommandBuilder();
string tableName = "This Table Name Is Long And Bad";
string sanitizedTableName = commandBuilder.QuoteIdentifier(tableName);
IDbCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM " + sanitizedTableName;
// Becomes 'SELECT * FROM [This Table Name Is Long And Bad]' in MS-SQL,
// 'SELECT * FROM "This Table Name Is Long And Bad"' in Oracle, etc.
(在 4.5 之前,您需要一些其他方法来获取 DbProviderFactory —— 可能是从应用程序配置中的数据提供程序名称或硬编码的某处。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)