Как я могу избежать атак SQL-инъекций?

Вчера я говорил с разработчиком, и он упомянул что-то об ограничении вставки в поле базы данных, например, строки, такие как -- (минус минус).

В том же типе я знаю, что это хороший подход к удалению HTML-символов, таких как <, > и т.д. Не --. Это правда? Должен ли я беспокоиться о --, ++? Это больше похоже на миф или старые вещи?


Update

Большое спасибо за все ответы, это легко понять, потому что я немного новичок в этом. Ну, точнее, в этом случае наше обсуждение было посвящено и веб-сайту С# ASP.NET MVC, который мы разрабатываем, поэтому там есть сложная форма регистрации с важной информацией, поэтому я не уверен, использует ли MVC Linq для интерфейс с базой данных уже поставляется с такой защитой или нет. Поэтому, если кто-то может дать некоторые намеки на это, было бы здорово. Еще раз спасибо

Ответ 1

Правильный способ избежать атак SQL Injection - это не просто запретить некоторые пробные символы, а скорее использовать параметризованный SQL. Здесь вы можете найти хорошие статьи по теме параметризированного SQL:

http://www.codinghorror.com/blog/archives/000275.html

http://www.codeproject.com/KB/database/ParameterizingAdHocSQL.aspx

Теперь, когда вы упомянули, что работаете с ASP.net, я могу дать вам некоторые ссылки, которые специально посвящены SQL Injection в ASP.

http://en.csharp-online.net/ASP.NET_Security_Hacks%E2%80%94Avoiding_SQL_Injection http://www.codeproject.com/KB/aspnet/SQL_Injection_.aspx?msg=3209511

Вот более общая статья о том, как сделать ваш ASP более безопасным: http://www.codeproject.com/KB/web-security/Securing_ASP_NET_Apps.aspx

И, конечно, статья MSDN по SQL-инъекции: http://msdn.microsoft.com/en-us/library/ms998271.aspx

Ответ 2

SQL-инъекция представляет собой высокий риск для безопасности большинства веб-сайтов, которые позволяют пользователям скручивать параметры в оператор, который выполняется в базе данных.

Простым примером может быть:

Поле ввода "Имя: _________

"SELECT * FROM tblCustomer WHERE Name = '" + nameInputField + "'"

Итак, если я набираю "Боб", мы имеем

"SELECT * FROM tblCustomer WHERE Name = 'Bob'"

Но если я наберу "'; DROP TABLE tblCustomer", мы получим более зловещий

"SELECT * FROM tblCustomer WHERE Name = ''; DROP TABLE tblCustomer"

Существует множество способов избежать этих проблем, и многие из них встроены в любой язык, который вы используете, поэтому вместо того, чтобы думать обо всех хитроумных возможностях ";", "-", "/*" и т.д., попробуйте и используйте то, что уже существует.

Выскажите, какой язык вы используете, и я уверен, что мы можем сказать вам, как избежать этих атак.

Ответ 3

Он говорил о атаке SQL Injection, что совершенно правильно в том, что он сказал.

Проблема заключается не в таких данных, существующих в базе данных, а в передаче входных данных непосредственно в базу данных без их очистки.

Не очищая его, если кто-то переходит в строку, заканчивающуюся на ;, они могут последовать за ней тем, что они хотят (select * from sys.objects, например) или что-то более злонамеренное, например, отбрасывание некоторых таблиц.

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

Храните как можно больше -- в своей базе данных, но не передавайте это через вашу базу данных, не проходя процесс очистки (здесь важна хорошая библиотека БД - она ​​должна содержать кавычки и другие потенциально опасные вход).

Ответ 4

Нет ничего опасного в том, что вы вставляете строку, содержащую -- в базу данных.

Опасно вставлять что-либо в таблицу базы данных, которая поступает непосредственно из пользовательского ввода без его обработки, в противном случае вы оставите себя открытым для атаки SQL-инъекций. Пример. Кодер позволяет пользователю вводить свое имя в поле, а пользователь вводит:

Joe '); drop table users; commit transaction; --

а затем кодер помещает это в свою базу данных MySQL так:

conn.execute("insert into users (username) values ('" + userInput + "')");

Boom Пользователь удалил таблицу пользователей (при условии, что логин базы данных имеет права делать это, а это не должно, но это другая тема), поскольку кодер не обеспечивал что строка от пользователя была экранирована правильно, и поэтому она была отправлена ​​непосредственно в механизм БД, и злоумышленник посмеется.: -)

Используйте любые инструменты, обеспечиваемые вашей средой, чтобы обеспечить правильное экранирование строк. Например, JDBC использует для этого класс PreparedStatement. Большинство сред будут иметь что-то подобное.

Ответ 5

Использовать параметризованные запросы. Эти запросы представляют переменные в качестве заполнителя в SQL, например select * from person where name = ?. После создания SQL-запроса вы устанавливаете значения параметров в запросе. Параметрированные запросы гарантируют, что все, что было заменено заполнителем, не будет считаться частью инструкции SQL.

См. статью Джеффа Этвуда для хорошего обзора параметризованных запросов.

Ответ 6

Это не опасно, если вы правильно избегаете данных при выполнении INSERT/UPDATE/...

И экранирование HTML-символов НЕ - хороший подход. Представьте, что вы написали функцию, которая ускользает от таких символов, и вы сохранили некоторый экранированный текст в базе данных. Затем вы заметите, что ваша функция не удаляла '<', поэтому вы меняете функцию... теперь, что происходит с записями, которые уже находятся в базе данных? - Их '<' символы остаются неизмененными. Таким образом, НИКОГДА избегать текста перед сохранением его в базе данных (конечно, сбежать от SQL-запроса). Экранирование должно происходить, когда страница HTML/XML/... создается из текста, то есть после запроса исходного текста из базы данных!

Ответ 7

Попробуйте экранировать символы Это особенно относится к тем, кто использует процедурный php, применяет некоторые real_escape_string при проверке из таблицы базы данных, например

$a = $_POST['username'];
$b = $_POST['password'];

$c = mysqli_query($cone, "select * from member where (username = '".mysqli_real_escape_string($cone, $a)."' && password = '".mysqli_real_escape_string($cone,$b)."')");
if(mysqli_num_rows($c)==1){
    $_SESSION['username'] = $a;
    header("Location:member.php");
    exit();
}else{
    $unam_error = "Wrong Username or password";
}