правила написания безопасного кода для веб приложений

12 навыков создания защищенных веб-приложений

Данная статья не содержит никаких откровений. В первую очередь информация о типовых уязвимостях и методах их решения будет полезна начинающим. Опытные разработчики все это знают, или должны знать, если считают себя таковыми.

Большинство примеров кода не привязаны к какому-либо конкретному языку программирования, но для наглядности я буду использовать PHP.

1. Защита от SQL injection

Допустим у вас есть вебсайт с формой ввода имени пользователя. Для проверки наличия имени в базе данных вы используте вот такой код:

Пользователю достаточно ввести вот такое значение в поле Username

чтобы получился запрос, который всегда возвращает данные:

Для тех баз данных, которые поддерживают выполнение несколько запросов в одном пакете, злоумышленник может исполнить запрос удаляющий или изменяющий данные.

Пример такого ввода:

2. Защита от Сross Site Scripting (XSS)

XSS уязвимости могут быть подвержены динамические вебсайты, где пользователи вводят какие-то свои данные, которые потом будут показаны на странице: форумы, гостевые книги, комментарии блогам и другое. Идея XSS заключается во встраивании в текст комментария какого-то Javascript кода, который исполнится, когда страницу откроет другой пользователь.

Чем может навредить безобидный джаваскрипт? Довольно многим, от открытие левых сайтов в попапе или простого завешивания браузера до воровства куки. Последнее уже может привести к выполнению другим пользователем действий на этом сайте от вашего имени. Рассмотрим минимальный пример.

Форма для ввода текста:

Мы видим, что введенный текст никак не обрабатывается и выводится на страницу в исходном виде. Теперь рассмотрим такой пример ввода:

Нетрудно видеть, что javascript код исполнится после сабмита формы. Лечится пропусканием ввода через htmlentities() непосредственно перед показом:

3. Использование HTTPS

Здесь все очень просто. Если ваше приложение работает с финансовыми, медицинскими или просто с очень важными данными — используйте HTTPS. Данные между браузером и веб-сервером передаются в зашифрованном виде и не могут быть расшифрованы в случае перехвата сниффером.

4. Предотвращение скачивания пользовательских файлов по прямой ссылке

Рассмотрим веб-приложение, где пользователи могут закачивать на сервер свои личные файлы. Некоторые файлы могут быть конфиденциальными и не должны быть доступны никому, кроме их владельца.

Есть закачивать все файлы в директорию вида public_html/files, то файл mysecretdoc.pdf будет доступен любому желающему по прямой ссылке mysecurewebsite.com/files/mysecretdoc.pdf.

Есть как минимум два способа предотвратить эту ситуацию:

5. Хранение паролей пользователей

— Не хранить пароли открытым текстом

Достаточно очевидное решение. Если мы будем хранить хэши паролей (MD5+salt), последстивия утечки таблицы паролей становятся намного менее серьезными, особенно в сочетании со следующим пунктом.

— Требовать, чтобы пароли удовлетворяли определенными правилам сложности и заставлять менять их через какое-то время. Как пользователь я не очень люблю этот метод, но он работает.

— Использовать комбинацию пароля (пин-кода) и устройства типа RSA токена для логина. Подойдет для банковских или внутрикорпоративных приложений.

— Сделать авторизацию через сторонний сервис, такой как Facebook, Twitter или OpenID. Пусть у них болит голова как уберечь пароли.

6. Шифрование и обфускация кода

Здесь важно понимать, что шифрование и обфускация защищают от изменения и понимания кода, но не от его исполнения. Защифрованный код исполняется точно так же как и исходный и, более того, модуль расшифровки поставляется вместе с зашифрованным кодом и можеи быть использован для декодирования. Если злоумышленник получил доступ к вашему серверу, шифрование кода мало чем поможет.

