什么是防止sql注入的好方法?

vof42yt1  于 2021-07-26  发布在  Java
关注(0)|答案(4)|浏览(333)

这个问题在这里已经有答案了

如何将用户提供的输入添加到sql语句中(2个答案)
5年前关门了。
我必须为我的在职培训公司规划一个应用程序管理系统。前端将用c#完成,后端用sql完成。
现在我从来没有做过这个范围的项目之前;在学校里,我们只上了sql的基础课。不知何故,我们的老师完全没有讨论sql注入,这是我现在才在网上读到的。
所以不管怎样,我的问题是:如何防止c#中的sql注入?我模模糊糊地认为,可以通过适当地屏蔽应用程序的文本字段,使其只接受指定格式的输入来实现。例如:电子邮件文本框的格式应为“example@examplecompany.tld". 这种方法足够吗?或者.net有预定义的方法来处理这样的事情吗?我是否可以对文本框应用筛选器,使其只接受电子邮件地址格式,或对名称文本框应用筛选器,使其不接受特殊字符?

iq3niunx

iq3niunx1#

通过使用 SqlCommand 它的子参数集合所有检查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);
        }
    }
}
fhity93d

fhity93d2#

sql注入可能是一个棘手的问题,但有办法解决。只需使用像linq2entities、linq2sql、nhibrenate这样的orm,就可以降低风险。但是,即使使用它们,也可能有sql注入问题。
sql注入的主要功能是用户控制的输入(xss也是如此)。在最简单的例子中,如果您有一个使用用户名和密码的登录表单(我希望您永远不会有一个这样做的表单)。

SELECT * FROM Users WHERE Username = '" + username + "' AND password = '" + password + "'"

如果用户要为用户名admin'输入以下内容——在对数据库执行时,sql语句将如下所示。

SELECT * FROM Users WHERE Username = 'Admin' --' AND password = ''

在这个简单的例子中,使用参数化查询(orm就是这样做的)将消除您的风险。还有一个不太有名的SQL注入攻击向量,它是用存储过程来解决的。在这种情况下,即使使用参数化查询或orm,仍然会有sql注入问题。存储过程可以包含execute命令,这些命令本身可能会被sql注入攻击所接受。

CREATE PROCEDURE SP_GetLogin @username varchar(100), @password varchar(100) AS
DECLARE @sql nvarchar(4000)
SELECT @sql = ' SELECT * FROM users' +
              ' FROM Product Where username = ''' + @username + ''' AND password = '''+@password+''''

EXECUTE sp_executesql @sql

因此,即使使用参数化查询或orm,本例也会遇到与前一个相同的sql注入问题。尽管这个例子看起来很傻,但你会惊讶于这样的东西经常被写出来。
我的建议是使用orm来立即减少发生sql注入问题的机会,然后学习发现可能出现问题的代码和存储过程,并解决它们。我不建议直接使用ado.net(sqlclient,sqlcommand等等),除非你必须这样做,不是因为在参数中使用它有点不安全,而是因为它更容易变得懒惰,只需要开始使用字符串编写sql查询而忽略参数。orm在强迫您使用参数方面做得很好,因为它们就是这么做的。
下一步请访问有关sql注入的owasp站点https://www.owasp.org/index.php/sql_injection 并使用sql注入备忘单来确保您能够发现并消除代码中出现的任何问题。https://www.owasp.org/index.php/sql_injection_prevention_cheat_sheet 最后,我要说的是,在你和你公司的其他开发人员之间建立一个良好的代码审查机制,在这里,你可以审查其他人的代码,比如sql注入和xss。很多时候程序员会错过这些东西,因为他们正试图匆忙推出一些特性,而不会花太多时间来检查代码。

cqoc49vn

cqoc49vn3#

我的答案很简单:
使用实体框架在c#和sql数据库之间进行通信。这将使参数化的sql字符串不易受到sql注入的攻击。
作为奖励,它也很容易处理。

ac1kyiln

ac1kyiln4#

不应该通过验证输入来阻止sql注入;相反,应该在将输入传递到数据库之前对其进行正确的转义。
如何转义输入完全取决于您使用什么技术与数据库接口。在大多数情况下,除非您正在编写纯sql(您应该尽量避免),否则框架会自动处理它,这样您就可以免费获得防弹保护。
在你决定了你的接口技术是什么之后,你应该进一步探索这个问题。

相关问题