Как этот запрос MySQL уязвим для SQL-инъекций? - PullRequest
4 голосов
/ 25 ноября 2008

В комментарии к предыдущему вопросу кто-то сказал, что следующее SQL-выражение открывает мне возможность ввода SQL-кода:

select
    ss.*,
    se.name as engine,
    ss.last_run_at + interval ss.refresh_frequency day as next_run_at,
    se.logo_name    
from 
    searches ss join search_engines se on ss.engine_id = se.id
where
    ss.user_id='.$user_id.'
group by ss.id
order by ss.project_id, ss.domain, ss.keywords

Предполагая, что переменная $userid правильно экранирована, как это делает меня уязвимым и что я могу сделать, чтобы это исправить?

Ответы [ 7 ]

14 голосов
/ 25 ноября 2008

Каждая библиотека интерфейса SQL, которую стоит использовать, имеет некоторую поддержку параметров привязки. Не пытайся быть умным, просто используй это.

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

Кроме того, некоторые базы данных поддерживают подготовленное кэширование операторов, поэтому правильное выполнение этого может также повысить эффективность.

Легче, безопаснее, быстрее.

5 голосов
/ 25 ноября 2008

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

Например, в PHP, используя mysqli :

$db_connection = new mysqli("localhost", "user", "pass", "db");
$statement = $db_connection->prepare("SELECT thing FROM stuff WHERE id = ?");
$statement->bind_param("i", $user_id); //$user_id is an integer which goes 
                                       //in place of ?
$statement->execute();
1 голос
/ 25 ноября 2008

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

Чтобы ответить на ваш вопрос, как описывалось здесь многими людьми, ЕСЛИ переменная была 'правильно выбрана', то у вас нет проблем. Но зачем беспокоиться, делая это? Как отмечали некоторые люди, иногда Правильное побег не является простым делом. В PHP есть шаблоны и библиотеки, которые делают SQL-инъекцию невозможной, почему бы нам просто не использовать это? (Я также сознательно делаю предположение, что ваш код на самом деле PHP). Винко Врсалович ответ может дать вам идеи о том, как решить эту проблему.

1 голос
/ 25 ноября 2008

Если экранировать $ user_id , то вы не должны быть уязвимы для SQL-инъекций.

В этом случае я бы также гарантировал, что $ user_id является числовым или целым числом (в зависимости от требуемого точного типа). Вы всегда должны ограничивать данные наиболее строгим типом, который вы можете.

1 голос
/ 25 ноября 2008

Если он правильно экранирован и проверен, то у вас нет проблем.

Проблема возникает, когда она не экранирована или не проверена должным образом. Это может произойти из-за небрежного кодирования или недосмотра.

Проблема не в конкретных случаях, а в шаблоне. Этот шаблон делает возможным внедрение SQL, а другой - невозможным.

0 голосов
/ 25 ноября 2008

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

0 голосов
/ 25 ноября 2008

Это утверждение как таковое на самом деле не является проблемой, оно «безопасно», однако я не знаю, как вы это делаете (на один уровень выше в стеке API). Если $ user_id вставляется в оператор с использованием строковых операций (как будто вы позволяете Php автоматически заполнять оператор), то это опасно.

Если его заполнить с помощью API привязки, значит, вы готовы к работе.

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