В комментарии к предыдущему вопросу кто-то сказал, что следующий оператор 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 правильно экранирована, как это делает меня уязвимым и что я могу сделать, чтобы это исправить?






Если от него правильно ускользнуть, это не сделает вас уязвимым. Дело в том, что правильно сбежать сложнее, чем кажется на первый взгляд, и вы обрекаете себя на правильное побег каждый раз, когда выполняете подобный вопрос. Если возможно, избегайте всех этих проблем и используйте подготовленные операторы (или связанные параметры или параметризованные запросы). Идея состоит в том, чтобы позволить библиотеке доступа к данным правильно экранировать значения.
Например, в 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();
Каждая библиотека интерфейса SQL, которую стоит использовать, имеет какую-то поддержку для параметров привязки. Не пытайтесь быть умным, просто используйте это.
Вы можете действительно, действительно думать / надеяться, что вы избежали вещей как следует, но это просто не стоит того времени, которое вы не делаете.
Кроме того, несколько баз данных поддерживают кэширование подготовленных операторов, поэтому правильное его выполнение также может повысить эффективность.
Легче, безопаснее, быстрее.
+1 Потому что привязка - это «настоящий и профессиональный» ответ на такого рода вопросы.
Это утверждение как таковое на самом деле не проблема, оно «безопасно», однако я не знаю, как вы это делаете (на один уровень выше в стеке API). Если $ user_id вставляется в оператор с использованием строковых операций (например, если вы позволяете Php автоматически заполнять оператор), то это опасно.
Если он заполняется с помощью API привязки, то вы готовы к работе.
Если он правильно экранирован и проверен, у вас нет проблем.
Проблема возникает, когда она не экранирована или не проверена должным образом. Это могло произойти из-за небрежного кодирования или недосмотра.
Проблема не в конкретных экземплярах, а в шаблоне. Этот шаблон делает возможной SQL-инъекцию, в то время как другой шаблон делает это невозможным.
Если $ user_id экранирован, вы не должны быть уязвимы для SQL-инъекции.
В этом случае я бы также убедился, что $ user_id является числовым или целым числом (в зависимости от точного требуемого типа). Вы всегда должны ограничивать данные наиболее строгим типом, который вы можете.
Если бы он был уверен, что $ user_id является числовым, ему не понадобились бы одинарные кавычки вокруг интерполированного значения в его SQL.
Я прочитал это как использование строк в одинарных, а не в двойных кавычках, отсюда и конкатенация.
Все ответы хороши и верны, но я чувствую, что должен добавить, что парадигма prepare / execute также не является решением Только. У вас должен есть уровень абстракции базы данных, а не использование библиотечных функций напрямую, и такой уровень является хорошим местом для явного экранирования строковых параметров, независимо от того, позволяете ли вы это делать prepare или делаете это самостоятельно.
Уровни абстракции базы данных переоценены. И в любом случае важна парадигма подготовки / выполнения, независимо от того, выполняется ли это с помощью DAL или непосредственно на уровне конкретной базы данных.
Я мог бы ответить, полагая, что подготовка / выполнение чрезмерно раздута. :-) Хороший DAL похож на любой другой слой абстракции: достаточно толстый, чтобы быть полезным, но не настолько тонкий, чтобы просто переименовывать функции.
Я думаю, что «правильно экранированный» - вот ключевое слово. В вашем последний вопрос я предполагаю, что ваш код скопирован из вашего производственного кода, и, поскольку вы задали вопрос о соединении трех таблиц, я также предполагаю, что вы не выполнили надлежащее экранирование, поэтому мое замечание о SQL Инъекционная атака.
Чтобы ответить на ваш вопрос, как многие здесь описали, ЕСЛИ переменная была «правильно экранирована», тогда у вас нет проблем. Но зачем этим заниматься? Как отмечали некоторые люди, иногда правильный побег - непростая задача. В PHP есть шаблоны и библиотеки, которые делают SQL-инъекцию невозможной, почему бы нам просто не использовать это? (Я также намеренно предполагаю, что ваш код на самом деле является PHP). Винко Врсалович отвечать может дать вам идеи о том, как подойти к этой проблеме.
Вам следует рассмотреть возможность использования параметров привязки. Кажется, вы в порядке, но вы не можете быть уверены, что следующий разработчик, работающий над этим, не добавит еще одну переменную ранее в запрос, где она более уязвима.