Есть только один сценарий, когда это дело работает в качестве защиты от исполнения кода. Код расшифровки может устанавливаться как модуль на сервер и, если в руки злоумышленнику попал только сам зашифрованный код, без этого модуля он его не исполнит.

7. Шифрование данных

Шифрование данных защищает от ситуации, когда база данных попала в чужие руки, но нет кода, который с ней работает.

Технически ничего сложного здесь нет. Шифрование/декодирование можно реализвать как средствами языка программирования так и в самой БД. Второй метод предпочтительнее, особенно если нужно реализовать поиск по зашифрованным данным.

Вот как это можно сделать для MySQL.

Шифрование с помощью триггеров

Декодирование в SQL запросе

Бонус для параноиков

В качестве эксперимента можно использовать пароль пользователя в качестве фразы шифрования данных. Если пользователей в системе несколько, персональные данные каждого из них шифруются своим собственным паролем. В таком случае даже получив доступ к коду или к базе данных злоумышленник не сможет расшифровать данные.

Из минусов:
— при смене пароля придется перешифровать данные
— в случае утери пароля восстановить данные не получится

8. Защита данных сессии (PHP, shared server)

В случае, когда ваше приложение хостится вместе с сотней других на одном сервере, кто-то может получить доступ ко всему серверу и прочитать или подделать переменные сессии.

Содержание типичного файла сессии PHP:

Решение:
— шифровать переменные сессии
— хранить данные сессии в БД. В PHP можно переопределить обработчик сессии с помощью функции session_set_save_handler

9. Обработка сообщений об ошибках

Как только система переводится в режим продакшен убедитесь что никакие необработанные сообщения об ошибках не будут показаны пользователю. Это может дать информацию о структуре базе данных или о структуре приложения.

Как минимум, сообщения об ошибках стоит отключить. В PHP это можно сделать вот так:

Наиболее же правильный метод это перехват сообщений об ошибке, запись их в БД, отправка уведомления разработчику итд. В PHP перехват сообщений об шибках делается с помощью функции set_error_handler(). И вот еще пример перехвата фатальных ошибок, которые нельзя перехватить с помощью set_error_handler().

10. Защита соединения между базой данных и приложением

Применимо к ситуации когда база данных расположена на другом сервере. Вот статья, которая рассказывает как создать SSL тоннель между MySQL и PHP.

11. Защита от form spoofing

Допустим у вас есть форма редактирования данных пользователя вот с таким УРЛ: example.com/edit_user.php?id=12345. Ничто не мешает пользователю 12345 поменять номер аккаунта в УРЛ и попытаться отредактировать другого пользователя. Простая проверка на стороне сервера пресекает эти попытки на корню.

Неискушенный прграммист может подумать, что заменив GET на POST мы избавимся от номеров аккаунтов в УРЛ и закроем уязвимость. Разумеется это не так. Сохранив страницу на свой компьютер и изменив данные формы, злоумышленник может подделать POST запрос.

Допустим у вас есть интернет магазин, в котором цена продукта берется из поля на форме. Поменяв значение поля, злоумышленник сможет купить товар по более низкой цене.

Эта тема плотно перекликается с валидацией всех данных, вводимых пользователем. Допустим у вас есть радио-кнопка с выбором пола.

Зная, что значение этого поля может быть только m или f, программист может посчитать проверку этого поля необязательным и записать его в базу данных в виде как оно есть.

Злоумышленник может сохранить эту страницу себе на диск и поменять ее следующим образом.

Даже если вы обработаете ввод с помощью mysql_real_escape_string(), значение все равно получится слишком длинным для односимвольного поля и поломает запрос (вот для чего мы советуем отключать сообщения об ошибках в продакшен версии).

Хорошим решением будет усечение этого поля до одного символа:

12. Защита от Cross-site request forgery (CSRF)

Эта уязвимость менее известна чем XSS, хотя не менее опасна. Представим себе форум, где участник Vasya постит сообщние, содержащее вот такой вот код:

Когда эту страницу откроет участник Petya, браузер исполнит запрос

Проблема в том, что если банк хранит данные доступа в куках, Petya будет залогинен автоматически и транзакция совершится от его имени, о чем он, конечно, и не подозревает.

Первая мысль которая приходит в голову — заметить GET на POST на всех важных формах (или вообще на всех). К сожалению это не решает проблему полностью. Ничто не мешает злоумышленнику разместить вот такую форму на своем вебсайте:

Если Васе удастся заманить Петю на свой вебсайт — форма будет отправлена и цель достигнута. Еще одна причина не ходить по подозрительным вебсайтам.

Заключение

Теперь хорошие новости. От большинства этих уязвимостей несложно защититься. Многие PHP фреймворки (Yii, CakePHP, CodeIgniter, Zend, Symfony) и генераторы кода (PHPRunner) имеют встроенную защиту от большиства уязвимостей. Тем не менее, стоит понимать, как оно работает, чем чревато и как защититься. Предупрежден — значит вооружен.

Источник

Шпаргалка для разработчика: создаём безопасное веб-приложение

правила написания безопасного кода для веб приложений

Эта статья — своего рода ‘cheat sheet’ для веб-разработчика. Она даёт представление о «программе-минимум» для создания веб-приложения, защищённого от самых распространённых угроз.

Экранирование пользовательского ввода

Что это?

В случае если данные пользовательского ввода, отображаемые в браузере, не предполагают наличия активного контента (HTML-разметки, CSS-стилей, JavaScript), данные пользовательского ввода должны быть закодированы (экранированы) перед использованием (отображением). Экранирование предполагает замену специальных символов (набор специальных символов зависит от контекста — HTML, JavaScript и т.д) для того, чтобы обработанные данные трактовались как тест, а не как активный контент. С точки зрения безопасности это делается главным образом для защиты от XSS.

Что делать?

Следует избегать хранения закодированных данных. Кодирование должно выполняться на стороне клиента, как можно ближе к месту использования данных. Главным образом это связано с тем, что только клиент знает, в каком контексте данные отображаются и от чего зависит необходимый тип кодирования.

Возможные контексты экранирования:

HTML-контекст — необходимо экранирование для HTML.

HTML-атрибут — необходимо экранирование для HTML-атрибута.

JavaScript — необходимо экранирование для JavaScript.

URL — необходимо экранирование для URL.

Кроме того, хранение закодированных данных может привести к двойному экранированию. Многие фреймворки экранируют текст по умолчанию (например ASP.NET Core).

Многие фреймворки предоставляют встроенный набор методов для данных целей.

Примеры

Экранирование HTML

Экранирование HTML-атрибута

Экранирование JavaScript

Экранирование JSON

Экранирование URL

Санитайзинг пользовательского ввода

Что это?

В случае если данные пользовательского ввода, отображаемые в браузере, предполагают наличие активного контента (HTML-разметки, CSS-стилей, JavaScript), необходимо выполнять санитайзинг пользовательского ввода — удаление/экранирование всего неразрешённого (например, в контексте HTML это касается тегов и атрибутов). С точки зрения безопасности это делается главным образом для защиты от XSS.

Что делать?

Предпочтительным подходом в таком случае является whitelisting — явное перечисление того, что разрешено. Конкретная логика и список разрешённых тегов и атрибутов сильно зависят от конкретного приложения. Реализовать санитайзинг безопасным образом в целом довольно сложно, предпочтительно использовать готовые протестированные решения и библиотеки. В контексте ASP.NET таким решением может быть использование Html Agility Pack — HTML-парсера, на основе которого можно создать необходимую логику санитайзинга HTML, удовлетворяющую необходимым требованиям приложения.

Пример

Пользователь может оставлять комментарии, содержащие теги . Пользовательский ввод:

Пользовательский ввод после санитайзинга:

Контроль над произвольным пользовательским вводом

