Руководство 2018 года по созданию безопасного программного обеспечения PHP!
содержание
- предисловие
- Версия PHP / Версии PHP
- Composer Управление зависимостями / Управление зависимостями с помощью Composer
- HTTPS и безопасность браузера / HTTPS и безопасность браузера
-
Разработка безопасных программ PHP / Разработка безопасного программного обеспечения PHP
- Внедрение базы данных / взаимодействие с базой данных
- Загрузка файлов / Загрузка файлов
- Межсайтовый скриптинг / Межсайтовый скриптинг (XSS)
- Подделка межсайтовых запросов (CSRF)
- XML-атаки / XML-атаки (XXE, XPath Injection)
- Десериализация и внедрение объектов PHP
- Хэширование пароля
- Криптография общего назначения
- Случайность
- HTTPS-запросы на стороне сервера / HTTPS-запросы на стороне сервера
- Чего следует избегать
- Специализированные варианты использования
- Несколько слов от автора / Слово от автора
- Ресурсы
предисловие
Приближается 2018 год, программисты общего профиля (особенно программисты веб-разработки) должны отказаться от многих вредных привычек и концепций программирования на PHP в прошлом. Хотя некоторым это не нравится, это правда.
Это руководство должно быть сосредоточено наPHP: The Right WayДополнение к главе о безопасности, а не общие темы программирования на PHP.
текст
PHP-версия
Пожалуйста, используйте PHP 7.2 в 2018 году и планируйте перейти на PHP 7.3 в начале 2019 года.
PHP 7.2 был выпущен 30 ноября 2017 года.
На момент написания этой статьи только версии 7.1 и 7.2 все еще активно поддерживаются официальными лицами PHP, в то время как версии 5.6 и 7.0 имеют обновления безопасности только примерно через год.
Для других официально не поддерживаемых версий PHP, хотя некоторые операционные системы предлагают долгосрочную поддержку и обслуживание, это часто вредно. В частности, они предоставляют исправления безопасности без номеров версий, что затрудняет объяснение безопасности системы (только зная версию PHP).
Поэтому, какие бы обещания ни давали другие поставщики, вы всегда должны придерживаться их, если можете.Официально поддерживаемые версии PHP. Таким образом, несмотря на то, что в конечном итоге это недолговечная безопасная версия, версия, которая постоянно работает над обновлением, всегда будет преподносить вам неожиданные сюрпризы.
управление зависимостями
Жизнь слишком коротка, я использую Composer
В экосистеме PHPComposerявляется самым передовым решением для управления зависимостями. Мы рекомендуем PHP: The Right Way оуправление зависимостямиполная глава.
Если вы не используете Composer для управления зависимостями вашего приложения, в конечном итоге (надеюсь, позже, но, скорее всего, раньше) зависимость в вашем приложении будет серьезно устаревать, и тогда уязвимости в старой версии будут использоваться для компьютерных преступлений.
важный: При разработке программного обеспечения всегда помнитеОбновляйте зависимости. К счастью, это всего лишь одна строка команды:
composer update
Если вы используете какой-то профессиональный, вам нужно использовать расширение PHP (написано на языке C), тогда вы не можете использовать управление Composer, но нужен PECL.
Рекомендуемое расширение
Независимо от того, что вы пишете, вы всегда будете в выигрыше от этих зависимостей. Это в дополнение к тому, что рекомендует большинство PHP-программистов (PHPUnit, PHP-CS-Fixer, ...).
roave/security-advisories
Roave's security-advisoriesиспользоватьFriends of PHP repositoryУбедитесь, что ваш проект не зависит от некоторых известных уязвимых зависимостей.
composer require roave/security-advisories:dev-master
Кроме того, вы можетезагрузить свойcomposer.lock
Файл в Sensio LabsКак часть рутинной уязвимости автоматизации, чтобы оценить рабочий процесс, чтобы напомнить об обнаружении любых устаревших пакетов.
vimeo/psalm
Psalm — это инструмент статического анализа, помогающий выявить возможные ошибки в коде. Существуют и другие хорошие инструменты статического анализа (например,PhanиPHPStanвеликолепны), но когда вы обнаружите, что вам нужна поддержка PHP 5, Psalm будет первым выбором для PHP 5.4+.
Использовать Псалом легко:
# Version 1 doesn't exist yet, but it will one day:
composer require --dev vimeo/psalm:^0
# Only do this once:
vendor/bin/psalm --init
# Do this as often as you need:
vendor/bin/psalm
Если вы запускаете его впервые в существующей кодовой базе, вы можете увидеть много красных ошибок. Но если вы не создаете программу размером с WordPress, попытка пройти все тесты не составит труда.
Независимо от того, какой инструмент статического анализа вы используете, мы рекомендуем вам добавить его вРабочий процесс непрерывной интеграции(рабочий процесс непрерывной интеграции) для запуска при каждом изменении кода.
HTTPS и безопасность браузера
HTTPS, which should be tested, and security headers .
В 2018 году небезопасные HTTP-сайты больше не будут приниматься. К счастью, благодаря протоколу ACME иLet's Encrypt certificate authority, возможны бесплатные сертификаты TLS.
Интегрируйте ACME в свой сервер с легкостью.
- Caddy: Автоматически присоединиться.
-
Apache: как только
mod_md
доступный. До этого,Множество качественных онлайн-уроков. - Nginx: относительно просто.
Вы можете подумать: «Хорошо, у меня уже есть сертификат TLS, потребуется некоторое время, чтобы возиться с информацией о конфигурации, чтобы сайт был безопасным и быстрым».
Нет!Мозилла хорошо поработала!. Вы можете использовать генератор конфигурации для созданияРекомендуемый комплект.
Если вы хотите, чтобы ваш сайт был безопасным, HTTPS (HTTP через TLS)абсолютно никаких компромиссовиз. Использование HTTPS сразу устраняет многие типы атак (злоумышленник посередине, прослушивание, воспроизведение и несколько атак в стиле сеанса, которые позволяют пользователям выдавать себя за других).
Голова безопасности
Использование HTTPS на сервере дает пользователям множество преимуществ в плане безопасности и производительности, но его также можно улучшить, воспользовавшись некоторыми функциями безопасности браузера. И большая часть этого будет связана с заголовками безопасности содержимого ответа.
-
Content-Security-Policy
- Вам нужен этот заголовок, потому что он обеспечивает детальный контроль над тем, разрешено ли браузеру загружать внутренние и внешние ресурсы, тем самым обеспечивая эффективный уровень защиты от эксплойтов междоменных сценариев.
- видетьCSP-Builderдля быстрого и простого развертывания/управления политиками безопасности контента.
- Для более глубокого анализа Скотт Хелмintroduction to Content-Security-Policy headers, было бы хорошим руководством.
-
Expect-CT
- Вам нужен этот заголовок, потому что он добавляет уровень защиты от мошеннических/скомпрометированных центров сертификации, вынуждая некоего злоумышленника выдать свидетельство своего плохого сертификата в публично проверяемую структуру данных только для добавления.
- Установлен приоритет
enforce,max-age=30
. Пока вы достаточно уверены, что заголовок не вызовет прерывания обслуживания, увеличьтеmax-age
Бар.
-
Referrer-Policy
- Вам нужен этот заголовок, потому что он позволяет вам контролировать, передается ли информация о поведении пользователя третьим лицам.
- Точно так же Скотт Хелме предоставляетХорошая статья о заголовке Referrer-Policy.
- Если нет причин разрешать более разрешающую настройку, установите
same-origin
илиno-referrer
.
-
Strict-Transport-Security
- Вам нужен этот заголовок, потому что он говорит браузеру устанавливать будущие запросы с тем же источником через HTTPS вместо небезопасного HTTP.
- При первом развертывании установите для него значение
max-age = 30
, затем увеличьте это значение до некоторого большого значения (например, 31536000), когда будете уверены, что ничего не сломается.
-
X-Content-Type-Options
- Вам нужен этот заголовок, потому что обфускация типа MIME может привести к непредсказуемым результатам, в том числе странным пограничным случаям, которые допускают уязвимости XSS. Это лучше всего сопровождать стандартным заголовком Content-Type.
- Установлен в
nosniff
.
-
X-Frame-Options
- Вам нужен этот заголовок, потому что он позволяет предотвратить кликджекинг.
- Установить как
DENY
(илиSAMEORIGIN
, но только при использовании<frame>
элемент).
-
X-XSS-Protection
- Вам нужен этот заголовок, потому что он включает некоторые анти-XSS-функции браузера, которые не включены по умолчанию.
- Установить как
1; mode=block
.
Опять же, если вы используете встроенные функции управления сеансом PHP (рекомендуется), вам может понадобиться вызвать этотsession_start()
:
<?php
session_start([
'cookie_httponly' => true,
'cookie_secure' => true
]);
Это заставляет ваше приложение использовать флаги HTTP-Only и Secure при отправке идентификаторов сеанса, предотвращая XSS-атаки от кражи файлов cookie пользователей, и заставляет их отправлять по HTTPS соответственно. Ранее мы рассказывали в сообщении блога 2015 года.Безопасный сеанс PHP.
Целостность субресурсов
В какой-то момент в будущем вы можете использовать CDN для загрузки общедоступных библиотек JavaScript/CSS вашего веб-сайта. Инженеры по безопасности увидели, что существует явный риск того, что, если многие веб-сайты используют CDN для обслуживания контента, взломы и замена CDN (получение контроля над CDN) могут внедрить (вредоносный) код на тысячи веб-сайтов.
чекЦелостность субресурсовБар.
Целостность подресурсов (SRI, целостность подресурсов) вы захотите разрешить содержимое хеширования файлов сервисов CDN. В настоящее время SRI позволяет использовать только безопасные криптографические хеш-функции, что означает, что злоумышленник не может сгенерировать тот же хэш, что и исходный файл вредоносной версии ресурса.
Реальный пример:Bootstrap v4-alpha uses SRI in their CDN example snippet
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"
integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ"
crossorigin="anonymous"
/>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"
integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn"
crossorigin="anonymous"
></script>
документировать отношения
Веб-разработчики часто устанавливают целевые свойства гиперссылок (например,target ="_ blank"
ссылка откроется в новом окне). Однако, если вы не пройдетеrel ="noopener"
этикетка, вы можетеРазрешить целевой странице управлять текущей страницей.
Не делай это:
<a href="http://example.com" target="_blank">Click here</a>
Это сделаетhttp://example.com
Страница управляет текущей страницей.
Вместо этого он должен делать:
<a href="https://example.com" target="_blank" rel="noopener noreferrer">Click here</a>
Открывается в новом окне, делая этоhttps://example.com
, контроль над текущим окном также не предоставляется потенциально злонамеренному третьему лицу.
Можно поподробнееУглубленное изучение.
Разрабатывать безопасные PHP-программы
Если безопасность приложений — новая для вас тема, начнитеВведение в безопасность приложенийДавайте начнем.
Большинство экспертов по безопасности отмечают, что разработчики могут использоватьOWASP Top 10Ожидание запуска ресурсов.
Тем не менее, наиболее распространенными уязвимостями могут быть проблемы с безопасностью того же высокого уровня (например, код и данные не полностью разделены, логика не является строгой и надежной, операционная среда небезопасна или не поддаются расшифровке криптографических протоколов и т. д.).
Наше предположение заключается в том, что новичку в области безопасности следует дать знать некоторые более простые базовые знания и проблемы в области безопасности, а также то, как решить эти проблемы, должно стать лучшим долгосрочным проектом по обеспечению безопасности.
следовательно,Мы не рекомендуем топ-10 или 20 безопасных списков..
внедрение базы данных
Если вы пишете код SQL самостоятельно, обязательно используйтеprepared
Заявления и информация, предоставленная из сети или файловой системы, передаются как параметры, а не в виде конкатенации строк. Кроме того, убедитесь, что выПодготовленный оператор без использования макета.
Для хороших результатов можно использоватьEasyDB.
Не делай это:
<?php
/* Insecure code: */
$query = $pdo->query("SELECT * FROM users WHERE username = '" . $_GET['username'] . "'");
следует сделать:
<?php
/* Secure against SQL injection: */
$results = $easydb->row("SELECT * FROM users WHERE username = ?", $_GET['username']);
Существуют и другие уровни абстракции базы данных, обеспечивающие такую же безопасность (EasyDB на самом деле использует PDO, но на самом делеprepare
избегается перед заявлениемprepared
имитация высказывания). Безопасен (включая хранимые процедуры), если пользовательский ввод не влияет на структуру запроса.
Файл загружен
Глубоко:Как безопасно разрешить пользователям загружать файлы?
Принимая загрузка файлов - это рискованное предложение, но безопасно предпринять некоторые основные меры предосторожности. То есть, если файлы могут быть загружены напрямую, эти файлы могут быть случайно разрешены выполнять или интерпретировать. Загруженные файлы должны быть только для чтения или записи чтения и никогда не должны быть исполнены.
Если корневая директория вашего сайта/var/www/example.com
, пожалуйста, не сохраняйте загруженный файл в/var/www/example.com/uploaded_files
.
Вместо этого сохраните в каталог, к которому нет прямого доступа (например:/var/www/example.com-uploaded/
), чтобы избежать случайного запуска его как сценария на стороне сервера и получения бэкдора для удаленного выполнения кода.
Более аккуратный подход — переместить корень веб-сайта на один уровень вниз (т.е.:/var/www/example.com/public
).
Как безопасно загрузить эти загруженные файлы, также является проблемой.
- При прямом доступе к типу изображения SVG код JavaScript выполняется в браузере пользователя. несмотря на то чтов своем MIME-типе
image/
префикс вводит в заблуждение, но это правильно. - Как упоминалось ранее, прослушивание типов MIME может привести к атакам с путаницей типов. видетьX-Content-Type-Options.
- Если вы откажетесь от предыдущего совета о том, как безопасно хранить загруженные файлы, злоумышленник может получить полный контроль над сервером, загрузив файл .php или .phtml и получив доступ к файлу непосредственно в браузере для выполнения произвольного кода.
межсайтовый скриптинг
Вот все, что вам нужно знать о межсайтовом скриптинге в PHP.
Точно так же предотвратить XSS так же просто, как SQL-инъекцию. У нас есть простые и удобные в использовании API для разделения структуры документа и заполненных данных.
Тем не менее, все еще есть много программистов веб-разработки, которые все еще разрабатывают, генерируя в ответ большую строку HTML-кода. И это не является уникальной реальностью для PHP, это то, о чем должны знать все программисты веб-разработки.
Это хороший способ уменьшить XSS-уязвимости. В заключение вышеизложенноеГлава о безопасности браузеракажется очень актуальным. Короче:
- Старайтесь избегать вывода и ввода (
Always escape on output, never on input
). Если вы храните очищенные данные в базе данных, а уязвимость SQL-инъекции обнаруживается где-то еще, злоумышленники заражают запись, доверенную для очистки, вредоносными программами, тем самым обходя XSS-защиту. - Если в вашем фреймворке есть механизм шаблонов, обеспечивающий автоматическую фильтрацию контекста, используйте его. Эти работы могут быть безопасно выполнены фреймворком.
-
echo htmlentities($ string,ENT_QUOTES | ENT_HTML5,'UTF-8')
— это безопасный и эффективный способ блокировать все атаки XSS на веб-страницы в кодировке UTF-8, но не на любой HTML. - Если ваша среда требует использования Markdown вместо HTML, не используйте HTML.
- Если вам нужно использовать собственный HTML (без использования механизма шаблонов), см. пункт 1 и используйтеHTML PurifierБар. HTML Purifier не подходит для перехода в контекст атрибута HTML.
Подделка межсайтовых запросов
Подделка межсайтовых запросов (CSRF) — это запутанная прокси-атака, которая заставляет браузер пользователя выполнять вредоносные HTTP-запросы (с использованием разрешений пользователя) от имени злоумышленника.
Это легко решить в общем случае, всего в два шага:
- Используйте HTTPS. Это обязательное условие. Без HTTPS любая защита уязвима, хотя сам HTTPS не защищает от CSRF.
- Добавлена базовая аутентификация вызов-ответ.
- Добавьте свойство скрытой формы в каждую форму.
- Заполняется криптографически безопасным случайным значением (называемым токеном).
- Убедитесь, что скрытые атрибуты формы предоставлены и соответствуют ожидаемым значениям.
Мы написалиAnti-CSRFбиблиотека и:
- Вы можете сделать каждый токен только один раз, чтобы предотвратить воспроизведение атак.
- Несколько токенов хранятся в бэкэнде.
- Как только токен будет получен, токен будет переработан.
- Каждый токен может быть привязан к определенному URL-адресу.
- В случае утечки токена его нельзя использовать в другом контексте.
- Токены могут быть привязаны к определенным IP-адресам.
- После версии 2.1 токены можно использовать повторно (например, для использования Ajax).
Если вы не используете фреймворк для предотвращения уязвимостей CSRF, отложите Anti-CSRF в сторону. В ближайшем будущем,Файлы cookie SameSite позволят нам легче избегать атак CSRF..
XML-атака (XXE, внедрение XPath)
В приложениях, обрабатывающих большие объемы XML, есть две основные уязвимости:
- XML External Entities (XXE)
- XPath-инъекция
Кроме, атаки XXE могут использоваться в качестве средств запуска для локальных/удаленных файлов, содержащих код атаки.
Ранние версии Google Docs были известны как XXE , но в основном о них не слышали, за исключением коммерческих приложений, которые в значительной степени использовали XML.
Основные средства защиты от XXE-атак:
<?php
libxml_disable_entity_loader(true);
Помимо XML-документов,XPath-инъекцияОчень похоже на SQL-инъекцию.
К счастью, передача пользовательского ввода в запрос XPath очень редка в экосистеме PHP.
И, к сожалению, это также означает, что нет лучших мер избегания (предложенные и параметризованные запросы XPath), доступных в экосистеме PHP. Ваша лучшая ставка - установить белый список разрешенных символов на любые данные, которые включают запрос XPath.
<?php
declare(strict_types=1);
class SafeXPathEscaper
{
/**
* @param string $input
* @return string
*/
public static function allowAlphaNumeric(string $input): string
{
return \preg_replace('#[^A-Za-z0-9]#', '', $input);
}
/**
* @param string $input
* @return string
*/
public static function allowNumeric(string $input): string
{
return \preg_replace('#[^0-9]#', '', $input);
}
}
// Usage:
$selected = $xml->xpath(
"/user/username/" . SafeXPathEscaper::allowAlphaNumeric(
$_GET['username']
)
);
Белый список всегда безопаснее черного списка.
Десериализация и внедрение объектов PHP
Если вы передаете ненадежные данные вunserialize()
, обычно это один из следующих двух результатов:
- Внедрение объектов PHP, которое можно использовать для запуска цепочки POP и запуска других эксплойтов для неправомерного использования объектов.
- Повреждение памяти в самом интерпретаторе PHP.
Большинство разработчиков предпочитают использовать сериализацию JSON, что значительно повышает уровень безопасности их программного обеспечения. Но помни,json_decode()
Уязвимость к атакам типа «отказ в обслуживании» (Hash-DoS) с коллизией хэшей. К несчастью,Проблема PHP Hash-DOS не решена полностью.
отdjb33
переехал вSiphash
, старший бит хэш-вывода устанавливается равным 1 для строкового ввода и 0 для целочисленного ввода, используяCSPRNG
Предоставленный ключ запроса полностью устранит эти атаки.
К сожалению, команда PHP не готова отказаться от прироста производительности, достигнутого в серии PHP 7, поэтому трудно убедить их отказаться от djb33 (который очень быстр, но небезопасен) в пользу SipHash (который тоже быстро, но не безопасно) так же быстро, как djb33, но безопаснее). Если производительность значительно пострадает, это может помешать принятию будущих версий, но также повлияет на безопасность.
Итак, лучше всего сделать следующее:
- использовать
JSON
, потому что большеunserialize()
безопаснее. - По возможности убедитесь, что ввод аутентифицирован перед десериализацией.
- Для данных, предоставляемых пользователю, используйте секретный ключ, известный только серверу.
sodium_crypto_auth()
иsodium_crypto_auth_verify()
проверять. - Для данных, предоставленных третьими лицами, разрешите им использовать
sodium_crypto_sign()
подпишите свое сообщение JSON, затем используйтеsodium_crypto_sign_open()
и сторонние открытые ключи для аутентификации сообщений.- Если вам необходимо, чтобы подпись передавалась в шестнадцатеричной или Base64-битной кодировке, вы можете использовать отдельный API подписи.
- Для данных, предоставляемых пользователю, используйте секретный ключ, известный только серверу.
- Если вы не можете проверить строку JSON, строго ограничьте скорость и заблокируйте IP-адреса, чтобы снизить риск повторных нарушителей.
хэш пароля
Глубоко:Как безопасно хранить пароли пользователей в 2016 году
Безопасное хранение паролей раньше было горячо обсуждаемой темой, но теперь довольно просто реализовать, особенно в PHP:
<?php
$hash = \password_hash($password, PASSWORD_DEFAULT);
if (\password_verify($password, $hash)) {
// Authenticated.
if (\password_needs_rehash($hash, PASSWORD_DEFAULT)) {
// Rehash, update database.
}
}
Вам даже не нужно знать, какой алгоритм используется под капотом, потому что, если вы используете последнюю версию PHP, вы также будете использовать новейшие технологии, и пароли пользователей будут обновляться автоматически (пока новые алгоритмы по умолчанию доступны).
Не важно, что вы делаете,Не делайте вещи, которые делают WordPress.
С PHP 5.5 до 7.2 алгоритмом по умолчанию является Bcrypt. В будущем он может переключиться на получениеПобедитель конкурса хэшей паролейАргон2.
Если вы не использовалиpassword_*
API, который требует переноса устаревших хэшей, убедитесь, чтодействовать. Многие компании ошибаются, наиболее известныеYahoo. В последнее время неправильная реализация традиционных обновлений хэша, похоже, привела кОшибка iamroot от Apple.
Универсальное шифрование
Вот некоторые из тем, о которых мы подробно писали:
- Using Encryption and Authentication Correctly (2015)
- Recommended: Choosing the Right Cryptography Library for your PHP Project: A Guide (2015)
- Recommended: You Wouldn't Base64 a Password - Cryptography Decoded (2015)
- Cryptographically Secure PHP Development (2017)
- Recommended: Libsodium Quick Reference: Similarly-Named Functions and Their Use-Cases (2017)
В общем, вы всегда должны использовать криптографическую библиотеку Sodium (libsodium) для шифрования на уровне приложения. Если вам нужно поддерживать версии PHP до 7.2 (например, 5.2.4), вы можете использоватьsodium_compat, в основном предполагая, что ваш пользователь также 7.2.
В определенных случаях вам могут понадобиться разные библиотеки из-за строгого выбора алгоритма и совместимости. Если вы сомневаетесь, проконсультируйтесь с экспертом по криптографии и инженером-криптографом, чтобы убедиться, что выбранный вами пароль является безопасным (Это одна из услуг, которые мы предоставляем).
Случайность
Глубоко:Как генерировать безопасные целые числа и строки в PHP?
Если вам нужны случайные числа, используйтеrandom_int()
. Если вам нужны случайные строки байтов, используйтеrandom_bytes()
. Не используйmt_rand()
,rand()
илиuniqid()
.
Если вам нужно генерировать псевдослучайные числа из секретного начального числа, используйтеSeedSpring, вместоsrand()
илиmt_srand()
.
<?php
use ParagonIE\SeedSpring\SeedSpring;
$seed = random_bytes(16);
$rng = new SeedSpring($seed);
$data = $rng->getBytes(1024);
$int = $rng->getInt(1, 100);
HTTPS-запросы на стороне сервера
Убедитесь, что проверка сертификата TLS не отключена
Не стесняйтесь использовать любой HTTP-клиент, совместимый с PSR-7, с которым вы уже знакомы. Мы любим Guzzle, и некоторые люди предпочитают использовать cURL напрямую.
Что бы вы в конечном итоге ни использовали, убедитесь, что используете это с уверенностью, чтобыУбедитесь, что у вас всегда есть последний пакет CACert, что позволяет включить самые строгие настройки проверки сертификата TLS и защитить исходящие HTTPS-запросы к серверу.
Установить Certainty очень просто:
composer require paragonie/certainty:^1
Использовать Certainty также просто:
<?php
use ParagonIE\Certainty\RemoteFetch;
$latestCACertBundle = (new RemoteFetch())->getLatestBundle();
# cURL users:
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_CAINFO, $latestCACertBundle->getFilePath());
# Guzzle users:
/** @var \GuzzleHttp\Client $http */
$repsonse = $http->get(
'https://example.com',
[
'verify' => $latestCACertBundle->getFilePath()
]
);
Это защищает среднюю атаку между любым третьим сторонним API от вашего сервера и сетевой интеграции.
Нужна ли нам уверенность?
Для защиты вашей системы уверенность не является строго обязательной. Его отсутствие не является ошибкой. Но без уверенности программное обеспечение с открытым исходным кодом должно угадывать, где находится пакет CACert ОС, и если оно ошибается, оно, как правило, дает сбой и вызывает проблемы с удобством использования. Исторически сложилось так, что многие разработчики просто отключали проверку сертификатов, чтобы их код «просто работал», не осознавая, что они просто превращают приложение в активную атаку. Определенность устраняет этот стимул, привязывая CACert к последнему предсказуемому местоположению. Уверенность также для надеждыЗапустите собственный внутренний ЦСПредоставляет большое количество инструментов для бизнеса.
Кто отключил проверку сертификата?
Разработчик плагинов/расширений для популярных систем управления контентом (WordPress, Magento и др. CMS)! Это огромная проблема, которую мы пытаемся решить на уровне экосистемы. Он не привязан к какой-либо конкретной CMS, вы обнаружите, что эти небезопасные плагины и т. д. все похожи.
Если вы используете аналогичные CMS, пожалуйста, поищи плагинCURLOPT_SSL_VERIFYPEER
иCURLOPT_SSL_VERIFYHOST
, вы можете найти несколько, которые устанавливают эти значения наFALSE
.
вещи, которых следует избегать
-
Не используй
mcrypt
. Это криптографическая библиотека, которая не разрабатывалась более десяти лет. Это должно быть легко избежать ошибки, если вы будете следовать нашему совету по версии PHP, потому чтоmcrypt
Больше не поддерживает PHP 7.2 и позже. -
Настроить совет безопасности драйверовследует в основном игнорировать. Если вы читаете Руководство по безопасности PHP, в котором вам предлагается изменить настройки php.ini вместо написания лучшего кода, вы, вероятно, читаете устаревшие советы. закрыть окно и пойти в некоторые и
register_globals
В не связанной статье. - Не используйте JOSE (JWT, JWS, JWE), набор интернет-стандартов, который систематизирует серию подверженных ошибкам паролей. Хотя по какой-то причине это было прописано в стандарте, оно также привлекло многих проповедников.
- Зашифровать параметры URLОн часто используется компанией для нечетких метаданных (например, сколько у нас пользователей?). Это влекло за собой высокий риск ошибок реализации, вызывая чувство безопасности. В статье выдвигаем более безопасный вариант.
- Без принуждения, иначеНе предлагать функцию «Я забыл пароль». Не заблуждайтесь: функция сброса пароля — это лазейка. Существуют методы, которые можно реализовать для защиты от разумных моделей угроз, но не следует рассматривать пользователей с высоким уровнем риска.
- Избегайте RSA, используйте вместо этого libsodium. Если вы должны использовать RSA, обязательно укажите заполнение OAEP.
<?php
openssl_private_decrypt(
$ciphertext,
$decrypted, // Plaintext gets written to this variable upon success,
$privateKey,
OPENSSL_PKCS1_OAEP_PADDING // Important: DO NOT OMIT THIS!
);
Если вам нужно использовать заполнение PKCS#1 v1.5, то независимо от того, с каким из них вы интегрируетесь, на вас почти наверняка повлияетROBOTInfluence, сообщите об этом соответствующему поставщику (или US-CERT), чтобы разрешить утечку открытого текста и уязвимости для подписанной подделки.
Профессиональное использование
Теперь, когда вы освоили основы создания безопасных приложений PHP в 2018 году и позже, давайте рассмотрим более специализированное использование.
Шифрование с возможностью поиска
Глубоко:Создайте зашифрованную базу данных с возможностью поиска с помощью PHP и SQL
Зашифрованные базы данных с возможностью поиска желательны, но многие считают маловероятным. Сообщение в блоге, указанное выше, пытается сделать это, улучшая наше решение, но по сути это выглядит примерно так:
- Разработайте свою схему, чтобы компромисс базы данных не дает атакующим доступа к вашим ключам шифрования.
- Зашифровать данные с помощью ключа.
- Создайте несколько индексов (со своими уникальными ключами) на основе HMAC или защитите KDF с помощью статической соли.
- Необязательно: обрежьте вывод шага 3 и используйте его как фильтр Блума.
- Используйте результат шага 3 или 4 в запросе SELECT.
- расшифровать результат.
На любом этапе процесса вы можете пойти на различные компромиссы в зависимости от фактического использования.
Нет боковых каналов для аутентификации на основе токена
Глубоко:Split Tokens: Token-Based Authentication Protocols without Side-Channels
Говоря о базах данных (предыдущий раздел), знаете ли вы, что запросы SELECT теоретически могут быть источником утечек информации о времени?
Простые меры:
- разделить токен аутентификации пополам
- половина используется в запросах SELECT
- Вторая половина проверяется за постоянное время
- При желании сохраните хэш второй половины в базе данных. Это имеет смысл для токенов, которые можно использовать только один раз, например для сброса пароля или токенов «запомнить меня на этом компьютере».
Даже если вы можете использовать синхронизированную утечку, чтобы украсть половину токена, для успеха остальной части также потребуется насильственный взлом.
Разрабатывайте безопасные API
мы написалиSAPIENT(Secure API ENgineering Toolkit), чтобы упростить и упростить обмен сообщениями с проверкой подлинности между серверами. В дополнение к безопасности, обеспечиваемой HTTPS,Sapient
Позволяет шифровать и аутентифицировать сообщения с помощью общего секретного или открытого ключа. Это позволяет даже злоумышленнику посередине с мошенническим центром сертификации использоватьEd25519
Проверяйте подлинность запросов и ответов API или шифруйте сообщения на целевой сервер, которые можно расшифровать только с помощью ключа сервера-получателя. Поскольку каждое тело HTTP-сообщения аутентифицируется безопасным паролем, его можно безопасно использовать вместоstateful token juggling protocols
(например, OAuth). Однако, когда дело доходит до криптографии, всегда убедитесь, что их реализации исследованы экспертами, прежде чем делать что-то нестандартное.
всеSapient
Используемые криптографические алгоритмыSodium cryptography library
поставка.
Дальнейшее чтение:
Paragon Initiative Enterprises
Уже используется во многих своих продуктах, в том числе во многих проектах программного обеспечения с открытым исходным кодом.Sapient
,
и будет продолжать добавлять элементы программного обеспечения вSapient
в группе пользователей.
Регистрируйте события безопасности с помощью Chronicle
Глубоко:Chronicle Will Make You Question the Need for Blockchain Technology
Chronicleпредставляет собой криптографическую книгу только для добавления, основанную на структуре данных хэш-цепочки, со многими атрибутами, которые без излишеств обращаются к технологии «блокчейн» компаний.
В дополнение к творческому варианту использования криптографической книги только для добавления,Chronicle
Также может быть очень шустрым при интеграции в SIEM, так как вы можете отправлять критичные для безопасности события в приватныйChronicle
, и их нельзя изменить.
если вашChronicle
Установите перекрестную подпись своего хэша дайджеста с другимChronicle
экземпляр, или если есть другие экземпляры, настроенные для репликации вашегоChronicle
Содержание, для атакующего очень сложно вмешиваться в систему вашего журнала событий безопасности.
существуетChronicle
С помощью вы можете получить устойчивость, которую обещает блокчейн, без каких-либо проблем с конфиденциальностью, производительностью или масштабируемостью.
Чтобы опубликовать данные локальноChronicle
, вы можете использовать любойSapient-compatible API, но самое простое решение называетсяQuill.
Несколько слов от автора
Некоторые проницательные читатели могут заметить, что мы цитируем много собственных работ, включая сообщения в блогах и программное обеспечение с открытым исходным кодом. (и, конечно, не только цитируя нашу собственную работу)
Это не случайно.
С момента основания в начале 2015 года мы писали библиотеки безопасности и участвовали в повышении безопасности экосистемы PHP. Мы многое сделали, и наши инженеры по безопасности (которые недавно внедрили более безопасную криптографию в ядро PHP, совсем недавно, в PHP 7.2), самоуверенные, не очень хорошо разрекламированы или игнорируют то, что уже есть. Сделано.Прошел работу с постоянным энтузиазмом. Но есть вероятность, что вы не слышали об инструментах или библиотеках, которые мы разрабатывали годами. Прошу прощения.
В любом случае, мы не можем быть первопроходцами во всех аспектах, поэтому мы выбираем и максимально ценим общественный интерес, а не работу специалистов отрасли, жадных до небольшой прибыли. Вот почему на многие главы, посвященные безопасности браузера, ссылаютсяScott HelmeИ работа его компании, они доступны и понятны в том, чтобы сделать эти новые функции безопасности доступными для разработчиков.
Это руководство, конечно, не будет исчерпывающим. Способов написать небезопасный код почти столько же, сколько способов написать код.Безопасность — это состояние души, а не пункт назначения.Мы надеемся, что со всем написанным выше и привлеченными позже ресурсами это поможет разработчикам во всем мире начать писать безопасное программное обеспечение на PHP уже сегодня.
ресурс
Если вы следили за всем на этой странице и вам нужно больше, возможно, вас заинтересует наш кураторский список для чтения, чтобы узнать о безопасности приложений.
Если вы считаете, что написанный вами код достаточно безопасен, и хотите, чтобы мы оценили его с точки зрения инженера по безопасности, мы делаем это для наших клиентов.
Если вы работаете в компании, которая занимается тестированием на соответствие (PCI-DSS, ISO 27001 и т. д.), вы также можете нанять нашу компанию для проверки вашего исходного кода. Наш процесс более удобен для разработчиков, чем другие консалтинговые фирмы по безопасности.
Далее следует список ресурсов от сообществ PHP и информационной безопасности, которые помогают сделать Интернет более безопасным.
-
PHP: The Right Way: Практическое руководство по современной PHP-разработке, бесплатный онлайн.
-
Let's Encrypt: Управление сертификатом, который многое сделал для создания более безопасного Интернета, предлагая бесплатные сертификаты TLS.
-
Qualys SSL Labs: предоставляет быстрый и простой набор тестов для конфигурации TLS. Почти все используют это для решения своих проблем с набором шифров и сертификатами, и на то есть веские причины:It does its job well.
-
Security Headers: позволяет проверить, насколько хорошо ваш сайт использует функции безопасности браузера для защиты пользователей.
-
Report-URI: отличный бесплатный ресурс, который предоставляет службу отчетов о безопасности в режиме реального времени, которая отслеживает политики безопасности, такие как CSP/HPKP. Они дают вам Report-URI, который вы можете передать в браузер вашего пользователя, и если что-то случится или кто-то обнаружит вектор атаки XSS, они пожалуются на Report-URI. Report-URI объединяет эти ошибки и позволяет лучше устранять неполадки и сортировать эти отчеты.
-
PHP Security Advent Calenda:RIPSTechЕго команда несет ответственность.
-
Snuffleupagus: модуль PHP, ориентированный на безопасность (SuhosinПсихический преемник, кажется, в значительной степени уделяется)
-
PHP Delusions: веб-сайт, посвященный лучшему использованию PHP. Большая часть тона очень проницательна, и приверженность автора технической точности и ясности делает его достойным прочтения, особенно для тех, кто не слишком любит функции PDO.
-
Have I Been Pwned?: помогает пользователям определить, не являются ли их данные устаревшей утечкой данных.
конец
Оригинальный адрес:The 2018 Guide to Building Secure PHP Software - P.I.E. Staff
Впервые он был опубликован в сообществе Laravel China —The 2018 Guide to Building Secure PHP SoftwareЯ видел, что одноклассник прислал только оригинальную ссылку.Поскольку она полностью на английском языке и статья относительно длинная, я не читал ее подробно, но я могу знать, что это очень хорошая статья и стоит изучения.Я потратил время на перевод это в наши дни полный текст.
Чтобы избежать двусмысленности, некоторые профессиональные условия и предложения были сохранены в своих оригинальных текстах. Процесс перевода использовал Google и Google Translate. Мои английские и связанные профессиональные навыки ограничены. Если есть какие-либо ошибки, спасибо за указание поправок.