防止ASP.NET Web应用程序上的SQL注入

我是C#和ASP.NET的新手。

我正在使用VS2005 C#和SQL Server 2005,并且已经做了一些关于防止SQL注入的研究

我的服务器端 Web应用程序中有几个函数,我不确定它们是否需要输入validation。


1)从工具箱登录控件。 我已经直接从VS Toolbox实现了登录控件,我尝试使用RegularExpressionValidator作为我的登录工具,但它似乎不起作用。 Microsoft是否已对该工具进行内置validation?


2)将Excel文件表上传到SQL Server数据库。 我有一个function,允许用户将Excel文件表上传到数据库中。 一开始我不觉得有必要validation它,因为没有打开的SQL查询,但之后我问自己是否有可能用户在excel文件中输入SQL查询,这将导致上传期间的SQL注入。 以下是我的上传代码片段,如果需要validation,我们期待提供建议:

string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strUploadFileName + ";Extended Properties=Excel 8.0;"; using (OleDbConnection connection = new OleDbConnection(connStr)) { string selectStmt = string.Format("Select [COLUMNS] FROM [userlist$]"); OleDbCommand command = new OleDbCommand(selectStmt, connection); connection.Open(); Console.WriteLine("Connection Opened"); // Create DbDataReader to Data Worksheet using (DbDataReader dr = command.ExecuteReader()) { // SQL Server Connection String string sqlConnectionString = "Data Source="; // Bulk Copy to SQL Server using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnectionString)) { bulkCopy.DestinationTableName = "UserDB"; bulkCopy.WriteToServer(dr);; } } } 

3) INSERT语句。 我有几个INSERT语句,主要用于将新记录插入数据库。 由于这些语句实际上并不从数据库中获取数据,因此我不确定是否需要validation。 以下是INSERT语句示例:

 SqlConnection conn = new SqlConnection(""); string sql = string.Format("INSERT INTO [UserData] (Username, Password, Role, Membership, DateOfReg) VALUES ('" + un.Text + "', '" + pw.Text + "', '" + role.Text + "', '" + ms.Text + "', '" + dor.Text + "')"); --> all *.Text are textboxes on the webpage SqlCommand cmd = new SqlCommand(sql, conn); conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); 

4)网页中的搜索function。 我有几个.aspx页面,它们通过GridView显示数据。 下面是我的搜索查询示例,它使用文本框和下拉列表filter:

 SqlDataSource1.SelectCommand = "SELECT * FROM [UserData] where [" + DropDownList1.Text + "] like '%" + searchTextBox.Text + "%'"; SqlDataSource1.DataBind(); 

我想知道对sql语句本身进行输入validation检查的最简单方法是什么, 而不创建其他方法和函数 ,对于上面的例子,我已经看过regular expression并使用mysql_real_escape_string

提前感谢您提供的任何建议和意见。

给出的直接例子也是好的。

在这些示例中不需要validation(检查引号等内容),并且永远不应该使用(除少数情况下,白名单可能是合适的)。

所需要的是参数化 。 使用参数而不是连接。

SqlBulkCopy直接处理数据,所以没关系

 SqlConnection conn = new SqlConnection(""); string sql = string.Format("INSERT INTO [UserData] (Username, Password, Role, Membership, DateOfReg) VALUES ('" + un.Text + "', '" + pw.Text + "', '" + role.Text + "', '" + ms.Text + "', '" + dor.Text + "')"); --> all *.Text are textboxes on the webpage SqlCommand cmd = new SqlCommand(sql, conn); conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); 

只是要求被滥用。 你的系统被破坏了 。 你应该有类似的东西:

 cmd.CommantText = "INSERT INTO [UserData] (Username, ...) VALUES (@username, ...)"; cmd.Parameters.AddWithValue("Username", un.Text); ... 

或任何其他添加参数的方法。

你的例子4是一个有趣的例子,这是白名单可能适合的例子; SQL Server不允许您参数化列名,但您不能信任来自客户端的值。 如果您需要 “根据输入选择列”,则必须根据预期值进行测试:

 string[] allowedColumns = new[] {"Name", "Description", "Foo", "Bar"}; string colName = ... if(!allowedColumns.Contains(colName)) colName = allowedColumns[0]; // DENIED! 

一旦您按照预期值将列列入白名单,您现在知道该值不是"] where 1=1 drop table Users drop table Customers --"

然而! 搜索值应该参数化,即

 `... LIKE @searchValue` 

其中searchValue参数的值为"%" + something.Text + "%"

创建SqlCommand并传递数据,因为SqlParameter将为您完成任务

MSDN: SqlCommand.Parameters属性

 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命令而不是直接传递。 如果通过参数传递值,.net和Sql将处理传递的数据类型。

例如,请参阅以下内容:

 SelectCommand.CommandText = "Select * From [UserData] where ColumnValue like @RowValue"; SelectCommand.Parameters.AddWithValue("@RowValue","% ActualRowValue %"); 

您可以使用标记添加参数。 请参阅带参数的asp:SqlDataSource select命令