Что это?

В большинстве случаев данные пользовательского ввода должны проходить проверку на соответствие допустимым значениям, бизнес-правилам и т.п. Проверка может осуществляться как на клиентской, так и на серверной стороне. Проверка на клиентской стороне положительно влияет на user experience, позволяя получить более ранний отклик, но сама по себе не является достаточной. Проверка на сервере должна проводиться обязательно, вне зависимости от наличия клиентской проверки. С точки зрения безопасности это делается главным образом для защиты от фишинга.

Что делать?

Валидация пользовательского ввода

Пример

Система принимает сообщение об ошибке как часть URL:

Источник

Руководство по написанию защищённых PHP-приложений в 2018-м

правила написания безопасного кода для веб приложений

Приближается 2018 год, и технари — в частности веб-разработчики — должны отбросить многие старые методики и верования в сфере разработки защищённых PHP-приложений. Особенно это относится ко всем, кто не верит, что такие приложения вообще возможны.

Это руководство — дополнение к электронной книге PHP: The Right Way с сильным уклоном в безопасность, а не общие вопросы программирования на PHP (вроде стиля кода).

Содержание

Версии PHP

Вкратце: ничего не поделаешь, но в 2018-м вы будете пользоваться PHP 7.2, а в начале 2019-го — планировать перейти на 7.3.

PHP 7.2 вышел 30 ноября 2017 г.

На момент написания статьи только PHP 7.1 и 7.2 активно поддерживаются разработчиками языка, а для PHP 5.6 и 7.0 ещё примерно год будут выходить патчи безопасности.

В некоторых ОС есть долговременная поддержка уже не поддерживаемых версий PHP, но это считается в целом порочной практикой. Например, бэкпортирование патчей безопасности без инкрементирования номеров версий затрудняет оценку системы безопасности только по версии PHP.

Соответственно, вне зависимости от обещаний вендоров всегда старайтесь использовать только активно поддерживаемую версию PHP, если это возможно. Если даже вы какое-то время будете работать с версией, для которой выходят только патчи безопасности, регулярные обновления версий избавят вас от многих неприятных сюрпризов.

Управление зависимостями

Вкратце: используйте Composer.

Composer — это шедевральное решение по управлению зависимостями в PHP-экосистеме. В книге PHP: The Right Way целый раздел посвящён началу работы с Composer, очень рекомендуем его прочесть.

Если вы не пользуетесь Composer для управления зависимостями, то рано или поздно (надеюсь — поздно, но, скорее всего, рано) окажетесь в ситуации, когда одна из библиотек, от которой вы зависите, сильно устареет, а преступники начнут активно эксплуатировать уязвимости в старых версиях.

Важно: не забывайте обновлять свои зависимости по мере разработки ПО. К счастью, это можно сделать одной строкой:

Если вы делаете что-то особенное, требующее использования PHP-расширений (написанных на С), то вы не можете установить их с помощью Composer. Вам также потребуется PECL.

Рекомендуемые пакеты

Вне зависимости от того, что вы создаёте, наверняка эти зависимости будут вам полезны. Это в дополнение к тому, что рекомендует большинство PHP-разработчиков (PHPUnit, PHP-CS-Fixer и т. д.).

roave/security-advisories

Пакет Roave security-advisories использует репозиторий Friends of PHP, чтобы ваш проект не зависел от любых пакетов с известными уязвимостями.

Или можете загрузить свой файл composer.lock в Sensio Labs в качестве стандартной процедуры автоматической оценки на уязвимости, чтобы получать предупреждения о любых устаревших пакетах.

vimeo/psalm

Psalm — инструмент статичного анализа, помогающий определять возможные баги в вашем коде. Хотя есть и другие хорошие инструменты (например, замечательные Phan и PHPStan), но если вам нужна поддержка PHP 5, то Psalm — один из лучших инструментов статичного анализа для PHP 5.4+.

