Веб-безопасность: как усилить ваши файлы cookie HTTP

1656527078 veb bezopasnost kak usilit vashi fajly cookie http

Алексей Надалин

Примечание: это часть 4 серии о безопасности. Часть 3 – Защита веб-приложений с помощью этих HTTP-заголовков.

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

Файлы cookie HTTP были созданы для стандартизации такого механизма во всех браузерах. Они не что иное, как способ хранить данные, отправленные сервером, и отправлять их вместе с будущими запросами. Сервер посылает файл cookie, содержащий небольшие фрагменты данных. Браузер сохраняет его и отправляет вместе с будущими запросами на тот же сервер.

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

Защита файлов cookie является одним из важнейших аспектов при внедрении сеансов в Интернете. Таким образом этот раздел даст вам лучше понять файлы cookie, как их защитить и какие альтернативы можно использовать.

Сервер может установить файл cookie с помощью Set-Cookie заголовок:

HTTP/1.1 200 OkSet-Cookie: access_token=1234...

Затем клиент будет хранить эти данные и отправлять их в следующих запросах через Cookie заголовок:

GET / HTTP/1.1Host: example.comCookie: access_token=1234...

Обратите внимание, что серверы могут одновременно установить несколько файлов cookie:

HTTP/1.1 200 OkSet-Cookie: access_token=1234Set-Cookie: user_id=10...

и клиенты могут хранить несколько файлов cookie и отправлять их в своем запросе:

GET / HTTP/1.1Host: example.comCookie: access_token=1234; user_id=10...

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

Срок действия истекает

Указывает, когда срок действия файла cookie заканчивается, чтобы браузеры не сохраняли и не передавали его неограниченно. Ярким примером является идентификатор сеанса, срок действия которого обычно истекает через некоторое время. Эта директива выражается в виде даты в форме Date: <day-name>, <day> <month> <year> <час>;:<minute>:<second> GMT, нравится Дата: пт, 24 августа 2018 04:33:00 GMT. Вот полный пример файла cookie, срок действия которого истекает 1 января 2018 года:

access_token=1234;Expires=Mon, 1st Jan 2018 00:00:00 GMT

Максимальный возраст

Похож на Expires директива, Max-Age определяет количество секунд до истечения срока действия файла cookie. Печенье, которое должно длиться 1 час, будет выглядеть так:

access_token=1234;Max-Age=3600

Домен

Эта директива определяет, на какие хосты должен отправляться файл cookie. Помните, что файлы cookie обычно содержат конфиденциальные данные, поэтому браузерам важно не передавать их ненадежным хостам. Печенье с директивой Domain=trusted.example.com не будет посылаться вместе с запросами в любой домен, кроме trusted.example.comдаже не корневой домен example.com. Вот действительный пример файла cookie, ограниченного определенным субдоменом:

access_token=1234;Domain=trusted.example.com

Путь

Похож на Domain директивы, но применяется к URL-пути (/some/path). Эта директива предотвращает распространение файлов cookie с ненадежными путями, например в следующем примере:

access_token=1234;Path=/trusted/path

Сессии и постоянные файлы cookie

Когда сервер отправляет файл cookie, не устанавливая его Expires или Max-Ageбраузеры рассматривают это как a файл сеанса cookie: вместо того, чтобы угадывать его время жизни или использовать забавные эвристики, браузер удаляет его, когда выключается.

А постоянный файл cookieнапротив, сохраняется у клиента до установленного им срока Expires или Max-Age директивы.

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

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

Я не думаю, что есть однозначный выигрыш между сессией и постоянными файлами cookie, поскольку оба очень хорошо служат разным целям. Однако я заметил, что Facebook, Google и подобные службы будут использовать постоянные куки. Из личного опыта я обычно всегда использовал постоянные файлы cookie, но никогда не приходилось привязывать важную информацию, например номер социального страхования или баланс банковского счета, к сеансу.

В некоторых случаях может потребоваться использовать файлы cookie сеанса из-за требований соответствия. Я видел, как аудиторы просили конвертировать все постоянные файлы cookie в сеанс. Когда люди спрашивают меняя должен использовать X или Y?” мой ответ: “это зависит от контекста”. Создание гостевой книги для вашего блога имеет другие последствия для безопасности, чем создание банковской системы. Как мы увидим далее в этой серии, я рекомендовал бы понять ваш контекст и попытаться построить такую ​​систему достаточно безопасно: абсолютная безопасность – это утопия, как и 100% соглашение об уровне обслуживания.

Только для хоста

