На страже безопасности JavaScript

На страже безопасности JavaScript

От автора: как написать код, который не делает того, чего не должен. Иногда нас, разработчиков, просят выполнять много разных задач. Мне приходилось быть графическим дизайнером для создания CSS, антропологом, работающим с сорока языками I18N / L10N, или детективом, собирающим воедино историю логов, чтобы найти ошибку в устаревшем коде.

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

Заставьте язык работать на себя

Представьте, что вас попросили просмотреть этот код:

Бесплатный курс «Full-Stack практика»

Изучите курс и создайте веб-приложение с нуля на JavaScript, NodeJS, ExpressJS

Получить курс

Это делает то, что нужно, но все равно глубоко ошибочно.

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

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

Это более многословно, но данная функция не тесно связана с непроверенными предположениями безопасности клиентов. (Позже я покажу, как сохранить код минимальным.)

Доверенные процессы не фильтруются

Представьте, что вы отвечаете за помощь разработчикам в создании безопасного кода. Вы бы предпочли услышать:

или же

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

Первый аргумент основан на фильтрации. Это действительно трудно понять правильно (подсказка: в HTML ‘:’ и ‘\:’ означают одно и то же), и, поскольку программа развивается, фильтры, как правило, со временем ослабевают, поскольку во время тестирования ложные срабатывания легче найти, чем ложно-отрицательные.

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

Проверьте предположения, прежде чем сделать то, что вы не сможете отменить

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

Будет беда, если злоумышленник сможет вызвать:

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

Кстати, предложение по Надежным типам идентифицирует критические точки в DOM, и добавляет патчи для выполнения проверок вокруг этих точек. В Google мы используем JSConformance, чтобы увести разработчиков от этих критических точек и предоставить безопасные оболочки.

Используйте инструменты, на которые вы можете полагаться

Пример makeLink(…) немного причудливый. (Автор хотел, чтобы один пример охватывал всю статью.)

Бесплатный курс «Full-Stack практика»

Изучите курс и создайте веб-приложение с нуля на JavaScript, NodeJS, ExpressJS

Получить курс

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

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

Языки шаблонов, которые понимают различные контексты, в которых фигурируют url и linkText, могут принимать во внимание ваши решения при использовании TrustedHTML или TrustedURL, обеспечивая при этом безопасность при работе с простыми строками.

HTML не единственный язык, который создают программы Node. В «Дорожной карте по безопасности Node.js» я написал, что шаблоны строк с тегами обеспечивают баланс безопасности и простоты использования.

Например, safesql понимает синтаксис строк SQL, а тег sh понимает синтаксис bash и sh, поэтому вы можете использовать его вывод с child_process.

Запланированные ошибки

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

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

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

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

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

Через уязвимый код не может утечь то, чего он не содержит

Представьте, что ваш коллега пишет веб-сервис, который выдает ответ JSON, когда пользователь запрашивает свой список друзей.

Они тестируют веб-сервис и видят, что он производит массив вроде [ { "displayName": "ILikeCats", "userId": "A01F" } ]. Позже я хочу сделать более подробный ответ для текущего пользователя. Я добавляю поле homeAddress к тому же классу Account, что использовал мой коллега.

Мы склонны полагать, что добавление в API не нарушит существующий код, но мое добавочное изменение теперь приводит к утечке через запрос коллеги PII: [ { "displayName": "ILikeCats", "userId": "A01F", "homeAddress": "..." } ]

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

Относитесь к JavaScript как к динамическому языку

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

Это прекрасное изменение, но вы не должны удалять код, который проверяет входные данные. TypeScript делает прагматические предположения, так что, даже если нет ошибок типа, значение переменной может не соответствовать ее типу. Если вы не уверены (или вы фанат TS):

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

Несоответствие типов определяет «доверенный» класс типов, но TypeScript не распознает нарушения типов.

«Очень простой фрагмент кода» предлагает вам попытаться выяснить, как атаковать фрагмент JS, который все еще уязвим при добавлении типов.

Уровень защиты

Я использовал везде XSS в качестве примера проблемы безопасности, так как разработчики знакомы с ним, но некоторые могут сказать: «Почему я должен беспокоиться о XSS? Я использую строгую Content-Security-Policy».

Я бы не сказал: «Я ношу защитный шлем, поэтому мне не нужны защитные очки». Когда вы создаете защитные слои, в данном случае Content-Security-Policy, и безопасные методы кодирования, злоумышленник должен обойти и то, и другое, чтобы повлиять на ваших пользователей.

Попросите помощи

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

Источник: https://www.javascriptjanuary.com/

Редакция: Команда webformyself.

Бесплатный курс «Full-Stack практика»

Изучите курс и создайте веб-приложение с нуля на JavaScript, NodeJS, ExpressJS

Получить курс

Безопасность и защита сайта от угроз и взлома

Прямо сейчас посмотрите видео

Смотреть

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Я не робот.

Spam Protection by WP-SpamFree