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

本文关键字:NET Web 应用程序 注入 SQL ASP 上的 防止 | 更新日期: 2023-09-27 18:17:14

我是c#和ASP.NET新手。

我使用VS2005 c#和SQL Server 2005,并做了一些关于防止SQL注入的研究

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


1) 从工具箱登录控件。我已经实现了直接从VS工具箱登录控件,我试图使用RegularExpressionValidator为我的登录工具,但它似乎不工作。微软是否已经为该工具提供了内置验证?


2) 上传excel文件表的到SQL Server数据库。我有一个功能,允许用户上传excel文件表到数据库。一开始我不觉得有必要验证它,因为没有开放的sql查询,但在那之后我问自己,如果用户在excel文件中输入sql查询,这将导致上传过程中的sql注入。下面是我上传的代码片段,如果需要验证,我会期待建议:

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=<datasource>";
        // Bulk Copy to SQL Server
        using (SqlBulkCopy bulkCopy =
                   new SqlBulkCopy(sqlConnectionString))
        {
            bulkCopy.DestinationTableName = "UserDB";
            bulkCopy.WriteToServer(dr);;
        }
    }
}

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

SqlConnection conn = new SqlConnection("<datasource>");
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)搜索功能。我有几个.aspx页面显示数据的GridView。下面是一个使用文本框和下拉列表过滤器的搜索查询示例:

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

我想知道在不创建额外的方法和函数的情况下对sql语句本身进行输入验证检查的最简单方法是什么,就像我看到的regular expression和使用mysql_real_escape_string一样。

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

直接举例也可以。

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

验证(检查诸如引号之类的东西)在这些示例中永远不需要,并且永远不应该使用(除了少数情况,白名单可能是合适的)

需要的是参数化。使用参数代替串联。

SqlBulkCopy直接处理数据,所以很好,但是:

SqlConnection conn = new SqlConnection("<datasource>");
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。属性

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命令