Если сервер не содержит a Domain директиву файл cookie следует считать a host-only один, что означает, что его реальность ограничена только текущим доменом.

Это своего рода поведение «по умолчанию» от браузеров, когда они получают файл cookie, не имеющий файла Domain набор. Вы можете найти небольшой пример, который я написал на github.com/odino/wasec/tree/master/cookies. Это простая веб-приложение, которая устанавливает файлы cookie на основе параметров URL-адреса и печатает файлы cookie на странице с помощью определенного JavaScript.

<html>  <div id="output"/ >  <script>    let content = "none";
if (document.cookie) {      let cookies = document.cookie.split(';')      content=""
cookies.forEach(c => {        content += "<p><code>" + c + "</code></p>"      })    }
document.getElementById('output').innerHTML = "Cookies on this document: <div>" + content + "</div>"  </script><html>

Если вы следуете инструкциям в README вы сможете получить доступ к веб-серверу по адресу wasec.local:7888, который иллюстрирует, как host-only куки работают:

m9IqWiPYM7AufqGrh2YMCdUKpb11gNAOt4ml

Если мы попытаемся посетить субдомен, файлы cookie, которые мы установили в основном домене, не будут видны — попробуйте перейти к sub.wasec.local:7888:

B1ndsOGF72jb-Ti35ANDfeEqWrKOpcwZHxcx

Способ обойти это ограничение состоит в том, как мы видели раньше, указать Domain директиву файла cookie, которую мы можем сделать, посетив wasec.local:7888/?domain=on:

YSlhV6FjATiBRrejQPVuTPt6kiEocPmMZF8kZ

Если мы посмотрим на программу, которая работает на субдомене, теперь мы сможем увидеть файлы cookie, установленные на родительском домене, поскольку они используют Domain=wasec.localчто позволяет любому домену «под» wasec.local чтобы получить доступ к файлам cookie:

khal1469WCPimijC1tw1uiJkfrycXP8fPvY0

В терминах HTTP, вот как выглядят ответы, отправленные с сервера:

~ ᐅ curl -I  200 OKSet-Cookie: example=test_cookieDate: Fri, 24 Aug 2018 09:34:08 GMTConnection: keep-alive
~ ᐅ curl -I " 200 OKSet-Cookie: example=test_cookieSet-Cookie: example_with_domain=test_domain_cookie;Domain=wasec.localDate: Fri, 24 Aug 2018 09:34:11 GMTConnection: keep-alive

Суперкуки

Что если бы мы смогли установить файл cookie в домене верхнего уровня (TLD), например .com или .org? Это, безусловно, будет серьезной проблемой безопасности по двум основным причинам:

  • конфиденциальность пользователя: каждый веб-сайт, работающий на этом конкретном TLD, сможет отслеживать информацию о пользователе в общем хранилище
  • утечка информации: сервер мог ошибочно сохранить конфиденциальную часть данных в файле cookie, доступном для других сайтов

К счастью, файлы cookie TLD, иначе известные как суперкуки, отключаются веб-браузерами по причинам, которые я упоминал выше. Если вы попытаетесь установить суперкуки, браузер просто откажется это сделать. Если мы добавим параметр super=on в нашем примере мы увидим, как сервер пытается установить суперкуки, а браузер игнорирует его:

SLB7Yd8qDqf3-G44HvGbjAMxSkS8N3XmnxUr

Однако в современном Интернете есть другие способы отслеживания пользователей, примером этого является отслеживание ETag. Поскольку файлы cookie обычно связаны с отслеживанием, эти методы часто называют суперкуки, даже если они не полагаются на файлы cookie HTTP. Другие термины, которые могут относиться к тому же набору технологий и практик, – это permacookies (постоянные файлы cookie) или zombiecookies (файлы cookie, которые никогда не умирают).

Нежелательная реклама Verizon

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

В 2016 году Verizon был признан виновным в отслеживании пользователей без их согласия и распространении их информации с рекламодателями. Это привело к штрафу в размере 1,35 миллионов долларов и невозможности для компании продолжать свою сомнительную политику отслеживания.

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

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

До сих пор мы едва поцарапали поверхность файлов cookie HTTP. Пора попробовать настоящий сок.

Есть 3 очень важные директивы (Secure, HttpOnlyи SameSite), что следует понять, прежде чем использовать файлы cookie, поскольку они сильно влияют на то, как файлы cookie хранятся и защищаются.

Зашифруйте или забудьте

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

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

