提问人:LeonidasFett 提问时间:1/17/2013 最后编辑:Nondeterministic narwhalLeonidasFett 更新时间:5/17/2015 访问量:162184
防止SQL注入的好方法是什么?[复制]
What are good ways to prevent SQL injection? [duplicate]
问:
我必须为我的在职培训公司编写一个应用程序管理系统。前端将使用 C# 完成,后端将使用 SQL 完成。
现在我以前从未做过这种规模的项目;在学校里,我们只有关于SQL的基本课程。不知何故,我们的老师完全没有讨论SQL注入,我现在只是通过在网上阅读它才接触到的。
所以无论如何,我的问题是:如何防止 C# 中的 SQL 注入?我隐约认为可以通过正确屏蔽应用程序的文本字段来完成,以便它只接受指定格式的输入。例如:电子邮件文本框的格式应为“[email protected]”。这种方法就足够了吗?或者 .NET 是否具有处理此类内容的预定义方法?是否可以将筛选器应用于文本框,使其仅接受电子邮件地址格式或名称文本框,使其不接受特殊字符?
答:
我的答案很简单:
使用 Entity Framework 在 C# 和 SQL 数据库之间进行通信。这将使参数化的 SQL 字符串不容易受到 SQL 注入的影响。
作为奖励,它也很容易使用。
评论
不应通过尝试验证输入来阻止 SQL 注入;相反,在将该输入传递到数据库之前,应正确转义该输入。
如何转义输入完全取决于你使用什么技术来与数据库进行交互。在大多数情况下,除非您正在编写裸 SQL(您应该尽可能避免这种情况),否则框架会自动处理它,因此您可以免费获得防弹保护。
在你决定了你的接口技术之后,你应该进一步探索这个问题。
评论
User.Name = "Joe"; User.Save();
Database.ExecuteQuery("UPDATE users SET name = 'Joe' WHERE id = 1");
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 注入问题。存储过程可以包含执行命令,而这些命令本身可能容易受到 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 查询并忽略参数。ORMS在强制你使用参数方面做得很好,因为这正是它们所做的。
接下来:访问 SQL 注入 https://www.owasp.org/index.php/SQL_Injection 上的 OWASP 站点,并使用 SQL 注入备忘单,以确保您可以发现并消除代码中出现的任何问题。https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet 最后,我想说的是,在你和你公司的其他开发人员之间建立良好的代码审查,在那里你可以审查彼此的代码,比如SQL注入和XSS。很多时候,程序员错过了这些东西,因为他们试图匆忙推出一些功能,而不是花太多时间审查他们的代码。
评论
通过使用 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);
}
}
}
评论
^\s*['"]\s*\)\s*;
using
上一个:什么是SQL注入?[复制]
评论