Интернет магазин китайских планшетных компьютеров



Компьютеры - Внедрение SQL-кода - Защита от атак типа внедрение SQL-кода

23 января 2011


Оглавление:
1. Внедрение SQL-кода
2. Методика атак типа внедрение SQL-кода
3. Защита от атак типа внедрение SQL-кода



Для защиты от данного типа атак необходимо тщательно фильтровать входные параметры, значения которых будут использованы для построения SQL-запроса.

Фильтрация строковых параметров

Предположим, что код, генерирующий запрос, выглядит так:

statement := 'SELECT * FROM users WHERE name = "' + userName + '";';

Чтобы внедрение кода было невозможно, для некоторых СУБД, в том числе, для MySQL, требуется брать в кавычки все строковые параметры. В самом параметре заменяют кавычки на \", апостроф на \', обратную косую черту на \\. Это можно делать таким кодом:

statement := 'SELECT * FROM users WHERE name = ' + QuoteParam + ';';
function QuoteParam : string;
{ на входе — строка; на выходе — строка в кавычках и с заменёнными спецсимволами }
var
  i : integer;
  Dest : string;
begin
  Dest := '"';
  for i:=1 to length do
    case s of
      '''' : Dest := Dest + '\''';
      '"' : Dest := Dest + '\"';
      '\' : Dest := Dest + '\\';
    else Dest := Dest + s;
    end; 
  QuoteParam := Dest + '"';
end;

Для PHP фильтрация может быть такой:

<?
$query = "SELECT * FROM users WHERE user='".mysql_real_escape_string."';";
?>

Фильтрация целочисленных параметров

Возьмём другой запрос:

statement := 'SELECT * FROM users WHERE id = ' + id + ';';

В данном случае поле id имеет числовой тип, и его нельзя брать в кавычки. Поэтому «закавычивание» и замена спецсимволов на escape-последовательности не проходит. В таком случае помогает проверка типа; если переменная id не является числом, запрос вообще не должен выполняться.

Например, на Delphi для противодействия таким инъекциям помогает код:

 id_int := StrToInt;
 statement := 'SELECT * FROM users WHERE id = ' + IntToStr + ';';

В случае ошибки функция StrToInt вызовет исключение EConvertError, и в его обработчике можно будет вывести сообщение об ошибке. Двойное преобразование обеспечивает корректную реакцию на числа в формате $132AB. На стандартном Паскале, не умеющем обрабатывать исключения, код несколько сложнее.

Для PHP этот метод будет выглядеть так:

 $query = 'SELECT * FROM users WHERE id = ' .  $id;

Усечение входных параметров

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

Например, если известно, что поле id в вышеприведённых примерах может принимать значения не более 9999, можно «отрезать лишние» символы, оставив не более четырёх:

statement := 'SELECT * FROM users WHERE id = ' + LeftStr + ';';

Использование параметризованных запросов

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

  • на Delphi — свойство TQuery.Params;

Например

var
  sql, param : string;
begin
  sql := 'select :text as value from dual';
  param := 'alpha';  
  Query1.Sql.Text := sql;
  Query1.ParamByName.AsString := param;
  Query1.Open;
  ShowMessage;  
end;
  • на Perl — через DBI::quote или DBI::prepare;
  • на Java — через класс PreparedStatement;
  • на C# — свойство SqlCommand.Parameters;
  • на PHP — MySQLi, PDO.
  • на Parser — язык сам предотвращает атаки подобного рода.


Просмотров: 3720


<<< Аналитические функции (SQL)
Курсор (базы данных) >>>