Использовать Psalm просто:

Если вы впервые применяете этот код к имеющейся базе данных, то увидите много красных отметок. Если вы не создаёте приложение масштаба WordPress, то маловероятно, что вам придётся совершить подвиг Геркулеса, чтобы пройти все эти тесты.

Вне зависимости от того, какой инструмент статичного анализа вы выбрали, рекомендуем внедрить его в рабочий процесс непрерывной интеграции (если это возможно), чтобы инструмент запускался после каждого изменения кода.

HTTPS и безопасность в браузере

В 2018-м сайтам уже будет непозволительно работать по незащищённому HTTP. К счастью, можно было бесплатно получить TLS-сертификаты и автоматически обновлять их благодаря протоколу ACME и сертификационной компании Let’s Encrypt.

Интегрировать ACME в свой веб-сервер — пара пустяков.

Вы могли подумать: «Ладно, у меня есть TLS-сертификат. Теперь нужно потратить несколько часов на поиск конфигурации, чтобы сайт стал безопасным и быстрым».

Нет! Mozilla вам поможет. Для создания рекомендованных шифронаборов для своей аудитории можете использовать генератор конфигураций.

HTTPS (HTTP через TLS) совершенно безальтернативен, если хотите сделать свой сайт безопасным. Использование HTTPS моментально исключает несколько видов атак на ваших пользователей (внедрение контента «человек посередине», перехват данных, атаки повтором и манипуляции с сессиями ради подмены пользователя).

Заголовки безопасности

Хотя применение HTTPS на вашем сервере даёт много преимуществ по безопасности и производительности, можно пойти ещё дальше и воспользоваться другими функциями браузера по повышению безопасности. Большинство из них подразумевает отправку с контентом заголовков HTTP-ответов.

Аналогично, если вы используете встроенные PHP-свойства управления сессиями (что рекомендуется), то, возможно, захотите вызвать session_start() :

Тогда ваше приложение при отправке идентификационных кук будет использовать только безопасные HTTPS-флаги, что предотвратит успешные XSS-атаки с помощью кражи пользовательских кук, они будут отправляться только по HTTPS. Пару лет назад мы уже писали о безопасных PHP-сессиях.

Целостность подресурсов

Однажды в будущем вы станете работать над проектом, использующим CDN для выгрузки традиционных Javascript/CSS-фреймворков и библиотек в центральное расположение. Неудивительно, что специалисты по безопасности предсказали очевидную проблему: если много сайтов используют CDN для предоставления части своего содержимого, то взлом CDN и подмена данных позволит внедрять произвольный код на тысячи (если не миллионы) сайтов.

Поэтому придумали целостность подресурсов (subresource integrity).

Целостность подресурсов (SRI) позволяет закреплять хеш содержимого файла, которое вам должна предоставить CDN. Текущая реализация SRI позволяет использовать только криптографические хеш-функции, поэтому злоумышленники не смогут сгенерировать вредоносные версии контента, приводящие к таким же хешам, как у оригинальных файлов.

Взаимосвязи документов

Не делайте так

Это позволит example.com получить контроль над текущей страницей.

Делайте так

Разработка защищённых PHP-приложений

Если безопасность ПО для вас в новинку, можете начать с введения A Gentle Introduction to Application Security.

Многие специалисты по безопасности с самого начала обращают внимание разработчиков на ресурсы вроде OWASP Top 10. Но многие распространённые уязвимости можно считать особыми случаями одних и тех же высокоуровневых проблем (код/данные не разделены адекватно, ошибочная логика, небезопасная операционная среда, сломанные криптографические протоколы).

Мы считаем, что, если прививать неофитам в безопасности более простое, более фундаментальное представление о проблемах безопасности и их решениях, это поможет в долгосрочной перспективе улучшить ситуацию с безопасностью.

Взаимодействие с базами данных

