Предотвращение внедрения SQL-кода в веб-приложении ASP.NET - PullRequest
6 голосов
/ 07 декабря 2011

Я новичок в C # и ASP.NET.

Я использую VS2005 C # и SQL Server 2005 и провел некоторые исследования по предотвращению SQL-инъекций

У меня есть несколько функций вмое серверное веб-приложение, которое, я не уверен, требует ли оно подтверждения ввода.


1) Вход элемент управления из панели инструментов,Я реализовал управление входом непосредственно из VS Toolbox и попытался использовать RegularExpressionValidator для моего инструмента входа, но, похоже, он не работает.У Microsoft уже есть встроенная проверка для инструмента?


2) Загрузка листов файлов Excel в базу данных SQL Server.У меня есть функция, которая позволяет пользователям загружать листы файлов Excel в базу данных.Вначале я не чувствую необходимости проверять его, так как нет открытых SQL-запросов, но после этого я спрашиваю себя, возможно ли пользователю ввести SQL-запросы в файл Excel, что приведет к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 сам заявляет, не создавая дополнительных методов и функций , к приведенным выше примерам, как я видел regular expression и используя mysql_real_escape_string.

Заранее благодарим вас за любые предоставленные советы и предложения.

Неплохо было бы привести и прямые примеры.

Ответы [ 3 ]

11 голосов
/ 07 декабря 2011

Проверка (проверка таких вещей, как кавычки и т. Д.) никогда не требуется в этих примерах и никогда не должна использоваться (за исключением нескольких случаев, когда может пригодиться белый список).

Требуется параметризация . Используйте параметры вместо конкатенации.

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 + "%"

2 голосов
/ 07 декабря 2011

Создайте SqlCommand и передайте данные, поскольку SqlParameter выполнит задачу за вас

MSDN: SqlCommand.Parameters Свойство

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);
        }
    }
}
1 голос
/ 07 декабря 2011

Самый простой способ - ввести параметры в команду sql вместо прямой передачи. .Net и Sql позаботятся о передаваемых типах данных, если вы передадите значения через параметры.

Например, см. Следующее:

SelectCommand.CommandText = "Select * From [UserData] where ColumnValue like  @RowValue";
SelectCommand.Parameters.AddWithValue("@RowValue","% ActualRowValue %");

Вы можете добавить параметры, используя разметку. Обратитесь к команде asp: SqlDataSource select с параметрами

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...