防止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
一样。
事先感谢您提供的任何意见和建议。
直接举例也可以。
验证(检查诸如引号之类的东西)在这些示例中永远不需要,并且永远不应该使用(除了少数情况,白名单可能是合适的)
需要的是参数化。使用参数代替串联。
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 %");
您可以使用标记添加参数。参考带有参数