0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#статьи</a></p>
1
<p><a>#статьи</a></p>
2
<ul><li>3 июл 2020</li>
2
<ul><li>3 июл 2020</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Разбираемся, почему одну из самых полезных возможностей современных языков программирования нужно использовать с осторожностью.</p>
4
</ul><p>Разбираемся, почему одну из самых полезных возможностей современных языков программирования нужно использовать с осторожностью.</p>
5
<p> vlada_maestro / shutterstock</p>
5
<p> vlada_maestro / shutterstock</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
7
<p>В большинстве современных языков программирования есть функции, которые позволяют выполнить какую-нибудь команду операционной системы или запустить код:</p>
7
<p>В большинстве современных языков программирования есть функции, которые позволяют выполнить какую-нибудь команду операционной системы или запустить код:</p>
8
<ul><li><em>system ()</em>в C++;</li>
8
<ul><li><em>system ()</em>в C++;</li>
9
<li><em>eval ()</em>в JavaScript;</li>
9
<li><em>eval ()</em>в JavaScript;</li>
10
<li><em>exec ()</em>в PHP;</li>
10
<li><em>exec ()</em>в PHP;</li>
11
<li><em>os.system ()</em>в Python и так далее.</li>
11
<li><em>os.system ()</em>в Python и так далее.</li>
12
</ul><p>Например, с помощью одной строчки на <a>C++</a>, содержащей<em>system ()</em>, можно в графической оболочке Gnome показать уведомление пользователю:</p>
12
</ul><p>Например, с помощью одной строчки на <a>C++</a>, содержащей<em>system ()</em>, можно в графической оболочке Gnome показать уведомление пользователю:</p>
13
//Вывод оповещения в оболочке рабочего стола GNOME для Linux system("notify-send 'Hello, World!'");<p>Это очень удобно, потому что иначе пришлось бы создавать отдельное окно, указывать его расположение на экране, закрывать через определённое время и так далее.</p>
13
//Вывод оповещения в оболочке рабочего стола GNOME для Linux system("notify-send 'Hello, World!'");<p>Это очень удобно, потому что иначе пришлось бы создавать отдельное окно, указывать его расположение на экране, закрывать через определённое время и так далее.</p>
14
<p>Вы можете передать в <em>system ()</em>любую встроенную команду операционной системы или внешнюю программу, установленную на компьютере. Они будут выполнять все те действия, на которые способна ваша ОС: создавать, удалять, перемещать файлы и папки, выключать компьютер, открывать другие программы и многое другое.</p>
14
<p>Вы можете передать в <em>system ()</em>любую встроенную команду операционной системы или внешнюю программу, установленную на компьютере. Они будут выполнять все те действия, на которые способна ваша ОС: создавать, удалять, перемещать файлы и папки, выключать компьютер, открывать другие программы и многое другое.</p>
15
<p>Можно, например, создать видеоредактор, почти не задумываясь о том, как происходит работа с самим файлом. Для этого достаточно с помощью<em>system ()</em>передать программе ffmpeg необходимые аргументы. Остаётся лишь создать графический интерфейс, и приложение готово.</p>
15
<p>Можно, например, создать видеоредактор, почти не задумываясь о том, как происходит работа с самим файлом. Для этого достаточно с помощью<em>system ()</em>передать программе ffmpeg необходимые аргументы. Остаётся лишь создать графический интерфейс, и приложение готово.</p>
16
<p>Чаще всего строка, содержащая команду, которую необходимо выполнить вызовом<em>system ()</em>, формируется с добавлением каких-либо данных. Это может быть текст уведомления или аргументы для другой программы. Затем<em>system ()</em>запускает командную оболочку<em>(Bourne Shell или аналогичную)</em>и передаёт команду ей. Это позволяет получить почти полный доступ к системе.</p>
16
<p>Чаще всего строка, содержащая команду, которую необходимо выполнить вызовом<em>system ()</em>, формируется с добавлением каких-либо данных. Это может быть текст уведомления или аргументы для другой программы. Затем<em>system ()</em>запускает командную оболочку<em>(Bourne Shell или аналогичную)</em>и передаёт команду ей. Это позволяет получить почти полный доступ к системе.</p>
17
<p>Важно! Если у пользователя есть возможность повлиять на передаваемые функции system () данные, он может попытаться сделать командную инъекцию (англ. Command injection или Shell injection) - добавить к данным вредоносные инструкции, которые будут выполнены в оболочке.</p>
17
<p>Важно! Если у пользователя есть возможность повлиять на передаваемые функции system () данные, он может попытаться сделать командную инъекцию (англ. Command injection или Shell injection) - добавить к данным вредоносные инструкции, которые будут выполнены в оболочке.</p>
18
<p>Рассмотрим фрагмент кода на C++:</p>
18
<p>Рассмотрим фрагмент кода на C++:</p>
19
//Спрашиваем пользователя, какое сообщение он хочет вывести string input; cout << "Your message: "; //Получаем ввод getline(cin, input); //Формируем команду string s = "notify-send '" + input + "'"; //Преобразуем строку в принимаемый функцией system() тип данных const char *command = s.c_str(); //Запускаем команду system(command);<p>Кроме самого текста сообщения, взломщик может ввести и что-нибудь нежелательное и даже опасное. Например, вот такой фрагмент:</p>
19
//Спрашиваем пользователя, какое сообщение он хочет вывести string input; cout << "Your message: "; //Получаем ввод getline(cin, input); //Формируем команду string s = "notify-send '" + input + "'"; //Преобразуем строку в принимаемый функцией system() тип данных const char *command = s.c_str(); //Запускаем команду system(command);<p>Кроме самого текста сообщения, взломщик может ввести и что-нибудь нежелательное и даже опасное. Например, вот такой фрагмент:</p>
20
<p>Hello! ' & & rm -rf /* & & echo 'a</p>
20
<p>Hello! ' & & rm -rf /* & & echo 'a</p>
21
<p>В итоге оболочка получит три команды вместо одной:</p>
21
<p>В итоге оболочка получит три команды вместо одной:</p>
22
<ul><li>notify-send 'Hello! ' - вывод уведомления, задуманный разработчиками.</li>
22
<ul><li>notify-send 'Hello! ' - вывод уведомления, задуманный разработчиками.</li>
23
<li>rm -rf /* - удаление всех файлов на компьютере.</li>
23
<li>rm -rf /* - удаление всех файлов на компьютере.</li>
24
<li>echo 'a - вывод буквы a. Эта команда нужна для того, чтобы не было конфликтов с кавычками.</li>
24
<li>echo 'a - вывод буквы a. Эта команда нужна для того, чтобы не было конфликтов с кавычками.</li>
25
</ul><p>Конечно, вряд ли кто-то будет делать что-нибудь подобное на своём устройстве. Но ваша программа может работать и на сервере.</p>
25
</ul><p>Конечно, вряд ли кто-то будет делать что-нибудь подобное на своём устройстве. Но ваша программа может работать и на сервере.</p>
26
<p>Вот пример для сайта, написанный на Python:</p>
26
<p>Вот пример для сайта, написанный на Python:</p>
27
#!/usr/bin/env python3 import os print("Content-type: text/html") print() print("<h1>Hello world!</h1>") os.system("notify-send 'Hello!'")<p>Каждый раз, когда пользователи будут заходить на эту страницу, на сервере будет выводиться уведомление.</p>
27
#!/usr/bin/env python3 import os print("Content-type: text/html") print() print("<h1>Hello world!</h1>") os.system("notify-send 'Hello!'")<p>Каждый раз, когда пользователи будут заходить на эту страницу, на сервере будет выводиться уведомление.</p>
28
<p>Этот пример немного надуманный, потому что на серверах обычно не устанавливают оболочку рабочего стола. Но есть и другие похожие уязвимости, которые не требуют GUI, но могут использоваться для взлома.</p>
28
<p>Этот пример немного надуманный, потому что на серверах обычно не устанавливают оболочку рабочего стола. Но есть и другие похожие уязвимости, которые не требуют GUI, но могут использоваться для взлома.</p>
29
<em>Результат работы программы</em><p>В веб-приложениях функции вроде<em>os.system ()</em>нужны очень редко, но последствия их небрежного использования могут оказаться весьма серьёзными: утечка данных пользователей, поломка оборудования, потеря прибыли и так далее.</p>
29
<em>Результат работы программы</em><p>В веб-приложениях функции вроде<em>os.system ()</em>нужны очень редко, но последствия их небрежного использования могут оказаться весьма серьёзными: утечка данных пользователей, поломка оборудования, потеря прибыли и так далее.</p>
30
<p>Даже если программа запущена не от root и разрушительное действие напрямую невозможно, взломщик может выполнить<strong>эскалацию привилегий</strong><em>(англ.<strong>Privilege escalation</strong>)</em> - с помощью известных уязвимостей получить повышенный уровень доступа к системе. Перечень таких незакрытых лазеек время от времени публикуется на различных хакерских сайтах.</p>
30
<p>Даже если программа запущена не от root и разрушительное действие напрямую невозможно, взломщик может выполнить<strong>эскалацию привилегий</strong><em>(англ.<strong>Privilege escalation</strong>)</em> - с помощью известных уязвимостей получить повышенный уровень доступа к системе. Перечень таких незакрытых лазеек время от времени публикуется на различных хакерских сайтах.</p>
31
<p>Что касается языков, которые не имеют доступа к командной оболочке<em>(например, JavaScript в браузере),</em>то в них возможна<strong>инъекция кода</strong><em>(англ.<strong>Code injection</strong>)</em> - передача вредоносного кода текущей программе.</p>
31
<p>Что касается языков, которые не имеют доступа к командной оболочке<em>(например, JavaScript в браузере),</em>то в них возможна<strong>инъекция кода</strong><em>(англ.<strong>Code injection</strong>)</em> - передача вредоносного кода текущей программе.</p>
32
<p>Самый простой пример - попытка ввести JavaScript-код в какую-нибудь форму на сайте. Например, взломщик может оставить комментарий следующего вида:</p>
32
<p>Самый простой пример - попытка ввести JavaScript-код в какую-нибудь форму на сайте. Например, взломщик может оставить комментарий следующего вида:</p>
33
<p>Пользователи, которые будут открывать страницу с этим комментарием, будут перенаправляться на другой сайт.</p>
33
<p>Пользователи, которые будут открывать страницу с этим комментарием, будут перенаправляться на другой сайт.</p>
34
<p>Другой пример - функция<em>eval ()</em>в JavaScript:</p>
34
<p>Другой пример - функция<em>eval ()</em>в JavaScript:</p>
35
//Команды, которые пришли с сервера //К основным инструкциям попал код, который делает невозможной нормальную работу сайта commands = "Foo(); Bar(); while(true) { alert(1); }"; //Выполнение переданных команд eval(commands);<p>Способы введения инъекции примерно те же самые.</p>
35
//Команды, которые пришли с сервера //К основным инструкциям попал код, который делает невозможной нормальную работу сайта commands = "Foo(); Bar(); while(true) { alert(1); }"; //Выполнение переданных команд eval(commands);<p>Способы введения инъекции примерно те же самые.</p>
36
<p>Если для работы вашей программы необходимы функции вроде<em>system ()</em>или<em>eval (),</em>то нужно выполнить<strong>валидацию</strong>всех вводимых данных - проверить их на соответствие определённым требованиям.</p>
36
<p>Если для работы вашей программы необходимы функции вроде<em>system ()</em>или<em>eval (),</em>то нужно выполнить<strong>валидацию</strong>всех вводимых данных - проверить их на соответствие определённым требованиям.</p>
37
<p>Основные способы валидации и защиты от инъекций кода:</p>
37
<p>Основные способы валидации и защиты от инъекций кода:</p>
38
<ul><li><strong>Создание чёрного списка.</strong>Блокируйте ввод, если значение находится в чёрном списке или частично состоит из запрещённых данных<em>(например, Hello! , rm -rf /*).</em></li>
38
<ul><li><strong>Создание чёрного списка.</strong>Блокируйте ввод, если значение находится в чёрном списке или частично состоит из запрещённых данных<em>(например, Hello! , rm -rf /*).</em></li>
39
<li><strong>Создание белого списка.</strong>Блокируйте ввод, если введённые пользователем данные не встречаются в белом списке.</li>
39
<li><strong>Создание белого списка.</strong>Блокируйте ввод, если введённые пользователем данные не встречаются в белом списке.</li>
40
<li><strong>Экранирование.</strong>Преобразуйте специальные символы в их кодовое представление<em>(> заменять на & #62;)</em>или экранируйте их <em>(" заменять на \").</em></li>
40
<li><strong>Экранирование.</strong>Преобразуйте специальные символы в их кодовое представление<em>(> заменять на & #62;)</em>или экранируйте их <em>(" заменять на \").</em></li>
41
<li><strong>Проверка формата.</strong>Проверяйте, чтобы сообщение вводилось в определённом формате. Например, телефонный номер может выглядеть так: 8 (800) 555-35-35.</li>
41
<li><strong>Проверка формата.</strong>Проверяйте, чтобы сообщение вводилось в определённом формате. Например, телефонный номер может выглядеть так: 8 (800) 555-35-35.</li>
42
<li><strong>Ограничение длины.</strong>Удаляйте все лишние символы, если длина строки превышает какое-либо значение.</li>
42
<li><strong>Ограничение длины.</strong>Удаляйте все лишние символы, если длина строки превышает какое-либо значение.</li>
43
<li><strong>Обрезка текста.</strong>Удаляйте все пробелы в начале и конце строки.</li>
43
<li><strong>Обрезка текста.</strong>Удаляйте все пробелы в начале и конце строки.</li>
44
<li><strong>Используйте директиву</strong><a><strong>use strict</strong></a><strong>и подобные</strong>. Сообщите интерпретатору, чтобы он более строго реагировал на ошибки в коде.</li>
44
<li><strong>Используйте директиву</strong><a><strong>use strict</strong></a><strong>и подобные</strong>. Сообщите интерпретатору, чтобы он более строго реагировал на ошибки в коде.</li>
45
</ul><p>В зависимости от особенностей приложения могут помочь и другие способы защиты. Например, если есть база данных, то имеет смысл использовать хранимые процедуры. Если же это онлайн-игра, то нужно проверять список подключённых DLL.</p>
45
</ul><p>В зависимости от особенностей приложения могут помочь и другие способы защиты. Например, если есть база данных, то имеет смысл использовать хранимые процедуры. Если же это онлайн-игра, то нужно проверять список подключённых DLL.</p>
46
<p>Важно! Задействовать какой-то один из перечисленных способов, скорее всего, не поможет - злоумышленник может найти другие неприкрытые лазейки.</p>
46
<p>Важно! Задействовать какой-то один из перечисленных способов, скорее всего, не поможет - злоумышленник может найти другие неприкрытые лазейки.</p>
47
<p>Подходите к защите комплексно, старайтесь использовать сразу несколько методов. И не забывайте следить за тем, какие права есть у вашего приложения. Это не позволит взломщику нанести серьёзный ущерб, если ему всё же удастся ввести инъекцию кода.</p>
47
<p>Подходите к защите комплексно, старайтесь использовать сразу несколько методов. И не забывайте следить за тем, какие права есть у вашего приложения. Это не позволит взломщику нанести серьёзный ущерб, если ему всё же удастся ввести инъекцию кода.</p>
48
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
48
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>