Санитарная обработка данных SQL - PullRequest
10 голосов
/ 13 августа 2010

Google ведет всевозможные дискуссии по очистке запросов для доступа в Интернет, но я не нахожу ничего, что касалось бы того, что меня беспокоило:

Очистка входных данных пользователя в программе на c #. Это должно быть сделано обратимым преобразованием, а не удалением. В качестве простого примера проблемы я не хочу искажать ирландские имена.

Каков наилучший подход, и есть ли какая-нибудь библиотечная функция, которая это делает?

Ответы [ 2 ]

9 голосов
/ 14 августа 2010

Это зависит от того, какую базу данных SQL вы используете. Например, если вам нужен литерал с одинарными кавычками в MySQL, вам нужно использовать обратную косую черту, Dangerous: ' и экранированный литерал с символом экранирования: \'. Для MS-SQL все совершенно иначе, Опасно: ' экранировано: ''. Ничего не удаляется, когда вы экранируете данные таким способом, это способ представления управляющего символа, такого как кавычка, в его буквальной форме.

Вот пример использования параметризованных запросов для MS-SQL и C #, взятых из Документов :

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);
        }
    }
}

Для MySQL я не знаю о параметризованной библиотеке запросов, которую вы можете использовать. Вы должны использовать mysql_real_escape_string () или, если хотите, вы можете использовать эту функцию .:

public static string MySqlEscape(this string usString)
{
    if (usString == null)
    {
        return null;
    }
    // SQL Encoding for MySQL Recommended here:
    // http://au.php.net/manual/en/function.mysql-real-escape-string.php
    // it escapes \r, \n, \x00, \x1a, baskslash, single quotes, and double quotes
    return Regex.Replace(usString, @"[\r\n\x00\x1a\\'""]", @"\$0");
}
0 голосов
/ 13 августа 2010

Используйте правильно сконструированный DAL с объектами параметров SQL, передаваемых хранимым процедурам, и вам не нужно об этом беспокоиться. Реализуйте бизнес-объекты и dal, чтобы абстрагировать пользовательский ввод настолько, чтобы он не выполнялся как SQL, а распознавался как значения. примеры забавны:

public class SomeDal
{
    public void CreateUser(User userToBeCreated)
    {
        using(connection bla bla)
        {
            // create and execute a command object filling its parameters with data from the User object
        }
    }
}

public class User
{
    public string Name { get; set; }
    ...
}

public class UserBL
{
    public CreateUser(User userToBeCreated)
    {
        SomeDal myDal = new SomeDal();
        myDal.CreateUser(userToBeCreated);
    }
}

public class SomeUI
{
    public void HandleCreateClick(object sender, e ButtonClickEventArgs)
    {
        User userToBeCreated = new User() { Name = txtName.Text };
        UserBL userBl = new UserBL();
        userBl.CreateUser(userToBeCreated);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...