我正在使用VS2005 C#和sql Server 2005,并且已经做了一些关于防止sql注入的研究
我的服务器端Web应用程序中有几个功能,我不确定它们是否需要输入验证.
1)从工具箱登录控制.我已经直接从VS ToolBox实现了登录控件,我尝试使用RegularExpressionValidator作为我的登录工具,但它似乎不起作用. Microsoft是否已对该工具进行内置验证?
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语句,主要用于将新记录插入数据库.由于这些语句实际上并不从数据库中获取数据,因此我不确定是否需要进行验证.以下是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语句本身进行输入验证检查的最简单方法是什么,而不创建其他方法和函数,对于上面的例子,我已经看到了正则表达式并使用了MysqL_real_escape_string.
提前感谢您提供的任何建议和意见.
给出的直接例子也很好.
解决方法
所需要的是参数化.使用参数而不是连接.
sqlBulkCopy直接处理数据,所以没关系,但是:
sqlConnection conn = new sqlConnection("<datasource>"); string sql = string.Format("INSERT INTO [UserData] (Username,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!
一旦您将列列入白名单中的预期值,您现在知道该值不是“],其中1 = 1 drop table用户删除表Customers – ”
然而!搜索值应参数化,即
`... LIKE @searchValue`
其中searchValue参数的值为“%”something.Text“%”