查看原文
其他

C# 防SQL注入最好实现方式是什么?

DotNet 2022-07-19

The following article is from NET技术问答 Author Stackoverflow

一、问题

如何在 C# 中是使用SQL防注入,我的模糊理解是可以通过限定应用程序接收的字段格式来实现最终目的,比如说:email字段只能接收email的格式,name字段不能输入特殊字符,以此类推,C#中应该也有对应的预定义方法。

这里想问大家有什么其他的思考。

二、回答

理论上你的做法是相对高效的,但是落地非常繁琐,其实你完全可以使用 SqlCommandSqlParameters[] 实现SQL的参数化查询,它是一种非常通用的解决方案,无需特定字段使用特定格式的方式,参考如下代码:

private static void UpdateDemographics(Int32 customerID,  
    string demoXml, string connectionString)
  
{  
    // Update the demographics for a store, which is stored    
    // in an xml column.    
    string commandText = "UPDATE Sales.Store SET Demographics = @demographics "  
        + "WHERE CustomerID = @ID;";  
  
    using (SqlConnection connection = new SqlConnection(connectionString))  
    {  
        SqlCommand command = new SqlCommand(commandText, connection);  
        command.Parameters.Add("@ID", SqlDbType.Int);  
        command.Parameters["@ID"].Value = customerID;  
  
        // Use AddWithValue to assign Demographics.   
        // SQL Server will implicitly convert strings into XML.  
        command.Parameters.AddWithValue("@demographics", demoXml);  
  
        try  
        {  
            connection.Open();  
            Int32 rowsAffected = command.ExecuteNonQuery();  
            Console.WriteLine("RowsAffected: {0}", rowsAffected);  
        }  
        catch (Exception ex)  
        {  
            Console.WriteLine(ex.Message);  
        }  
    }  
}  
SQL 注入是一种很搞的问题,但还是有几种解决办法,要想减少风险,可以使用 ORM 框架 Linq2Entities, Linq2SQL, NHibrenate 等等,即使这么说,用这些框架还是有一定的注入风险的,SQL 注入的来源主要是用户界面的输入框,一个经典的例子是:假如你有一个登录界面,需要输入 用户名密码
SELECT * FROM Users WHERE Username = '" + username + "' AND password = '" + password + "'"  
此时有一个用户在input上输入 Admin'--, 那么SQL语句将会发生质的变化。
SELECT * FROM Users WHERE Username = 'Admin' --' AND password = ''  
要解决这种问题,就需要使用参数化查询 SQLParameter 来解决。
三、总结
说实话, 对于SQL注入这块,我个人倾向于选择  ORM 和 裸SQL 之间的 Dapper 来进行处理,比如下面这样:
var list = Execute(conn =>  
{  
    var sql = string.Format($@"select t.TagNo from xxx as c  
                               join xxx as ct  
                               on c.ID = ct.ID  
                               where  t.TagNo in @TagNo and c.Cus_ID = @CustomerID"
);  

    var query = conn.Query<string>(sql, new { TagNo = epcList, CustomerID = context.CustomerID }).ToList();  

    return query;  
});    
写法灵活,可控性高,效率也不错。

- EOF -

推荐阅读  点击标题可跳转
几个超级实用但很少人知道的 VS 技巧 .NET Core 使用-网关 Ocelot+Consul概述 .NET 6 ThreadPool 实现


看完本文有收获?请转发分享给更多人

推荐关注「DotNet」,提升.Net技能 

点赞和在看就是最大的支持❤️

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存