Чтобы устранить проблему, мы можем использовать HTTPS при выдаче файла cookie и добавить файл Secure флаг к нему. Это позволяет браузерам никогда не отправлять файлы cookie в простых HTTP-запросах.

Возвращаясь к нашему практическому примеру, мы можем проверить это, перейдя в Сервер устанавливает 2 дополнительных файла cookie, один из Secure флаг и один без:

d-6jYVyjI-kFTegS5rXdAcHjBb2yne8hs6JQ

Когда мы возвращаемся назад и переходим к HTTP-версии сайта, мы отчетливо видим, что Secure файл cookie недоступен на странице. Попытайтесь перейти к wasec.local:7888.

A9mFjiSIIx2NcZFju3ZvS-oVebW5ozCXhhI5

Мы ясно видим, что версия HTTPS нашего приложения установила файл cookie, доступный для HTTP ( not_secure одно), а другое печенье, обозначенное как Secureнигде не видать.

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

JavaScript не может коснуться этого

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

К счастью, спецификация HTTP позаботилась об этом с помощью HttpOnly флаг. Используя эту директиву, мы можем указать браузеру не делиться файлом cookie с JavaScript. Затем браузер удаляет файл cookie из файла window.cookie переменной, что делает возможным доступ к файлу cookie через JavaScript.

Если мы посмотрим на пример wasec.local:7888/?httponly=on, мы можем четко увидеть, как это работает. Браузер сохранил файл cookie (как показано на снимке экрана DevTools ниже), но не предоставит ему доступ к JavaScript:

JBOOMVwOz2EVdfR7tRez4mdIcDhizfeQOZeW

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

The HttpOnly флажок помогает смягчить атаки XSS, запрещая доступ к критической информации, хранящейся в файле cookie. Используя его, злоумышленнику труднее увлечь сеанс.

В 2003 году исследователи обнаружили интересную уязвимость вокруг HttpOnly флажок, межсайтовое отслеживание (XST).

Короче говоря, браузеры не помешают доступу HttpOnly файлы cookie при использовании TRACE способ запроса. Хотя большинство браузеров отключили этот метод, я рекомендую выключить TRACE на уровне вашего веб-сервера, поворачивая 405 Not allowed код статуса

SameSite: Убийца CSRF

И последнее, но не менее важное SameSite флаг, одна из последних записей в мире cookie.

Этот флаг, представленный Google Chrome версии 51, эффективно устраняет Подделка межсайтовых запросов (CSRF) из Интернета. SameSite является простым, но прорывным новшеством, поскольку предыдущие решения для атак CSRF были либо неполными, либо слишком тяжелым бременем для владельцев сайтов.

Для того чтобы понять SameSite, нам сначала нужно взглянуть на уязвимость, которую она нейтрализует. CSRF – это нежелательный запрос, сделанный сайтом А к сайту B, когда пользователь проходит аутентификацию на сайте B.

Звучит сложно? Разрешите перефразировать.

Предположим, что вы вошли на свой банковский веб-сайт, имеющий механизм перевода денег на основе HTML <form> и несколько дополнительных параметров (целевой счет и сумма). Когда веб-сайт получаетves запрос POST с этими параметрами и вашим файлом cookie сеанса, он обработает передачу. Теперь предположим, что вредоносный сторонний веб-сайт устанавливает форму HTML как таковую:

<form action=" method="POST"><input type="hidden" name="destination" value="attacker@email.com" /><input type="hidden" name="amount" value="1000" /><input type="submit" value="CLICK HERE TO WIN A HUMMER" /></form>

Видите, куда это ведет?

Если вы нажмете кнопку «Отправить», умело замаскированную под привлекательный приз, с вашего счета будет перечислено 1000 долларов. Это подделка межсайтового запроса – ни больше, ни меньше.

