Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# QuoteIdentifier是否足以保护查询免受Sql注入攻击?_C#_Sql Injection - Fatal编程技术网

C# QuoteIdentifier是否足以保护查询免受Sql注入攻击?

C# QuoteIdentifier是否足以保护查询免受Sql注入攻击?,c#,sql-injection,C#,Sql Injection,虽然参数是防止Sql注入的最佳方法,但在构建动态查询时,有时我们不能使用它。例如,表/列/索引名不能作为参数传入,只能作为纯文本传入 好像 SqlCommandBuilder.QuoteIdentifier 是我能找到的唯一选择。调用此方法是否足以保护我们自己 MSDN文件: 在正确的目录大小写中给定一个不带引号的标识符,返回 该标识符的正确引用形式。这包括: 转义标识符中的任何嵌入引号 例如 "Select * FROM " + SqlCommandBuilder.QuoteIdentifi

虽然参数是防止Sql注入的最佳方法,但在构建动态查询时,有时我们不能使用它。例如,表/列/索引名不能作为参数传入,只能作为纯文本传入

好像

SqlCommandBuilder.QuoteIdentifier
是我能找到的唯一选择。调用此方法是否足以保护我们自己

MSDN文件:

在正确的目录大小写中给定一个不带引号的标识符,返回 该标识符的正确引用形式。这包括: 转义标识符中的任何嵌入引号

例如

"Select * FROM " + SqlCommandBuilder.QuoteIdentifier("CustomTable" + userInputText);
安全吗


编辑:查询只是一个示例。我很想知道Sql注入是否可能

对我来说似乎很安全。此外,这可能是一个很好的参考:


这样做可能不安全

为了防止SqlCommandBuilder.QuoteIdentifier方法出现任何可能的安全问题,您需要做的就是从数据库中获取可用表名等的列表,并根据它们验证用户输入

编辑后添加:我有理由怀疑QuoteIdentifier是否完全安全:如您先前引用的文档所述:

在正确的目录大小写中给定一个不带引号的标识符,返回该标识符的正确带引号形式。这包括正确转义标识符中的任何嵌入引号


在该文档中,没有任何地方说明如果在错误的catalog case(无论是什么catalog case)中给它一个不带引号的标识符会发生什么情况。或者,如果标识符的长度大于。当然,无法依赖未定义的行为。

它无法保护您免受攻击者进入您不希望他们进入的表的攻击


例如SQL系统表…

在表名字段中使用用户输入永远不会安全,无论您如何尝试检查它,除非您将条目限制为有限的名称集或执行其他类型的魔法


即使删除引号,用户也可以键入:TableName;删除数据库数据库;或者从中选择*您是否考虑过使用OData?您可以传入文本、选择表、索引等。但是使用OData,您可以选择要以这种方式发布的表,并且它不会受到注入攻击,因为您必须显式地允许更新和插入操作


表名可能包含特殊字符,因此我认为清理不是一个好的选择。您能否提供一个示例,说明如何针对此进行注入?@Steve不,我不能,但有一些复杂的SQL注入攻击示例。我编辑了我的答案,提到了一个傻瓜式的方法。这只是一个例子。我只是想弄清楚sql注入是否可行,这不是权限的用途吗?因此,任何SQL查询都不能防止用户访问他应该再次查看的表的权限…如果使用组合框,则验证所选值仍然至关重要,因为有方法可以修改它。@AndrewMorton这就是为什么我建议也使用字符串[]和允许的值,但如果您开始这样想,如果用户篡改组件并删除验证,它仍然可能被破坏。
SqlCommand userInfoQuery = new SqlCommand(
    "SELECT id, name, email FROM users WHERE id = @UserName",
    someSqlConnection);

SqlParameter userNameParam = userInfoQuery.Parameters.Add("@UserName",
    SqlDbType.VarChar, 25 /* max length of field */ );

// userName is some string valued user input variable
userNameParam.Value = userName;
String username = "joe.bloggs";
SqlCommand sqlQuery = new SqlCommand("SELECT user_id, first_name,last_name FROM users WHERE username = ?username",  sqlConnection);
sqlQuery.Parameters.AddWithValue("?username", username);