Подтвердить что ты не робот

Как я могу защитить от атак SQL-инъекций с помощью Perl DBI?

Есть ли функция, которую я могу использовать в Perl для дезинфекции ввода, прежде чем поместить его в базу данных MySQL? Я не знаю регулярное выражение очень хорошо, поэтому, прежде чем я сделаю свою собственную функцию, я задавался вопросом, было ли уже сделано.

4b9b3361

Ответ 1

Правильный способ дезинфекции данных для вставки в вашу базу данных - использовать placeholders для всех переменных, которые будут вставлены в ваши строки SQL. Другими словами, НИКОГДА не делайте этого:

my $sql = "INSERT INTO foo (bar, baz) VALUES ( $bar, $baz )";

Вместо этого используйте ? заполнители:

my $sql = "INSERT INTO foo (bar, baz) VALUES ( ?, ? )";

И затем передайте переменные, которые нужно заменить при выполнении запроса:

my $sth = $dbh->prepare( $sql );
$sth->execute( $bar, $baz );

Вы можете комбинировать эти операции с некоторыми удобными методами DBI; выше также можно написать:

$dbh->do( $sql, undef, $bar, $baz );

Подробнее см. DBI docs.

Ответ 2

Незначительное (и, по общему признанию, педантичное) дополнение к ответам "использование заполнителей": параметризованные запросы не являются, строго говоря, "дезинфекцией". Они не изменяют данные каким-либо образом, чтобы сделать их безопасными. Вместо этого они защищают от SQL-инъекции, отправляя структуру запроса (команды) и данные по отдельным каналам.

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

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

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

И обязательная ссылка: http://bobby-tables.com/ содержит примеры использования параметризованных запросов на нескольких разных языках, включая Perl.

Ответ 3

Как вы называете базу данных?

DBI поддерживает записи с помощью placeholders. Оба DBIx::Class и Rose::DB::Object санировать значения автоматически, если вы используете метод "find", предоставляемый каждой библиотекой.

Ответ 4

В очень редких случаях вы не можете использовать заполнители, как описано в других ответах. Но даже в таком редком случае вы не должны вмешиваться в данные сами, так как это создает потенциальную ошибку. Лучше использовать методы DBI quote и quote_identifier. Кроме того, это делает ваш код менее зависимым от конкретной РСУБД.

Отказ от ответственности. Ниже приведен фиктивный пример и не предназначен для иллюстрации очень редкого случая, о котором я говорил.

$dbh->do('INSERT INTO ' . $dbh->quote_identifier($table) . ' (id, name) VALUES '
    '(NULL, ' . $dbh->quote($name) . ')');

Ответ 5

Ответ: используйте SQL-заполнители (?).

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