这是防止sql注入的安全方法吗



C#针对sql注入的方法安全吗?

string sqlDeclare = $"DECLARE  @number nvarchar(MAX)  SET @number = '%{sNumber}%' ";

string sqlFilter = "";
if (!string.IsNullOrEmpty(Number))
{
sqlFilter += $" and [table].[number] like @number ";
}

string sql = sqlDeclare + " SELECT [table].[*] ";
sql += " WHERE [table].[state] = 0 and [table].[column1] <> 3 AND [table].[id] > 0  ";
if (!string.IsNullOrEmpty(sqlFilter))
{
sql += sqlFilter;
}
sql += " order by datein";

附言:我不能使用Parametr.Add((

这是C#对抗sql注入的安全方法吗?

如果sNumber实际上是一种数字类型,比如int或decimal,那么我会说";也许";因为很难将SQL注入一个数字中,但最终,您所做的只是将字符串值直接连接到SQL查询中,这是典型的失败:

"SELECT * FROM t WHERE x = " + str

将字符串值放入db变量中,然后在sql中使用。这意味着选择查询不会是完成注入的地方,但它只是提前移动注入点:

想想当sNumber是像'; DROP TABLE students;--这样的值时会发生什么

DECLARE  @number nvarchar(MAX)  SET @number = '%';
DROP TABLE Students;--%' 
SELECT ...

如果你真的被限制使用这个功能(它需要扔掉,tbh(,那么你必须通过对输入进行消毒来尽最大努力防止注射。在这种情况下,你说你期望一个像2-12这样的文档编号,所以你的C#应该看起来像

if(!Regex.IsMatch(userInput, @"^d+-d+$"))
throw new ArgumentException("Bad input value, expecting document number like 2-12");
var dt = Execute4Table($"SELECT * FROM t WHERE x = '{input}');

从一般意义上说,这将是笨拙的,但您可能会做一些包装函数,接受N个参数并将它们序列化为JSON,然后将它们作为JSON字符串传递给sqlserver,并让SQL将它们分解为您在查询中使用的N个参数。这两个序列化程序应该对任何用户提供的值进行编码,使它们被解释为数据而不是代码。如果您的sqlserver对于json来说太旧,那么您也可以对base64执行类似的操作。在某种程度上,这与用"替换所有"没有太大区别,但使用set/deser方法,你将把编码的责任交给一个经过良好测试的库,如果你被这种方法束缚住了,你可能只能使用

如果您键入checksNumber变量并确保它没有字符串危险数据(您的sNumber可能有0';TRUNCATE TABLE [table];--,这将是SQL注入(,则会很安全。如果您检查您的snumber是否为整数,则可以安全地进行字符串插值。

否则将不安全。最好避免字符串插值/字符串串联。

int checkedNumber;
if (Int32.TryParse(out checkedNumber, sNumber))
{
string sqlDeclare = $"DECLARE  @number nvarchar(MAX)  SET @number = '%{sNumber}%' ";
string sqlFilter = "";
if (!string.IsNullOrEmpty(Number))
{
sqlFilter += $" and [table].[number] like @number ";
}
string sql = sqlDeclare + " SELECT [table].[*] ";
sql += " WHERE [table].[state] = 0 and [table].[column1] <> 3 AND [table].[id] > 0  ";
if (!string.IsNullOrEmpty(sqlFilter))
{
sql += sqlFilter;
}
sql += " order by datein";
}

最新更新