0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p>Заводишь сайт, наполняешь его контентом, запускаешь рекламную кампанию - трафик стабильно растет, пользователи активно комментируют и делятся статьями. Всё хорошо до того момента, пока в один не предвещающий беды день на сайте не оказывается ни одной статьи. Заходишь в лог запросов и видишь, что кто-то сделал DROP…</p>
1
<p>Заводишь сайт, наполняешь его контентом, запускаешь рекламную кампанию - трафик стабильно растет, пользователи активно комментируют и делятся статьями. Всё хорошо до того момента, пока в один не предвещающий беды день на сайте не оказывается ни одной статьи. Заходишь в лог запросов и видишь, что кто-то сделал DROP…</p>
2
<p>SQL-инъекция - это попытка изменить запрос к базе данных. Ввести ее можно через форму или ссылку, которая передает параметры методом GET. Представьте, что у вас на сайте есть форма регистрации, в которую пользователь вводит логин и пароль.</p>
2
<p>SQL-инъекция - это попытка изменить запрос к базе данных. Ввести ее можно через форму или ссылку, которая передает параметры методом GET. Представьте, что у вас на сайте есть форма регистрации, в которую пользователь вводит логин и пароль.</p>
3
<form action='reg.php' method='post'> <input type='text' name='login' placeholder='Логин' required><br> <input type='password' name='password' placeholder='Пароль' required><br> <input type='submit' value='Зарегистрироваться'> </form><p>Они отправляются на сервер и вставляются в запрос такого вида:</p>
3
<form action='reg.php' method='post'> <input type='text' name='login' placeholder='Логин' required><br> <input type='password' name='password' placeholder='Пароль' required><br> <input type='submit' value='Зарегистрироваться'> </form><p>Они отправляются на сервер и вставляются в запрос такого вида:</p>
4
$query = "INSERT INTO userlist (".$keys.“) VALUES (".$values.“)";<p>В переменной<em>$keys</em>содержатся ключи из супермассива<em>$_POST</em>, а в <em>$values</em> - значения:</p>
4
$query = "INSERT INTO userlist (".$keys.“) VALUES (".$values.“)";<p>В переменной<em>$keys</em>содержатся ключи из супермассива<em>$_POST</em>, а в <em>$values</em> - значения:</p>
5
$keys = ""; $values = ""; $first = 1; foreach($_POST as $key => $value) { if($first == 0) { //Добавляем запятую перед каждым пунктом, кроме первого $keys .= ","; $values .= ","; } $keys .= $key; $values .= "'".$value."'"; $first = 0; }<p>Это удобно, если в форме очень много полей, но из-за этого появляется уязвимость: если пользователь захочет запустить SQL-инъекцию, то он может просто создать в форме новое поле с нужным ему именем и ввести любое значение. Например, можно создать поле<em>admin</em>и ввести значение<em>1</em>.</p>
5
$keys = ""; $values = ""; $first = 1; foreach($_POST as $key => $value) { if($first == 0) { //Добавляем запятую перед каждым пунктом, кроме первого $keys .= ","; $values .= ","; } $keys .= $key; $values .= "'".$value."'"; $first = 0; }<p>Это удобно, если в форме очень много полей, но из-за этого появляется уязвимость: если пользователь захочет запустить SQL-инъекцию, то он может просто создать в форме новое поле с нужным ему именем и ввести любое значение. Например, можно создать поле<em>admin</em>и ввести значение<em>1</em>.</p>
6
<p>Если сайт плохо защищен, то хакер может совершить много попыток, но в итоге все же получить доступ к правам администратора.</p>
6
<p>Если сайт плохо защищен, то хакер может совершить много попыток, но в итоге все же получить доступ к правам администратора.</p>
7
<p>Прежде всего запомните, что безопасных систем не бывает, поэтому нужно постоянно искать уязвимости, которые могут быть у вашего сайта.</p>
7
<p>Прежде всего запомните, что безопасных систем не бывает, поэтому нужно постоянно искать уязвимости, которые могут быть у вашего сайта.</p>
8
<p>В примере выше нас бы спасло, если бы существовал белый список - нужно указать допустимые ключи и значения.</p>
8
<p>В примере выше нас бы спасло, если бы существовал белый список - нужно указать допустимые ключи и значения.</p>
9
$keys = ""; $values = ""; $first = 1; $allowed = array("login", "password", "email","nickname"); foreach($_POST as $key => $array) { $allowedKey = array_search($key,$allowed); if($allowedKey) { if($first == 0) { $keys .= ","; $values .= ","; } $keys .= $allowedKey; $values .= "'".$value."'"; $first = 0; } }<p>Теперь в переменные<em>$key</em>и<em>$values</em>попадут только те значения, которые входят в белый список<em>$allowed</em>.</p>
9
$keys = ""; $values = ""; $first = 1; $allowed = array("login", "password", "email","nickname"); foreach($_POST as $key => $array) { $allowedKey = array_search($key,$allowed); if($allowedKey) { if($first == 0) { $keys .= ","; $values .= ","; } $keys .= $allowedKey; $values .= "'".$value."'"; $first = 0; } }<p>Теперь в переменные<em>$key</em>и<em>$values</em>попадут только те значения, которые входят в белый список<em>$allowed</em>.</p>
10
<p>Передавать переменные этим способом очень опасно, потому что они оказываются на виду у пользователей. Если информация важная, то лучше используйте POST. Из ссылки злоумышленник может узнать не только имена переменных, но и какие значения должны быть в них - так он сможет выбрать оптимальную переменную для ввода инъекции.</p>
10
<p>Передавать переменные этим способом очень опасно, потому что они оказываются на виду у пользователей. Если информация важная, то лучше используйте POST. Из ссылки злоумышленник может узнать не только имена переменных, но и какие значения должны быть в них - так он сможет выбрать оптимальную переменную для ввода инъекции.</p>
11
<p>Не советуем использовать переменные прямиком из супермассива - лучше поместить их в другую переменную, предварительно проверив данные.</p>
11
<p>Не советуем использовать переменные прямиком из супермассива - лучше поместить их в другую переменную, предварительно проверив данные.</p>
12
<p>Старайтесь экранировать кавычки, заменять служебные символы, удалять лишние пробелы и так далее. Давайте посмотрим, что будет, если этого не делать:</p>
12
<p>Старайтесь экранировать кавычки, заменять служебные символы, удалять лишние пробелы и так далее. Давайте посмотрим, что будет, если этого не делать:</p>
13
<p>Используйте функции trim (убирает лишние пробелы), htmlspecialchars (заменяет треугольные скобки и другие спецсимволы), addslashes (экранирует кавычки и специальные символы) и другие.</p>
13
<p>Используйте функции trim (убирает лишние пробелы), htmlspecialchars (заменяет треугольные скобки и другие спецсимволы), addslashes (экранирует кавычки и специальные символы) и другие.</p>
14
<p>В приведенной форме регистрации, например, злоумышленник мог бы использовать кавычки и запятые, чтобы добавить новый ключ и новое значение. То есть, введя в поле что-то вроде "pass’, ’something", он бы добавил какую-нибудь еще информацию, которая не проходит белый список.</p>
14
<p>В приведенной форме регистрации, например, злоумышленник мог бы использовать кавычки и запятые, чтобы добавить новый ключ и новое значение. То есть, введя в поле что-то вроде "pass’, ’something", он бы добавил какую-нибудь еще информацию, которая не проходит белый список.</p>
15
<p>Также вы можете проверять типы переменных - число, строка, файл и так далее.</p>
15
<p>Также вы можете проверять типы переменных - число, строка, файл и так далее.</p>
16
<p>Недостаточно просто обработать данные - нужно узнать, откуда они пришли. Отследить источник можно несколькими способами:</p>
16
<p>Недостаточно просто обработать данные - нужно узнать, откуда они пришли. Отследить источник можно несколькими способами:</p>
17
<ul><li>проверять его в <em>$_SERVER[’HTTP_REFERER’]</em>;</li>
17
<ul><li>проверять его в <em>$_SERVER[’HTTP_REFERER’]</em>;</li>
18
<li>создать скрытое поле в форме;</li>
18
<li>создать скрытое поле в форме;</li>
19
<li>указать имя формы;</li>
19
<li>указать имя формы;</li>
20
<li>указать имя кнопки отправки и так далее.</li>
20
<li>указать имя кнопки отправки и так далее.</li>
21
</ul><p>Конечно, это лишь незначительный бонус к защите, но зато он отсеивает часть неопытных взломщиков, которые бросят свои потуги после нескольких попыток.</p>
21
</ul><p>Конечно, это лишь незначительный бонус к защите, но зато он отсеивает часть неопытных взломщиков, которые бросят свои потуги после нескольких попыток.</p>
22
<p>С помощью PDO и плейсхолдеров можно значительно снизить риск инъекции, потому что данные и запрос отправляются отдельно. Сначала производится подключение к базе, потом подготавливается запрос, затем отдельно указываются переменные, и, наконец, запрос выполняется. Выглядит это так:</p>
22
<p>С помощью PDO и плейсхолдеров можно значительно снизить риск инъекции, потому что данные и запрос отправляются отдельно. Сначала производится подключение к базе, потом подготавливается запрос, затем отдельно указываются переменные, и, наконец, запрос выполняется. Выглядит это так:</p>
23
$db = new PDO('mysql:host=localhost;dbname=test', $user, $pass); $stmt = $db->prepare("SELECT * FROM articles WHERE id=':id'"); $stmt->bindParam(':id', $id); $stmt->execute();<p>Данные отправляются уже в виде переменных. То есть если бы в переменной кто-то поставил лишнюю кавычку, сервер бы не подумал, что она - часть запроса. Поэтому попытка испортить запрос через переменную не сработала бы.</p>
23
$db = new PDO('mysql:host=localhost;dbname=test', $user, $pass); $stmt = $db->prepare("SELECT * FROM articles WHERE id=':id'"); $stmt->bindParam(':id', $id); $stmt->execute();<p>Данные отправляются уже в виде переменных. То есть если бы в переменной кто-то поставил лишнюю кавычку, сервер бы не подумал, что она - часть запроса. Поэтому попытка испортить запрос через переменную не сработала бы.</p>
24
<p>Этот способ, пожалуй, эффективнее остальных, поэтому переходите на PDO как можно скорее. Хотя его использование не означает, что другие меры безопасности уже не нужны - чем больше защитных механизмов вы установите, тем сохраннее будет информация.</p>
24
<p>Этот способ, пожалуй, эффективнее остальных, поэтому переходите на PDO как можно скорее. Хотя его использование не означает, что другие меры безопасности уже не нужны - чем больше защитных механизмов вы установите, тем сохраннее будет информация.</p>
25
<p>Часто проверками пренебрегают самоучки, которые изучают темы "по верхушкам", - они могут решить задачу, но редко задумываются о том, чтобы устранить уязвимости. Поэтому мы предлагаем курс с системным обучением - вы научитесь создавать эффективные и надежные системы, которым не будут страшны инъекции и утечки данных.</p>
25
<p>Часто проверками пренебрегают самоучки, которые изучают темы "по верхушкам", - они могут решить задачу, но редко задумываются о том, чтобы устранить уязвимости. Поэтому мы предлагаем курс с системным обучением - вы научитесь создавать эффективные и надежные системы, которым не будут страшны инъекции и утечки данных.</p>
26
<p>Кроме того, чтобы обезопасить сам запрос и переменные, нужно сделать всё, чтобы хакер не смог найти уязвимости. Для этого устраните все возможные дыры, из-за которых может появиться утечка информации и вероятность несанкционированного доступа к правам администратора.</p>
26
<p>Кроме того, чтобы обезопасить сам запрос и переменные, нужно сделать всё, чтобы хакер не смог найти уязвимости. Для этого устраните все возможные дыры, из-за которых может появиться утечка информации и вероятность несанкционированного доступа к правам администратора.</p>
27
<p>Все файлы на сайте можно открыть или скачать, если знать их адрес. Например, можно попытаться скачать файл header.php, чтобы найти там уязвимости (если скачивание будет удачным).</p>
27
<p>Все файлы на сайте можно открыть или скачать, если знать их адрес. Например, можно попытаться скачать файл header.php, чтобы найти там уязвимости (если скачивание будет удачным).</p>
28
<p>Поэтому лучше все подключаемые файлы переместить в отдельную директорию и запретить к ней прямой доступ. Например, можно создать папку includes и поместить туда:</p>
28
<p>Поэтому лучше все подключаемые файлы переместить в отдельную директорию и запретить к ней прямой доступ. Например, можно создать папку includes и поместить туда:</p>
29
<ul><li>отдельные блоки сайта;</li>
29
<ul><li>отдельные блоки сайта;</li>
30
<li>библиотеки пользовательских функций;</li>
30
<li>библиотеки пользовательских функций;</li>
31
<li>файл подключения к базе данных;</li>
31
<li>файл подключения к базе данных;</li>
32
<li>обработчики форм и так далее.</li>
32
<li>обработчики форм и так далее.</li>
33
</ul><p>Для этого создайте в этой папке файл<em>.htaccess</em>и добавьте туда такую строчку:</p>
33
</ul><p>Для этого создайте в этой папке файл<em>.htaccess</em>и добавьте туда такую строчку:</p>
34
<p>Прямой доступ заблокируется, но подключать эти файлы через PHP все еще будет можно.</p>
34
<p>Прямой доступ заблокируется, но подключать эти файлы через PHP все еще будет можно.</p>
35
<p>Порой нам всем бывает нужна помощь коллег, поэтому мы выкладываем фрагменты своего кода на форумы или Stackoverflow. Делать это рекомендуется только в очень крайних случаях и лишь тогда, когда вы убедитесь, что никто не сможет вычислить ваш сайт.</p>
35
<p>Порой нам всем бывает нужна помощь коллег, поэтому мы выкладываем фрагменты своего кода на форумы или Stackoverflow. Делать это рекомендуется только в очень крайних случаях и лишь тогда, когда вы убедитесь, что никто не сможет вычислить ваш сайт.</p>
36
<p>Ничто не должно намекать на то, какой тематики сайт, какой у него адрес, на каком он хостинге и так далее. Чем больше информации вы добровольно расскажете, тем выше риск быть взломанным.</p>
36
<p>Ничто не должно намекать на то, какой тематики сайт, какой у него адрес, на каком он хостинге и так далее. Чем больше информации вы добровольно расскажете, тем выше риск быть взломанным.</p>
37
<p>Всегда проверяйте код, который вы копируете, - в нем может быть какой-то незаметный эксплойт, который навредит вашему сайту или позволит автору кода получить к нему доступ. Старайтесь хотя бы читать то, что вы вставляете. Даже если там всего одна строчка, ее может быть достаточно, чтобы создать брешь в вашей защите.</p>
37
<p>Всегда проверяйте код, который вы копируете, - в нем может быть какой-то незаметный эксплойт, который навредит вашему сайту или позволит автору кода получить к нему доступ. Старайтесь хотя бы читать то, что вы вставляете. Даже если там всего одна строчка, ее может быть достаточно, чтобы создать брешь в вашей защите.</p>
38
<p>В идеале лучше вручную переписывать код - так вы точно заметите все подозрительные команды.</p>
38
<p>В идеале лучше вручную переписывать код - так вы точно заметите все подозрительные команды.</p>
39
<p>Вывод ошибок - очень полезная функция на этапе разработки. Но если сайт уже выложен в сеть, то оповещение о багах лучше отключить, потому что злоумышленник может увидеть, какие у сайта проблемы, и попытаться использовать эти уязвимости в своих целях.</p>
39
<p>Вывод ошибок - очень полезная функция на этапе разработки. Но если сайт уже выложен в сеть, то оповещение о багах лучше отключить, потому что злоумышленник может увидеть, какие у сайта проблемы, и попытаться использовать эти уязвимости в своих целях.</p>
40
<p>Отключить вывод можно в файле<em>.htaccess</em>, добавив туда следующие строки:</p>
40
<p>Отключить вывод можно в файле<em>.htaccess</em>, добавив туда следующие строки:</p>
41
php_flag display_errors offphp_value error_reporting 0<p>Кроме того, уберите вывод ошибок, который вы прописали в самом коде.</p>
41
php_flag display_errors offphp_value error_reporting 0<p>Кроме того, уберите вывод ошибок, который вы прописали в самом коде.</p>
42
<p>Обычно для подключения к базе данных создают учетную запись со всеми правами, чтобы можно было использовать все преимущества<a>SQL</a>, но лучше их ограничить. Для этого зайдите в phpmyadmin, добавьте нового пользователя и выдайте ему только часть прав:</p>
42
<p>Обычно для подключения к базе данных создают учетную запись со всеми правами, чтобы можно было использовать все преимущества<a>SQL</a>, но лучше их ограничить. Для этого зайдите в phpmyadmin, добавьте нового пользователя и выдайте ему только часть прав:</p>
43
<p>Пока ни одна галочка не отмечена - поставьте ее на пункт "Данные". Так можно будет оперировать существующими данными, но нельзя будет создать новую таблицу или удалить старую. Так вы защититесь в том числе и от атаки с помощью команды DROP, которая может удалить все статьи или комментарии с сайта.</p>
43
<p>Пока ни одна галочка не отмечена - поставьте ее на пункт "Данные". Так можно будет оперировать существующими данными, но нельзя будет создать новую таблицу или удалить старую. Так вы защититесь в том числе и от атаки с помощью команды DROP, которая может удалить все статьи или комментарии с сайта.</p>
44
<p>Если же менеджеру вашего сайта все же регулярно нужны привилегии администрирования и изменения структуры, создайте отдельного пользователя, которого будете использовать в админке. Но риск того, что доступ к ней кто-то получит, все равно существует. Поэтому стоит ограничить максимальное количество подключений и запросов.</p>
44
<p>Если же менеджеру вашего сайта все же регулярно нужны привилегии администрирования и изменения структуры, создайте отдельного пользователя, которого будете использовать в админке. Но риск того, что доступ к ней кто-то получит, все равно существует. Поэтому стоит ограничить максимальное количество подключений и запросов.</p>
45
<p>Также лучше поставить пароль на <em>root</em>, чтобы взломщик не смог подключиться через него.</p>
45
<p>Также лучше поставить пароль на <em>root</em>, чтобы взломщик не смог подключиться через него.</p>
46
<p>Старые версии языков (любых) часто не только менее функциональны, но и обладают букетом уязвимостей. Критические дыры стали известны хакерам много лет назад, поэтому они используют их, чтобы взломать сайт.</p>
46
<p>Старые версии языков (любых) часто не только менее функциональны, но и обладают букетом уязвимостей. Критические дыры стали известны хакерам много лет назад, поэтому они используют их, чтобы взломать сайт.</p>
47
<p>Да, в обновлении тоже могут быть баги, но не такие опасные. Тем более о них никто не будет знать, если после релиза прошло немного времени.</p>
47
<p>Да, в обновлении тоже могут быть баги, но не такие опасные. Тем более о них никто не будет знать, если после релиза прошло немного времени.</p>
48
<p>Банально, но простой пароль можно подобрать за несколько секунд. Особенно если он содержит персональные данные:</p>
48
<p>Банально, но простой пароль можно подобрать за несколько секунд. Особенно если он содержит персональные данные:</p>
49
<ul><li>дату рождения;</li>
49
<ul><li>дату рождения;</li>
50
<li>кличку питомца;</li>
50
<li>кличку питомца;</li>
51
<li>годовщину свадьбы;</li>
51
<li>годовщину свадьбы;</li>
52
<li>девичью фамилию матери и так далее.</li>
52
<li>девичью фамилию матери и так далее.</li>
53
</ul><p>Усугубляет положение то, что эту информацию мы часто выкладываем в свободный доступ.</p>
53
</ul><p>Усугубляет положение то, что эту информацию мы часто выкладываем в свободный доступ.</p>
54
<p>Безопасных систем не существует - вы можете только снизить вероятность взлома. Для этого нужно самому быть немного хакером:</p>
54
<p>Безопасных систем не существует - вы можете только снизить вероятность взлома. Для этого нужно самому быть немного хакером:</p>
55
<ul><li>вводите инъекции;</li>
55
<ul><li>вводите инъекции;</li>
56
<li>меняйте типы данных;</li>
56
<li>меняйте типы данных;</li>
57
<li>добавляйте в поля кавычки и знаки экранирования;</li>
57
<li>добавляйте в поля кавычки и знаки экранирования;</li>
58
<li>попробуйте загрузить на сайт файл<em>.php</em>с вредоносным кодом и так далее.</li>
58
<li>попробуйте загрузить на сайт файл<em>.php</em>с вредоносным кодом и так далее.</li>
59
</ul><p>Пытайтесь взломать собственный сайт, чтобы узнать, какие у него есть уязвимости. Сделайте это, пока кто-то не опередил вас.</p>
59
</ul><p>Пытайтесь взломать собственный сайт, чтобы узнать, какие у него есть уязвимости. Сделайте это, пока кто-то не опередил вас.</p>