Каждый ответ здесь охватывает только часть проблемы. На самом деле существует четыре разных части запроса, которые мы можем добавить к ней динамически:
и подготовленные операторы охватывают только 2 из них
. Но иногда нам приходится делать наш запрос еще более динамичным, добавляя операторы или идентификаторы также. Таким образом, нам понадобятся разные методы защиты.
В целом такой подход защиты основан на whitelisting . В этом случае каждый динамический параметр должен быть жестко закодирован в вашем скрипте и выбран из этого набора. Например, для динамического упорядочения:
$orders = array("name","price","qty"); //field names
$key = array_search($_GET['sort'],$orders)); // see if we have such a name
$orderby = $orders[$key]; //if not, first one will be set automatically. smart enuf :)
$query = "SELECT * FROM `table` ORDER BY $orderby"; //value is safe
Однако есть еще один способ защитить идентификаторы - экранирование. Пока вы указываете идентификатор, вы можете избежать обратных звонков внутри, удвоив их.
В качестве еще одного шага мы можем заимствовать поистине блестящую идею использования некоторого заполнителя (прокси для представления фактического значения в запросе) из подготовленных операторов и изобретать местозаполнитель другого типа - заполнителя идентификатора .
Итак, чтобы сделать длинный рассказ коротким: это заполнитель, не подготовленное заявление можно рассматривать как серебряную пулю.
Итак, общая рекомендация может быть сформулирована так: Пока вы добавляете динамические части запроса с использованием заполнителей (и эти заполнители правильно обрабатываются, конечно), вы можете быть уверены, что ваш запрос безопасен.
Тем не менее, есть проблема с ключевыми словами синтаксиса SQL (например, AND
, DESC
и т. д.), но белый список - единственный подход в этом случае.
Несмотря на то, что существует общее согласие в отношении наилучшей практики защиты SQL-инъекций, все еще существует множество плохих методов. И некоторые из них слишком глубоко укоренены в умах пользователей PHP. Например, на этой самой странице есть (хотя и невидимые для большинства посетителей) более 80 удаленных ответов - все они удалены сообществом из-за плохого качества или продвижения плохих и устаревших практик. Хуже того, некоторые из плохих ответов не удаляются, а скорее процветают.
Например, там (1) являются (2) еще (3) many (4) отвечает (5) , в том числе второй наиболее ответный ответ , предлагающий вам ручное стирание строки - устаревший подход, который оказался небезопасным.
Или есть несколько лучший ответ, который предлагает только другой метод форматирования строк и даже может похвастаться им как окончательной панацеей. Хотя, конечно, это не так. Этот метод не лучше обычного форматирования строки, но он сохраняет все свои недостатки: он применим только к строкам и, как и любое другое ручное форматирование, по существу является необязательной, необязательной мерой, склонной к человеческой ошибке любого рода.
Я думаю, что все это из-за одного очень старого суеверия, поддержанного такими авторитетами, как OWASP или PHP manual , который провозглашает равенство между тем, что «ускользает» "и защита от SQL-инъекций.
Независимо от того, что написано в руководстве по PHP, *_escape_string
ни в коем случае не делает данные безопасными и никогда не предназначались. Помимо бесполезности для любой части SQL, отличной от строки, ручное экранирование неверно, поскольку оно является ручным, как автоматическое.
И OWASP делает это еще хуже, подчеркивая, что пользовательский вход пользователя является совершенно бессмысленным: таких слов в контексте защиты от инъекций не должно быть. Каждая переменная потенциально опасна - независимо от источника! Или, другими словами, каждая переменная должна быть должным образом отформатирована для включения в запрос - независимо от источника. Это вопрос назначения. В тот момент, когда разработчик начинает отделять овец от коз (думая, является ли какая-то конкретная переменная «безопасной» или нет), он делает свой первый шаг к катастрофе. Не говоря уже о том, что даже формулировка предполагает, что в точке входа происходит массовое ускорение, напоминающее очень волшебную функцию кавычек - уже презренный, устаревший и удаленный.
Итак, в отличие от любого «экранирования» подготовленные операторы мера, которая действительно защищает от SQL-инъекции (если применимо).
Если вы все еще не уверены, вот пошаговое объяснение, которое я написал, The Hitchhiker's Guide на SQL Injection Prevention , где я подробно объяснил все эти вопросы и даже составил раздел, полностью посвященный плохим практикам и их раскрытию.
Никакой , не безопасно звонить delete
на выделенной стеку переменной. Необходимо только звонить delete
на вещах созданный new
.
malloc
или calloc
, должен быть точно один free
. new
должен быть точно один delete
. new[]
должен быть точно один delete[]
. В целом, Вы не можете смешивание и подгонка ни один из них, например, никакого free
- луг или delete[]
- луг new
объект. Выполнение так приводит к неопределенному поведению.
Ну, давайте попробуем его:
jeremy@jeremy-desktop:~$ echo 'main() { int a; delete &a; }' > test.cpp
jeremy@jeremy-desktop:~$ g++ -o test test.cpp
jeremy@jeremy-desktop:~$ ./test
Segmentation fault
Так, по-видимому, это не безопасно вообще.
Следует иметь в виду, что при выделении блока памяти, использующей новый (или malloc в этом отношении) фактический блок выделенной памяти будет больше, чем, что Вы попросили. Блок памяти будет также содержать некоторую бухгалтерскую информацию так, чтобы при освобождении блока это могло легко быть отложено в свободный пул и возможно объединено со смежными свободными блоками.
, Когда Вы пытаетесь освободить любую память, которую Вы не получили от нового, та бухгалтерская информационная привычка быть там, но система будет действовать как он, и результаты будут непредсказуемыми (обычно плохо).
Нет, Память выделила новое использование, должен быть удален с помощью оператора delete, и это выделило использование malloc, должен быть удален с помощью свободного. И никакая потребность освободить переменную, которые выделяются на стеке.
здесь память выделяется с помощью стека так никакая потребность удалить его exernally, но если у Вас есть allcoted динамично
как интервал *a=new интервал ()
тогда, необходимо сделать, удаляют a и не удаляют & (самостоятельно указатель), потому что память выделяется от свободного хранилища.