Если вы сами пишете SQL-запросы, проверьте, что вы используете подготовленные выражения (prepared statements) и что любая предоставляемая сетью или файловой системой информация передаётся в виде параметров, а не конкатенируется в строку запроса. Также удостоверьтесь, что вы избегаете эмулированных подготовленных выражений.

НЕ ДЕЛАЙТЕ ТАК:

В базах данных есть и другие слои абстракций, предоставляющие эквивалентный уровень безопасности (EasyDB под капотом использует PDO, но любыми способами старается отключить эмулирование подготовленных выражений в пользу настоящих подготовленных выражений, чтобы предотвратить проблемы). Пока вводимые пользователями данные не могут влиять на структуру запросов (это относится и к хранимым процедурам) — вы в безопасности.

Загрузка файлов

Принимать пользовательские файлы рискованно, но это можно делать безопасно, если принять ряд предосторожностей. В частности, закрыть прямой доступ к загружаемым файлам, чтобы они не могли быть исполнены или интерпретированы.

Загружаемые файлы должны иметь атрибуты «только для чтения» или «только для чтения или записи» и никогда не быть исполняемыми.

Лучше хранить их в отдельной директории, к которой нет прямого доступа (например, /var/www/example.com-uploaded/ ), чтобы они случайно не выполнялись как серверные скрипты и не открывали дверь удалённому исполнению кода.

Более чистое решение — переместить свою корневую директорию для файлов на один уровень вниз (т. е. в /var/www/example.com/public ).

Другая проблема загружаемых файлов связана с их безопасным скачиванием.

Межсайтовый скриптинг (XSS)

В идеальном мире предотвратить XSS было бы так же легко, как и SQL-внедрение. У нас был бы простой в использовании API для отделения структуры документа от его содержимого.

К сожалению, в реальном мире большинство веб-разработчиков генерируют длинный HTML и отправляют его в HTTP-ответе. Это характерно не только для PHP, просто таковы реалии веб-разработки.

Закрытие XSS-уязвимостей — задача вполне решаемая. Однако содержимое раздела о браузерной безопасности неожиданно обретает большую важность. Вкратце:

Подделка межсайтовых запросов (CSRF)

Подделка межсайтовых запросов — это разновидность атаки с подменой делегата: можно обмануть пользовательский браузер и заставить его выполнить вредоносный HTTP-запрос с повышенными пользовательскими привилегиями.

В целом эта проблема легко решается:

Мы написали библиотеку Anti-CSRF, которая идёт ещё дальше:

Если ваш фреймворк не заботится о CSRF-уязвимостях, то применяйте Anti-CSRF.

В скором будущем куки SameSite позволят прекращать CSRF-атаки с гораздо меньшими усилиями.

XML-атаки (XXE, XPath-внедрения)

Есть две основные уязвимости, проявляющиеся в приложениях, которые много обрабатывают XML:

XXE-атаки, помимо прочего, могут использоваться как стартовая площадка для эксплойтов локального/удалённого внедрения файлов.

Ранние версии Google Docs были уязвимы к XXE-атакам, но они мало известны за пределами бизнес-приложений, обрабатывающих большие объёмы XML.

Главное, что нужно сделать для защиты от XXE-атак:

XPath-внедрение очень похоже на SQL-внедрение, только здесь речь идёт об XML-документах.

К счастью, в PHP-экосистеме редко возникают ситуации, когда вводимые пользователями данные передаются в XPath-запросе.

К сожалению, это также означает, что лучшее доступное решение (для заранее скомпилированных и параметризованных XPath-запросов) в PHP-экосистеме отсутствует.

Рекомендуем использовать белые списки разрешённых символов для любых данных, имеющих отношение к XPath-запросам.

Белые списки безопаснее чёрных.

Десериализация и внедрение PHP-объектов

Если вы передаёте в unserialize() недоверенные данные, то напрашиваетесь на два варианта развития событий:

