Полный контроль: как язык веб-программирования Parser упрощает создание безопасных сайтов
20.04.23, Чт, 18:50, Мск,
Автор языка Константин Моршнев рассказал, как реализован подход к безопасности в единственном российском языке веб-программирования.
Содержание |
Обеспечение безопасности – один из ключевых факторов при разработке веб-приложений. При создании Parser этому было уделено особое внимание как в первоначальной, так и в последующих версиях. Язык разработал в 1997 году Константин Моршнев, технический директор Студии Артемия Лебедева. За время существования Parser на этом языке созданы сотни сайтов, в том числе самой студией: например, сайты платежной системы «Мир», Большого театра и «Мастерской Петра Фоменко», аэропортов Пулково и Шереметьево, а также университета МИСиС и «Альфа-Банка». Константин рассказал, на какие кибер-угрозы он и его команда обратили пристальное внимание и как защищены создаваемые на языке Parser веб-ресурсы.
Внимание на входные данные и защиту от SQL-инъекций
Чтобы оценить уровень угроз в интернете, автор языка веб-программирования Parser предлагает немного погрузиться в предметную область. Разработчики знают, что сайты ежечасно сканируются специализированным программным обеспечением, которое ищет уязвимости. Есть сервисы, которые анализируют и классифицируют оборудование, подключенное к Сети, поэтому при обнаружении недочетов в популярном ПО злоумышленнику даже нет необходимости самому сканировать интернет, он может сделать выборку и легко буквально `на блюдечке` получить IP-адреса уязвимых систем.
![]() | Веб-приложение — это виртуальная дверь на ваш сервер: взломав его, злоумышленник получит доступ к хранящимся на сервере данным а также может использовать ваш сервер для дальнейших злонамеренных действий. Например изменив содержимое вашего сайта или используя его для атак на другие сервера, – объясняет Константин Моршнев. | ![]() |
Вместо отмычки виртуальные взломщики используют некорректные данные. Поэтому одно из главных правил, которым руководствуется автор Parser, — при разработке веб-приложений попросту не доверять входным данным. Всё, что пришло из внешних источников может быть подменено.
![]() | В последние годы при разработке сайтов стали популярны java-script фреймворки, где сайт - это приложение, которое работает в браузере посетителя сайта. Нередко наблюдаю, что разработчики делают проверки в java-script и считают, что этого достаточно. К сожалению, это не так. Злоумышленник может передать полностью измененные данные на сервер, обойдя все проверки в java-script, - говорит автор Parser. | ![]() |
Для иллюстрации Константин приводит пример. Посетитель интернет-магазина положил в корзину десять единиц товара. Приложение JavaScript пересчитало сумму, добавив скидку 20%, после чего показало информацию в браузере и передало на сервер все содержимое корзины со скидкой. Тем временем злоумышленник может, например, увеличить сумму скидки или передать иные данные по скидке. Даже если расхождение будет замечено на этапе отгрузки заказа, предъявить претензии покупателю будет тяжело, ведь если веб-приложение позволило сформировать и оплатить такой заказ, значит, клиент прав.
![]() | Поэтому, несмотря на возможную трудоемкость, всю логику расчета корзины необходимо дублировать на сервере, – говорит технический директор Студии Лебедева. | ![]() |
Также существует большой класс ошибок, проявляющихся, когда неправильные данные передаются намеренно. Самый известный пример – это SQL-инъекция. Если делать запрос в базу данных, используя переданные пользователем данные, и при этом не экранировать специальные символы, это дает злоумышленнику возможность выполнить произвольный SQL-запрос.
![]() | Существует два основных способа защиты от SQL-инъекций. Первый – это использование именованных параметров. В этом случае код запроса фиксирован, а переданные посетителем данные передаются как дополнительные параметры запроса. Это надёжный подход, но его не всегда удобно использовать, если логика формирования SQL-запроса сложна. Приходится отдельно сформировать запрос и отдельно список параметров, – продолжает Константин. | ![]() |
Второй подход заключается в экранировании небезопасных символов во входных данных. Для этого, например, в PHP существует функция real_escape_string.TAdviser выпустил новую карту «Цифровизация банков»
Похожая проблема существует, если вставлять ввод пользователя в результирующую страницу. Злоумышленник может передать HTML-теги или код на JavaScript, что приведёт к искажению вывода. Здесь может показаться, что проблемы как таковой нет, ведь теоретически этот искаженный код увидит только злоумышленник. Но данные могут сохраниться в базу или код может сработать при переходе администратора по ссылке. В этом случае авторизационные cookies рискуют быть переданы на сервер злоумышленника. В PHP для экранирования в такой ситуации существует функция htmlspecialchars, которая, в частности, заменяет угловые скобки на соответствующие им HTML Entities.
![]() | Получается, что защита находится полностью в руках разработчика. Если он забудет вызвать нужную функцию, веб-приложение будет уязвимо, – объясняет технический директор Студии Лебедева. | ![]() |
Как реализована защита в Parser
В Parser автор-разработчик Константин Моршнев придумал и реализовал автоматическое преобразование небезопасных символов в зависимости от контекста использования. В частности, в третьей версии языка программирования для этого используется разделение данных на безопасные или `чистые` и небезопасные. Безопасные данные – это то, что написал сам разработчик в коде веб-приложения. Все остальные данные – те, что поступают из внешних источников, передаются посетителем в качестве параметров в форме или загружено из файла или другого сайта, считаются небезопасными.
Что происходит, когда смешиваются `чистые` и небезопасные данные? В этом случае Parser знает про каждый символ строки, безопасный он или нет.
![]() | Когда, например, формируется SQL-запрос к базе данных, то Parser к безопасным символам никакого преобразования не применяет. К небезопасным символам применяется правило преобразования, соответствующее контексту использования. В случае SQL-запроса в сервер MySQL будут экранированы символы кавычек. А в случае формирования кода HTML-страницы - угловые скобки, – говорит Моршнев. | ![]() |
Причем эти механизмы работают в Parser по умолчанию, разработчику не нужно их активировать. Таким образом язык берёт на себя значительную часть работы по обеспечению безопасности веб-приложения, что делает код приложения проще и менее подверженным ошибкам.
Сравним реализацию использования данных формы на PHP с аналогичным кодом на Parser. На PHP код может выглядеть, например, так:
$username = $mysqli->real_escape_string($_POST['username']);
$rs = $mysqli->query("select * from users where username='$username'");
А так – на Parser:
$rs[^table::sql{select * from users where username='$form:username'}]
Если сравнить вариант формирования HTML-кода с использованием данных формы на PHP с аналогичным кодом на Parser, то в первом случае код будет выглядеть так:
вид кавычек имеет значение
<input type="hidden" name="username" value="<?php echo htmlspecialchars($_POST['username']); ?>"/>
Второй вариант с кодом на Parser:
<input type="hidden" name="username" value="$form:username'"/>
Второй вариант в каждом случае выглядит значительно проще. Но в то же время цена такой простоты – необходимость хранения информации о безопасности каждого символа. Константин Моршнев провел несколько оптимизаций, которые позволили минимизировать как падение производительности, так и потребление памяти.
![]() | Изначально Parser разрабатывался как удобный инструмент для создания сайтов, доступный не только профессиональным программистам, но и разработчикам с небольшим опытом, — говорит Константин. — Эти накладные расходы и усложнение кода самого Parser многократно окупаются повышением безопасности тысяч сайтов, сделанных на этом языке программирования. | ![]() |
Гибкое экранирование данных в языке Parser
Данные перед использованием могут быть многократно преобразованы, но и в этом случае все будет работать корректно:
Берем первую букву имени и фамилию:
$name[^form:firstName.left(1). $form:lastName]
В SQL контексте будут экранированы кавычки:
^void:sql{update users .. set name='$name'}]
В HTML контексте будут экранированы угловые скобки:
<p>Имя: $name</p>
В случае, если сценарий работы с данными отличается от обычного, например, если пользователь уверен в безопасности пришедших данных, в языке веб-программирования авторства Константина Моршнева предусмотрены особые инструменты.
А именно: небезопасные данные можно пометить как чистые. Для этого есть оператор taint. Оператор может явно обозначить, что символы должны преобразовываться определенным образом. По данным создателя языка программирования, такая функция востребована среди более опытных разработчиков.
Поддержка Parser осуществляется уже более 20 лет. Вместе с тем продолжается постоянная работа над новыми возможностями и улучшениями с учетом запросов и потребностей пользователей Parser, чтобы язык оставался востребованным инструментом в мире веб-разработки.
Автор: Сергей Добронравов