ASP.NET是否能防止SQL注入攻击?

7
ASP.NET默认情况下是否在使用ASP控件时防止SQL注入攻击?

3
为了获得更好的答案,你应该明确说明你是如何访问你的数据库的(你使用了哪些控件)。 - M4N
我现在实际上没有特定的用例。但是在未来设计页面时,我想了解控件中内置的安全功能。起初,我认为通过使用ASP,我会获得许多免费的安全功能。但从这里的答案中,我学到了很多。对于有限数量的控件,确实内置了安全性,但对于大多数控件,没有安全性,并且在编写代码时应使用参数来保持自己的安全。我希望我可以将其中几个投票为“答案”,因为这里有很多好东西。 - mrtsherman
7个回答

10

是和不是。

ADO.NET非常支持参数化,当你正确使用它时,参数值将自动进行清理以防止SQL注入。因此,你可以向SqlCommand(或SqlDataSource控件)添加参数而不必太担心参数中包含的内容。

好消息是参数化非常容易。我将展示一个用C#编程实现的例子,但是如果你喜欢,也可以使用服务器控件在声明式中完成。

坏消息是就像其他任何事情一样,你仍然需要考虑你在做什么。任何来自不安全来源的字符串,如果想要保证安全性,必须进行参数化。如果直接将其原样粘贴到查询中,则会绕过ADO.NET的安全功能。

安全:

string name = txtName.Text;
sqlCommand.CommandText = "select * from product where name = @name";
sqlCommand.Parameters.AddWithValue("name", name);

不安全:

string name = txtName.Text;
sqlCommand.CommandText = "select * from product where name = " + name;

如果你的SQL查询中有任何来自用户的输入,你需要将其放入参数中,否则一切都无法保证。就像几乎任何事情一样,如果你真的想这样做,可能会给自己带来麻烦。例如,你可以将SQL代码放入参数中,并将其传递给SQL EXEC语句。但你不会这样做,对吗?因为这是一个非常糟糕的想法。

即使这样仍然不安全(是的,我在生产代码中看到过这种情况!)

string sql = "select * from product where name = " + txtName.Text;
sqlCommand.CommandText = "exec(@sql)";
sqlCommand.Parameters.AddWithValue("sql", sql);

TL;DR: ADO.NET拥有出色的功能来防止SQL注入,但只有在正确使用它们时才能发挥作用。


不知道为什么我打了 "eval" 而不是 "exec"。已修复。 - Justin Morgan
1
你的 sqlCommand2 示例很好。CommandText 是完全参数化的,但我们仍然受到攻击。希望永远不会在现实生活中遇到这种情况 :-) - Steven
@Steven:我希望情况是这样的。这几乎就是我在现实生活中看到的,当我看到它时,我有点哭了。 - Justin Morgan

10

不。只要您提供SQL,就由您来巧妙地使用控件。

通常意味着清理输入并使用参数查询或存储过程而非动态SQL语句。

如果控件为您生成查询(例如成员控件等),则您将得到很好的保护。


1
因此,当使用标准的ASP控件(如asp:TextBox)并在代码后端自己编写SQL语句时,安全性为零。当使用预配置的控件(如asp:datagrid),该控件连接到asp:sqldatasource时,则受到保护。 - mrtsherman
2
@mrtsherman - 我想补充一点,如果你在代码后端使用参数化,它和sqldatasource版本一样安全。而且可以设置一个没有参数化的sqldatasource,这样做和在代码后端操作一样不安全。所以参数化是关键。 - Justin Morgan

8

大多数ASP.Net控件(除了DataGrid)根本不使用SQL。

如果您在代码中使用自己的SQL(使用SqlCommand),则不会获得任何免费保护; 您需要使用参数。

少数使用SQL的控件(SqlDataSource和成员框架)确实使用参数,并且可以防止注入攻击。


3

ASP.NET无法防止SQL注入攻击!

ASP.NET只是Web应用程序框架,它不规定您以何种方式访问数据库。这取决于您如何实现数据访问:

  • 如果您正在使用ADO.NET,并且将SQL查询作为字符串构建,则必须对任何用户输入进行清洗,以免受到注入攻击。
  • 如果您正在使用ADO.NET并使用SqlParameters,则我认为您可以免受注入攻击。
  • 如果您使用ORM工具进行数据访问,则我认为您是安全的(至少在使用常见工具时是这样)
  • 如果您正在使用DataSets,则您也可能是安全的。
  • 如果您正在使用某些第三方数据绑定控件,则我希望它们会注意保护您免受SQL注入攻击

也许我在答案中忘记了很多事情,但您可以看出答案是:“要看情况而定”


1
如果您始终使用 SqlParameter,并且从不将用户输入连接到 SQL 中,那么您应该是安全的。您也可以在没有存储过程的情况下使用 SqlParameter

1

不,ASP.Net不能防止SQL注入。ASP.Net控件的MS提供的代码应该是没有SQL注入问题的,但这并不能防止开发人员陷入所有问题中。最好的防御是对SQL注入有良好的理解和谨慎的编码。当这是无法实现的,出于任何原因,有一些工具可以帮助,比如Microsoft Code Analysis Tool .NET (CAT.NET)。这是一个免费的VS插件,可以分析生成的程序集并检测SQL注入、XSS和XPath注入风险。这样的工具并不是万无一失的,但比没有要好得多。


我发现这个工具非常无用。它甚至不能发现最简单的SQL注入形式,比如:var cmd = con.CreateCommand(); cmd.CommandText = "UPDATE T SET V = '" + text + "'";。这个工具还有很长的路要走。 - Steven

0

部分地。默认情况下开启了一个过滤器,使得构造SQL注入攻击变得困难,除非将其关闭。

许多ASPNET应用程序访问MSSQL数据库的方法也使它们通常抵抗SQL注入攻击。

但是,如果你够粗心,仍然有可能创建一个易受攻击的应用程序。


ASP与数据库的连接以何种方式保护免受注入攻击?如果您可以破坏查询,那么连接方法就无关紧要了,是吗? - mrtsherman
@mrtsherman - 我认为它指的不是连接本身,而是整个SqlClient堆栈及其安全功能。@MarkR,也许需要一些详细说明? - Justin Morgan
许多应用程序使用带参数的命令对象或数据集(datarow等)对象,然后在内部生成参数化查询。这些模式不容易受到SQL注入攻击。当然,如果您忽略这些并编写自己的SQL,则会有风险,但默认情况下启用请求过滤器仍然可以提供保护(在某种程度上)。 - MarkR
这大概就是我认为你的意思了。我给你点赞。 - Justin Morgan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接