Многие разработчики предпочитают использовать вместо этого JSON-сериализацию, что является заметным улучшением безопасности ПО. Но имейте в виду, что json_decode() уязвима для DDoS-атак посредством хеш-коллизий. К сожалению, полное решение проблемы хеш-DOS в PHP ещё предстоит найти.

Полностью защититься от этих атак поможет мигрирование с djb33 на Siphash с назначением 1 в качестве старшего бита для хеша строкового входного значения, 0 для целочисленного и с заранее запрошенным ключом, его предоставит CSPRNG.

К сожалению, создатели PHP не готовы частично пожертвовать производительностью, которой они добились в PHP 7, поэтому трудно убедить их отказаться от djb33 (очень быстрого, но небезопасного) в пользу SipHash (тоже быстрого, хотя и не как djb33, но куда более безопасного). Значительное снижение производительности может даже помешать разработке будущих версий, что не пойдёт на пользу безопасности.

Поэтому лучше поступать так:

Хеширование паролей

Подробнее: Как в 2016-м безопасно хранить пользовательские пароли
Безопасное хранилище паролей раньше было темой активной дискуссии, но сегодня его просто реализовать, особенно в PHP:

Вам даже не нужно знать, какой там алгоритм, потому что если вы используете самую свежую версию PHP, то будете использовать и самые последние технологии, а пользовательские пароли будут автоматически обновлены, как только окажется доступен новый алгоритм по умолчанию.

Если интересно: с PHP 5.5 по 7.2 алгоритмом по умолчанию является bcrypt. В будущем его могут заменить Argon2, победителем в Соревновании по хешированию паролей.

Если до этого вы не использовали API password_* и вам нужно мигрировать легаси-хеши, то сделайте это именно так. Многие компании, например Yahoo, поступили неправильно. Похоже, недавно причиной бага с iamroot у Apple стала некорректная реализация обновления легаси-хешей.

Криптография общего назначения

Мы много писали на эту тему:

Для криптографии на уровне приложения всегда выбирайте библиотеку Sodium (libsodium). Если вам нужно поддерживать PHP ниже 7.2 (вплоть до 5.2.4), можете использовать sodium_compat и притвориться, что пользователи тоже применяют 7.2.

В особых случаях из-за выбранных алгоритмов и взаимозаменяемости вам могут понадобиться другие библиотеки. Если сомневаетесь, проконсультируйтесь у криптографа по поводу выбора шифра и у инженера по шифрованию по поводу безопасности реализации.

Особые случаи

Вы получили представление, как в 2018-м нужно создавать защищённые PHP-приложения. Давайте теперь рассмотрим некоторые специфические случаи.

Шифрование с возможностью поиска

Многим хочется иметь шифрованные базы данных с возможностью поиска, но считается, что их трудно реализовать. По ссылке выше вы найдёте статью, в которой мы последовательно ведём читателя по разработке такой БД. В частности:

На любом шаге вы можете идти на компромиссы в зависимости от того, что в вашем случае оправдано.

Аутентификация на основе токенов без побочных каналов

Если говорить о базах данных (предыдущий раздел): вы знали, что запросы SELECT теоретически могут быть источником утечек информации о тайминге?

Простые меры защиты:

Даже если воспользоваться утечкой данных о тайминге для кражи половины токена, оставшаяся половина потребует брутфорс-атаки.

Разработка защищённых API

Мы написали SAPIENT, Secure API ENgineering Toolkit, чтобы упростить задачу межсерверного аутентификационного обмена сообщениями. Sapient позволяет шифровать и/или аутентифицировать сообщения с помощью шифрования на основе общего (shared) или публичного ключа в дополнение к средствам безопасности HTTPS.

Это позволяет с помощью Ed25519 аутентифицировать и отвечать на API-запросы или шифровать сообщения для целевого сервера, которые можно расшифровать лишь с помощью секретного ключа на принимающем сервере, даже несмотря на атаку «человек посередине» в сочетании с фальшивой/скомпрометированной сертификационной организацией.

