Что передают параметры SQL и зачем мне это нужно?
Начинающий здесь:
В этом ответе на мой вопрос о том, как вставлять данные в SQL Server, он упомянул параметры передачи, а не конкатенацию строк, как в настоящее время.
Это действительно необходимо для безопасности? Если да, то какие именно параметры проходят? Когда я google, я много разбираюсь в хранимых процедурах. Это то, чего я хочу, я еще не знаю о хранимых процедурах....
Если вы можете указать мне в правильном направлении, я был бы признателен.
Спасибо.
EDIT:
Хорошо, вот что я получил. Кажется, что он правильно обновляет базу данных, и в конце концов я изменю жестко закодированные ints на входы с метки. Пожалуйста, подтвердите, что, как я это сделал, не уязвим для каких-либо 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();
}
}
Ответы
Ответ 1
Передача параметров SQL избавляет вас от необходимости создавать динамическую строку SQL.
Создание динамических операторов SQL - ОГРОМНЫЙ риск для безопасности, потому что люди могут вставлять свой собственный код SQL в ваше приложение, возможно, выполняя нежелательные команды против ваших данных.
Есть несколько хороших образцов возможных атак SQL Injection:
SQL-инъекции по примеру
Существует два способа передачи параметров в операторы 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
, и мы использовали коллекцию Parameters
объекта SqlCommand
для передачи значения.
Ответ 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
Этот сайт содержит подробный обзор того, что вы ищете.
Кроме того, были другие fooobar.com/questions/69457/... questions на эту тему. Wikipedia также имеет довольно хорошую запись для инъекций SQL.
Ответ 5
Основная проблема с просто конкатенацией строк заключается в том, что она часто оставляет вас уязвимыми для атак SQL Injection.
Google SQL Injection или прочитайте здесь.
Ответ 6
В дополнение к SQL-инъекциям и тому подобному, параметризованные запросы всегда выглядят одинаково для SQL-сервера. Скорее всего, план выполнения запросов будет кэшироваться, поэтому, если вы снова отправите тот же запрос, он будет работать быстрее. Это было бы очень заметно, если бы вы выполняли один и тот же запрос много раз в цикле или у вас было много клиентов, которые запрашивали ваш сервер.