Традиционно было 2 способа избавиться от CSRF:

  • Origin и Referer заголовки: сервер может проверить, что эти заголовки приходят из надежных источников (например https://bank.com). Недостатком этого подхода является то, что, как мы видели ранее в этой серии, нет Origin нет Referer очень надежны и могут быть «выключены» клиентом, чтобы защитить конфиденциальность пользователя.
  • Токены CSRF: сервер может включить подписанный маркер в форму и проверить его действительность после отправки формы. Это, как правило, надежный подход, и это рекомендуемая лучшая практика на протяжении многих лет. Недостатком маркеров CSRF является то, что они являются техническим бременем для бэкенда, поскольку вам придется интегрировать создание и проверку маркеров в веб-приложении. Это может показаться не сложной задачей, но более простое решение будет более чем здороваться.

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

Мы можем рассмотреть практическое SameSite с примером на github.com/odino/wasec/tree/master/cookies. Когда вы перейдете на wasec.local:7888/?samesite= на сервере установит SameSite печенье и «обычное».

1dgsuUD8OSILMOoGHxADrAS93-6odmj0xDkq

Если мы посетим wasec2.local:7888/same-site-form, мы увидим пример HTML-формы, инициирующей межсайтовый запрос:

E-DruZ3Sj0VBEXHgUlSDratIwueToplG16-D

Если мы нажмем кнопку отправки формы, мы сможем понять подлинную силу этого флага. Форма перенаправит нас на wasec.local:7888, но нет никаких следов SameSite файл cookie в запросе, сделанном браузером:

yjZRnPQ6vCQNcP5FDuBya89CR-4AZenYo68q

Не запутайтесь, увидев same_site_cookie=test на вашем экране: файл cookie доступен браузером, но он не был отправлен в самом запросе. Мы можем проверить это, просто введя в адресной строке:

Fzh4lrssQwMY-LT3X4RSpIUNJKzpccu-A9IH

Поскольку отправитель запроса «безопасен» (без источника, GET метод) браузер посылает SameSite файл cookie с запросом.

Этот гениальный флаг имеет 2 варианта, Lax и Strict. В нашем примере используется первый, поскольку он позволяет навигацию верхнего уровня на веб-сайт включать файл cookie. Когда вы указываете файлы cookie как SameSite=Strict браузер не будет отправлять файлы cookie по любому запросу между источниками, включая навигацию верхнего уровня. Это означает, что если вы щелкните ссылку на веб-сайт, который использует strict файлы cookie, вы вообще не войдете в систему. Очень высокий уровень защиты, который, с другой стороны, может удивить пользователей. The Lax Режим позволяет отправлять эти файлы cookie между запросами с помощью безопасных методов (например GET), создавая очень полезное сочетание безопасности и пользовательского опыта.

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

— маркировка cookies как Secure убедится, что они не будут посылаться из-за незашифрованных запросов, что делает атаки «человек посередине» достаточно напрасными

— с HttpOnly флажок мы сообщаем браузеру не делиться файлом cookie с клиентом (например, разрешать доступ JavaScript к файлу cookie), ограничивая радиус взрыва атаки XSS.

— обозначение файла cookie как SameSite=Lax|Strict не позволит браузеру посылать его в запросах между источниками, что делает любые виды CSRF-атаки неэффективными.

Альтернативы

Читая весь этот материал о файлах cookie и безопасности, у вас может возникнуть соблазн сказать: «Я действительно хочу держаться подальше от файлов cookie!». Реальность такова, что файлы cookie являются наилучшим вариантом, если вы хотите реализовать какой-то механизм сеанса через HTTP. Время от времени меня просят оценить альтернативы cookie, поэтому я попробую подытожить несколько вещей, которые очень часто упоминаются:

  • localStorage: особенно в контексте одностраничных приложений (SPA), localStorage иногда упоминается при обсуждении места хранения конфиденциальных маркеров. Проблема этого подхода состоит в том, что localStorage не обеспечивает никакой защиты от атак XSS. Если злоумышленнику удается выполнить простую localStorage.getItem('token') в браузере жертвы игра окончена. HttpOnly файлы cookie легко решают эту проблему.
  • JWT: веб-токены JSON определяют способ безопасного создания маркеров доступа для клиента. JWT – это спецификация, определяющая, как будет выглядеть маркер доступа, и не определяет, где будет храниться маркер. Другими словами, вы можете хранить JWT в файле cookie, localStorage или даже в памяти, поэтому нет смысла считать JWT «альтернативой» для файлов cookie.

Что бы сделал Леброн?

Aa-MltRxBUh6IYUkejN4oAVtsfMq4jDpvDy9

Пора перейти от протокола HTTP и его функций, таких как файлы cookie. В этой серии мы прошли долгое путешествие, разбирая, почему рождаются файлы cookie, как они структурированы и как вы можете защитить их, применив некоторые ограничения к ним. Domain, Expires, Max-Age и Path атрибуты и другие флаги, такие как Secure, HttpOnly и SameSite являются жизненно важными для отверждения печенья.

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

В следующей статье этой серии будет представлено то, что я называю.Ситуационные ситуации”.

Первоначально опубликовано на odino.org (14 сентября 2018 г.).
Вы можете следить за мной в Твиттере – ругательство здоровается! ?

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

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