Запуск веб-сайта в первые годы работы в Интернете был страшным делом. Сеть была развивающейся средой, и люди находили новое применение для нее почти каждый день. В книжных магазинах на интернет-аукционах сеть была расширяющейся вселенной новых возможностей.
По мере развития сети, так же стало известно о присущих ей уязвимостях безопасности. Умные трюки, которые были сыграны на одном сайте, можно было скопировать буквально на сотни других сайтов. Это был нормальный взгляд, чтобы войти на сайт, чтобы не найти ничего работающего, потому что кто-то нарушил его защиту и удалил свою базу данных. Уроки в сфере безопасности в те дни были с трудом заработаны.
Ниже приводятся примеры критических ошибок, которые привели к нескольким ранним сайтам и как вы можете помочь защитить себя и свою команду от той же участи.
Содержание статьи
- 1 Плохая проверка ввода: доверяя чему-либо, что пользователь отправляет вам
- 2 SQL-инъекция: разрешение пользователю запускать собственные запросы к базе данных
- 3 Подделка подпроса: запрос другим пользователям сделать вашу грязную работу для вас
- 4 Межсайтовый скриптинг: код чужого кода, запущенный на вашем сайте
- 5 npm audit: Защитите себя от кода, которым вы не являетесь
- 6 Обеспечение безопасности вашего сайта, как и 2019 год
Плохая проверка ввода: доверяя чему-либо, что пользователь отправляет вам
Наша история начинается в самом маловероятном месте: Пересечение животных. Animal Crossing была видеоигрой 2001 года, установленной в причудливом городе, наполненном счастливыми жителями, которые сосуществуют мирно. Как и большинство видеоигр, Animal Crossing был предметом многих сообществ поклонников на раннем веб-сайте.
Один такой неофициальный веб-форум был посвящен игрокам, обсуждая их приключения в Animal Crossing. Игроки могут торговать секретами, обращаться за помощью и делиться фотографиями своих виртуальных домов. Это может показаться вам образцовым сообществом, но вы ошибаетесь .
Однажды игрок обнаружил скрытое поле в форме профиля пользователя форума. Обычно эта страница позволяет пользователям изменять свое имя, пароль или фотографию своего профиля. Этот человек обнаружил, что скрытое поле содержит уникальный идентификатор пользователя, который идентифицирует их, когда база данных форума сохраняет изменения профиля в своей базе данных. Они обнаружили, что, изменив форму для изменения идентификатора пользователя, они могут вносить изменения в профиль любого другого игрока .
Излишне говорить, что это идиллическое онлайн-сообщество спустилось в хаос. Пользователи изменили пароли друг друга, удалили друг другу сообщения и атаковали друг друга под прикрытием полной анонимности. Что случилось?
Нет никаких официальных правил для разработки программного обеспечения в Интернете. Но если бы это было, мое золотое правило было бы:
Никогда не доверяйте пользовательскому вводу. Когда-либо.
Всегда спрашивайте себя, как пользователи будут отправлять вам данные, которые не то, что кажется. Если самое приятное сообщество геймеров, играющих самую счастливую игру на земле, может переключиться друг на друга, нигде в Интернете не безопасно.
Убедитесь, что вы проверяете ввод пользователя, чтобы убедиться, что он правильный тип (например, строка, номер, строка JSON) и что это длина которую вы ожидали. Не забывайте, что пользовательский вход не станет безопасным после его сохранения в вашей базе данных; любые данные, которые происходят из-за пределов вашей сети, могут быть опасными и должны быть экранированы до того, как они будут вставлены в HTML.
Обязательно проверяйте действия пользователя против того, что им разрешено делать. Создайте прозрачную политику управления доступом, которая определяет, какие действия пользователь может предпринять, и к чьим данным им разрешен доступ. Например, новому зарегистрированному пользователю не разрешается изменять профиль пользователя владельца веб-форума.
Наконец, никогда не полагайтесь на проверку на стороне клиента. Проверка ввода пользователя в браузере является удобством для пользователя, а не мерой безопасности. Всегда предполагайте, что пользователь имеет полный контроль над любыми данными, отправленными из браузера, и убедитесь, что вы проверяете данные, отправленные на ваш сервер из внешнего мира .
SQL-инъекция: разрешение пользователю запускать собственные запросы к базе данных
Давным-давно мой любимый веб-сайт был веб-форумом, посвященным серии видеоигр Final Fantasy. Как и пользователи форума Animal Crossing я бы просил много часов спорить с другими людьми в Интернете о моих любимых персонажах, моих любимых историях и о величайших спорах дня.
Однажды я заметил, что люди действуют странно. Пользователи были нехарактерно неприятны и размещались в частных областях форума, к которым обычно не имели доступа. Затем сообщения начали исчезать, а учетные записи пользователей для уважаемых людей были запрещены.
Оказывается, кто-то обнаружил способ войти в любую другую учетную запись пользователя, используя секретный пароль, который позволял им делать буквально все, что они хотели. Каким был этот пароль, который предоставил неисчислимую силу тем, кто его обладал?
'OR' 1 '=' 1
SQL — это компьютерный язык, используемый для запросов к базам данных. Когда вы заполняете форму входа в систему, как и предыдущую, ваше имя пользователя и ваш пароль обычно вставляются в SQL-запрос следующим образом:
SELECT COUNT (*)
ПОЛЬЗОВАТЕЛЯ
WHERE USERNAME = 'Алиса'
И ПАРОЛЬ = 'hunter2'
Этот запрос выбирает пользователей из базы данных, которые соответствуют имени пользователя Алисе и паролю hunter2 . Если есть хотя бы одна совпадающая с пользователем запись, пользователю будет предоставлен доступ. Давайте посмотрим, что произойдет, когда мы используем наш волшебный пароль!
SELECT COUNT (*)
ПОЛЬЗОВАТЕЛЯ
WHERE USERNAME = 'Admin'
И ПАРОЛЬ = '' ИЛИ '1' = '1'
Предоставляет ли пароль часть запроса к вам? Это потому, что это так! Этот пароль является преднамеренной попыткой внедрить наш SQL-запрос в запрос, следовательно, термин SQL-инъекции . Запрос теперь ищет пользователей, соответствующих имени пользователя Admin с незаполненным паролем или 1 = 1 . В SQL-запросе 1 = 1 всегда истина что делает этот запрос в 19449007] каждой отдельной записи в базе данных. Пока программное обеспечение форума проверяет наличие хотя бы одного пользователя он предоставит лицу доступ к доступу. Этот пароль будет работать для любого пользователя, зарегистрированного на форуме!
Итак, как вы можете защитить себя от SQL-инъекции?
Никогда не создавайте SQL-запросы, объединяя строки. Вместо этого используйте параметризованные инструменты запросов. PHP предлагает подготовленные операторы, а Node.JS имеет пакет knex. В качестве альтернативы вы можете использовать инструмент ORM, например Propel или sequelize.
Экспертная помощь в виде языковых функций или программных средств является ключевым союзником для обеспечения безопасности вашего кода. Получите всю необходимую помощь!
Подделка подпроса: запрос другим пользователям сделать вашу грязную работу для вас
Вы помните Netflix? Не Netflix, который у нас есть, Netflix, который использовал для аренды ваших DVD-дисков, отправив их вам. Моя следующая история о том, как кому-то удалось убедить пользователей Netflix отправлять ему свои DVD-диски — бесплатно
Вы когда-нибудь нажимали на гиперссылку, только чтобы найти то, чего не ожидали? Если вам повезет, вы, возможно, только что получили Rickrolled. Если вам не повезло …
Давайте просто скажем, что в темных местах Интернета есть более старые и факулированные вещи, чем Рик Эстли.
Что делать, если вы могли бы убедить людей посетить страницу, которую вы контролировали? И что, если эти люди были пользователями Netflix, и они вошли в систему? В 2006 году Дэйв Фергюсон сделал именно это. Он создал безобидную страницу с изображением на ней:
Вы заметили исходный URL-адрес изображения? Это намеренно создано для добавления определенного DVD в вашу очередь. Посыпьте еще несколько запросов на изменение имени пользователя и адреса доставки, и вы можете бесплатно скачать DVD-диски
Эта атака возможна, когда веб-сайты безоговорочно доверяют куки сессии пользователя, не проверяя, откуда поступают запросы HTTP.
Первой проверкой, которую вы можете сделать, является проверка того, что источник запроса и заголовки референта соответствуют местоположению веб-сайта. Эти заголовки не могут быть программно установлены.
Еще одна проверка, которую вы можете использовать, — это добавить токены CSRF в свои веб-формы, чтобы проверить, что запросы поступают из реальной формы на вашем веб-сайте. Токены — это длинные, непредсказуемые, уникальные строки, которые генерируются вашим сервером и вставляются в веб-формы. Когда пользователи заполняют форму, данные формы, отправленные на сервер, могут быть проверены на недавно сгенерированный токен. Это эффективный сдерживающий эффект CSRF-атак, поскольку токены CSRF не хранятся в файлах cookie.
Вы также можете установить SameSite = Strict
при настройке файлов cookie с HTTP-заголовком Set-Cookie. Это сообщает браузерам, что файлы cookie не должны отправляться с межсайтовыми запросами. Это относительно новая функция, хотя она хорошо поддерживается в вечнозеленых браузерах.
Межсайтовый скриптинг: код чужого кода, запущенный на вашем сайте
В 2005 году Samy Kamkar прославился тем, что у него много друзей. Много и много друзей.
Samy наслаждался использованием MySpace, который в то время был крупнейшей социальной сетью в мире. Социальные сети в то время были более ограниченными, чем сегодня. Например, MySpace позволяет загружать фотографии в свою фотогалерею, но ограничивает ограничение в двенадцать. Двенадцать фотографий. По крайней мере, вам не пришлось пробираться сквозь фотографии авокадо тостов тогда …
Сами обнаружил, что MySpace также заблокировал виды контента, которые вы могли бы разместить на своей странице в MySpace. Он обнаружил, что мог ввести в свой заголовок теги
и
был отфильтрован. MySpace не собирался позволять кому-то другому запускать свой собственный код на MySpace.
Заинтригованный, Сами приступил к выяснению, что он может сделать с тегами
и
чтобы стилизовать их с помощью CSS.
Этот код работал только в Internet Explorer и в некоторых версиях Safari, но было много людей, чтобы подружиться. Тем не менее, MySpace был готов к этому: они также отфильтровали слово javascript
из
.
Сами обнаружил, что, вставив строку в свой код, MySpace не отфильтровывает слово javascript . Браузер будет продолжать работать с кодом просто отлично ! Samy теперь сломал первую линию защиты MySpace и смог запустить код на странице своего профиля. Теперь он начал смотреть на что он мог сделать с этим кодом .
оповещения (document.body.innerHTML)
Сэми подумал, может ли он проверить источник страницы, чтобы найти информацию о других друзьях MySpace, чтобы подружиться. Для этого вы обычно использовали document.body.innerHTML
но MySpace также отфильтровывал это.
alert (eval ('document.body.inne' + 'rHTML'))
Это не проблема, если вы создаете код JavaScript внутри строки и выполняете его с помощью функции eval ()
. Этот трюк также работал с XMLHttpRequest.onReadyStateChange
что позволило Samy отправлять запросы друзей в MySpace API и устанавливать код JavaScript на его страницах новых друзей.
На его пути стояло последнее препятствие. Одна и та же политика происхождения - механизм безопасности, который предотвращает использование сценариев на одном домене, взаимодействующих с сайтами, размещенными в другом домене.
if (location.hostname == 'profile.myspace.com') {
document.location = 'http://www.myspace.com'
+ location.pathname + location.search
}
Сами обнаружил, что только домен http://www.myspace.com
будет принимать его запросы API, а запросы от http://profile.myspace.com
заблокирован политикой браузера с одинаковым исходным кодом. Путем перенаправления браузера на http://www.myspace.com
он обнаружил, что он может загружать страницы профиля и успешно делать запросы к API MySpace . Samy установил этот код на странице своего профиля, и он ждал.
В течение следующего дня более миллиона человек невольно установили код Samy на свои страницы профиля MySpace и пригласили своих друзей. Загрузка запросов друзей на MySpace была настолько большой, что сайт застегивался и закрывался. Им потребовалось два часа, чтобы удалить код Сами и исправить обнаруженные в нем дыры в безопасности. Сей был подвергнут набегам спецслужб Соединенных Штатов и приговорен к 90-дневной общественной службе.
Это сила установки немного JavaScript на чужом сайте. Это называется межсайтовым скриптингом, и его эффекты могут быть разрушительными. Подозревается, что сценарий Cross-Site scripting был виноват в нарушении правил British Airways 2018 года, в результате чего данные кредитной карты составили 380 000 человек.
Итак, как вы можете защитить себя от межсайтового скриптинга?
Всегда санируйте вход пользователя, когда он приходит, используя библиотеку, такую как sanitize-html. Инструменты с открытым исходным кодом, подобные этим, получают сотни сотен часов работы от десятков опытных участников. Не испытывайте соблазна бросить свою собственную защиту. MySpace был подготовлен, но они были недостаточно подготовлены. Нет смысла отказываться от этой помощи.
Вы также можете использовать язык автоматического шаблонирования, чтобы убедиться, что HTML-код другого пользователя не попадет на ваши страницы. И Angular и React сделают это для вас, и они чрезвычайно удобны в использовании.
Вы также должны реализовать политику безопасности содержимого, чтобы ограничить домены, из которых может быть загружено содержимое, такое как сценарии и таблицы стилей. Загрузка контента с сайтов, не находящихся под вашим контролем, представляет собой значительный риск для безопасности, и вы должны использовать CSP, чтобы заблокировать это только для источников, которым вы доверяете. CSP также может блокировать использование функции eval ()
.
Для содержимого, не находящегося под вашим контролем, рассмотрите настройку защиты целостности под-ресурсов. Это позволяет добавлять хеши в таблицы стилей и скрипты, которые вы добавляете на свой сайт. Хэши похожи на отпечатки пальцев для цифровых файлов; если содержимое изменяется, то и отпечаток пальца. Добавление хэшей позволит вашему браузеру сохранить ваш сайт в безопасности, если содержимое изменится без вашего ведома.
npm audit: Защитите себя от кода, которым вы не являетесь
JavaScript и npm работают в современной сети. Вместе они позволяют легко воспользоваться крупнейшим в мире публичным реестром программного обеспечения с открытым исходным кодом. Как вы защищаете себя от кода, написанного кем-то, с кем вы никогда не встречались? Введите npm audit.
npm audit проверяет безопасность дерева зависимостей вашего сайта. Вы можете начать использовать его, обновив до последней версии npm:
npm install npm -g
npm audit
Когда вы запустите npm audit
npm отправляет описание ваших зависимостей в реестр, который возвращает отчет об известных уязвимостях для установленных вами пакетов.
Если ваш сайт имеет известную уязвимость межсайтового скриптинга, об этом сообщит об этом в ходе проверки на npm. Более того, если уязвимость была исправлена, запуск исправления для проверки npm
автоматически установит вам патч-пакет!
Обеспечение безопасности вашего сайта, как и 2019 год
Правда заключается в том, что с первых дней существования сети количество нарушений в системе безопасности стало намного выше. Интернет - это гораздо больше, чем фэндомы и почтовые DVD-диски. Онлайн-банкинг теперь является основным, социальные сети и сайты знакомств, которые хранят интимную информацию о нашей личной жизни, и мы даже приглашаем интернет в наши дома.
Однако у нас есть мощные новые союзники, помогающие нам оставаться в безопасности. Есть больше ресурсов, чем когда-либо прежде, чтобы научить нас писать безопасный код. Такие инструменты, как «Угловое» и «Реакт», спроектированы с использованием функций безопасности, испеченных с самого начала. У нас есть новое поколение инструментов безопасности, таких как проверка на npm, чтобы следить за нашими зависимостями.
По мере перехода на 2019 год, давайте воспользуемся возможностью, чтобы задуматься над безопасностью кода, который мы пишем, и будем благодарны за все, что мы узнали за последние двадцать лет.