Поскольку тело каждого HTTP-сообщения аутентифицируется с помощью безопасного шифрования, его можно использовать вместо протоколов, оперирующих токенами с проверкой состояния (например, Oauth). Но если говорить о самом шифровании, то прежде чем делать что-то нестандартное, всегда нужно быть уверенными в том, что выбранный вами алгоритм проанализирован специалистами.

Вся используемая в Sapient криптография предоставлена шифровальной библиотекой Sodium.

Дополнительно почитать:

Paragon Initiative Enterprises уже использует Sapient во многих своих продуктах (включая open source проекты) и продолжит расширять портфолио пользователей Sapient.

Безопасное журналирование событий с помощью Chronicle

Chronicle — криптографический журнал, обновляемый только путём добавления новых записей. Он основан на использующей хеш-цепочки структуре данных, свойства которой, безо всяких излишеств, привлекают многие компании в стан технологии «блокчейна».

Помимо более изощрённых способов применения такого журнала, Chronicle превосходно себя проявляет в SIEM, поскольку вы можете отправлять важные с точки зрения безопасности события в личный журнал, после чего они становятся неизменяемыми.

Если ваш Chronicle настроен на перекрёстную запись (cross-sign) суммарного хеша в другие экземпляры Chronicle и/или если есть другие экземпляры, сконфигурированные на репликацию содержимого вашего Chronicle, то атакующему будет крайне сложно подделать ваши журналы событий безопасности.

С помощью Chronicle вы получите надёжность блокчейна без распространённых проблем с приватностью, производительностью или масштабируемостью.

Для публикации данных в локальный Chronicle можно использовать любой API, совместимый с Sapient, но самое простое решение — Quill.

Несколько слов от автора

Проницательный читатель мог заметить, что мы много ссылаемся на собственные работы (статьи и open source проекты), но мы ссылаемся не только на свои работы.

Наша компания с самого основания в начале 2015-го пишет библиотеки для обеспечения безопасности и участвует в повышении защищённости экосистемы PHP.

Мы много путешествуем, и наш инженер по безопасности (чьи недавние усилия по использованию более сильной криптографии в ядре PHP только что отразились в PHP 7.2), по его собственному признанию, не слишком силён в генерировании хайпа или интереса к своей работе. Наверняка вы не слышали и о половине инструментов или библиотек, созданных нами за эти годы.

Но мы не можем стать пионерами во всех направлениях, поэтому везде, где это возможно, связываемся с экспертами индустрии, которые, как нам кажется, больше ориентируются на общественное благо, чем на мелкий эгоизм. Поэтому большая часть раздела, посвящённого безопасности в браузере, снабжена ссылками на работы Скотта Хелме (Scott Helme) и компании. Он вложил много сил в то, чтобы эти новые возможности по обеспечению безопасности стали доступны и понятны разработчикам.

Конечно, это не исчерпывающее руководство. Существует почти столько же способов писать небезопасный код, сколько способов самого написания кода. Безопасность — это больше мышление, чем цель. Мы надеемся, что с помощью всего сказанного и приведённых ниже источников разработчики с сегодняшнего дня смогут создавать защищённые PHP-приложения.

Источники

Если вы уже изучили всё предложенное и хотите больше, почитайте курируемый нами список по изучению безопасности приложений.

Если вы считаете, что адекватно пишете безопасный код, и хотите покритиковать нас с точки зрения инженера по безопасности, то именно такую услугу мы и предлагаем своим клиентам.

Если вы работаете в компании, которая заинтересована в оценке соответствия требованиям (PCI-DSS, ISO 27001 и т. д.), можете нанять нас для аудита своего исходного кода. Мы работаем гораздо более дружественно к разработчикам, чем другие консультанты по безопасности.

Ниже — список источников от PHP-сообщества и сообщества по информационной безопасности.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *