什么是将参数传递给 SQL,我为什么需要它?
Posted
技术标签:
【中文标题】什么是将参数传递给 SQL,我为什么需要它?【英文标题】:What is passing parameters to SQL and why do I need it? 【发布时间】:2011-03-14 01:46:36 【问题描述】:这里是初学者:
在这个answer 关于如何将数据插入SQL Server 的问题中,他提到了传递参数而不是像我目前使用的字符串连接。
这对于安全来说真的有必要吗?如果是这样,传递参数究竟是什么?当我用谷歌搜索时,我得到了很多关于存储过程的信息。那是我想要的吗,我不知道存储过程....但是。
如果您能指出正确的方向,我将不胜感激。
谢谢。
编辑:
好的,这就是我得到的。似乎可以正确更新数据库,最终我会将硬编码的整数更改为标签的输入。请确认我如何做到这一点是否不易受到任何 sql 注入或黑客攻击。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
public partial class Stats : System.Web.UI.Page
public SqlDataReader DataReader;
public SqlCommand Command;
string queryString = ("INSERT INTO UserData (UserProfileID, ConfidenceLevel, LoveLevel, HappinessLevel) VALUES (@UID, @CL, @LL, @HL);");
//string queryString = ("INSERT INTO UserData (UserProfileID, ConfidenceLevel, LoveLevel, HappinessLevel) VALUES ('a051fc1b-4f51-485b-a07d-0f378528974e', 2, 2, 2);");
protected void Page_Load(object sender, EventArgs e)
LabelUserID.Text = Membership.GetUser().ProviderUserKey.ToString();
protected void Button1_Click(object sender, EventArgs e)
//connect to database
mysqlConnection database = new MySqlConnection();
database.CreateConn();
//create command object
Command = new SqlCommand(queryString, database.Connection);
//add parameters. used to prevent sql injection
Command.Parameters.Add("@UID", SqlDbType.UniqueIdentifier);
Command.Parameters["@UID"].Value = Membership.GetUser().ProviderUserKey;
Command.Parameters.Add("@CL", SqlDbType.Int);
Command.Parameters["@CL"].Value = 9;
Command.Parameters.Add("@LL", SqlDbType.Int);
Command.Parameters["@LL"].Value = 9;
Command.Parameters.Add("@HL", SqlDbType.Int);
Command.Parameters["@HL"].Value = 9;
Command.ExecuteNonQuery();
【问题讨论】:
我最自豪的时刻:***.com/questions/332365/… @Will - 我喜欢小鲍比桌。排名靠前的是他们关于 Gotos 的脱衣舞。 除了学习编写参数化查询之外,我还建议阅读 Justin Clarke 的一本书,名为“SQL 注入攻击与防御”,他在其中深入讨论了 SQL 注入是如何发生的,如何防范它包括 .NET 在内的各种语言,如何测试它等等。不错的读物。 @Thomas:听起来不错。我将不得不以某种方式抽出时间....我是我这个项目的一个人! 【参考方案1】:将参数传递给 SQL 使您不必构建动态 SQL 字符串。
构建动态 SQL 语句存在巨大的安全风险,因为人们可以将自己的 SQL 代码注入您的应用程序,可能会对您的数据执行不需要的命令。
有一些很好的可能的 SQL 注入攻击示例:
SQL Injection Attacks by Example
将参数传递给 SQL 语句有两种方法。一种是使用您提到的存储过程。另一种是使用参数化查询(这实际上是我更喜欢的)。
.NET 中的参数化查询实际上非常简单:
using(SqlConnection conn = new SqlConnection(connString))
SqlCommand command =
new SqlCommand("SELECT * FROM Users WHERE Username = @Username", conn);
command.Parameters.Add(new SqlParameter("@Username", "Justin Niessner"));
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable dt = new DataTable();
adapter.Fill(dt);
在该示例中,参数为@Username
,我们使用SqlCommand
对象的Parameters
集合来传递值。
【讨论】:
对刚开始的人的参数化查询有什么好的参考吗? @Greg 它看起来很简单。【参考方案2】:它会保护你免受小鲍比桌的伤害。
http://xkcd.com/327/
【讨论】:
哈哈,哇哦,那一定是我看过的最极客的漫画了……但我相信它会变得更糟!无论如何,谢谢,我明白你在说什么。【参考方案3】:这是一个例子:
SqlConnection myConn = new SqlConnection("my connection string");
SqlCommand myCmd = new SqlCommand("myStoredProcName", myConn);
myCmd.CommandType = CommandType.StoredProcedure;
myCmd.Parameters.AddWithValue("@cGroupID", 0).Direction = ParameterDirection.InputOutput;
myCmd.Parameters.AddWithValue("@gType", "C");
myCmd.Parameters.AddWithValue("@requirement", "Y");
myCmd.Parameters.AddWithValue("@usercode", "XX");
myConn.Open();
myCmd.ExecuteNonQuery();
int covID = (int)myCmd.Parameters["@cGroupID"].Value;
使用参数是防止某些错误并帮助停止注入向量的好方法。它还允许 OUTPUT 参数,如上面的示例中 cGroupID 返回一个我可以访问的值。
【讨论】:
【参考方案4】:简单连接字符串的主要问题是它经常使您容易受到 SQL 注入攻击。
Google SQL 注入或阅读here。
【讨论】:
【参考方案5】:除了 SQL 注入等,参数化查询在 SQL 服务器看来总是一样的。查询执行计划很可能会被缓存,因此如果您再次发送相同的查询,它将运行得更快。如果您在一个循环中多次运行相同的查询,或者您有许多客户端查询您的服务器,这将非常明显。
【讨论】:
以上是关于什么是将参数传递给 SQL,我为什么需要它?的主要内容,如果未能解决你的问题,请参考以下文章