Статьи

Основные преимущества Spring Security 3.2.0 RC1: заголовки безопасности


Этот пост был изначально написан Робом Винчем из SpringSource. 

Это мой последний пост в серии из двух статей о Spring Security 3.2.0.RC1. В моем  предыдущем посте  обсуждалась защита CSRF Spring Security. В этом посте мы обсудим, как использовать Spring Security для добавления различных заголовков ответов для защиты вашего приложения.

ЗАГОЛОВКИ БЕЗОПАСНОСТИ

Многие из новых функций Spring Security в 3.2.0.RC1 реализованы путем добавления заголовков к ответу. Основой для этих функций послужила усердная работа  Мартена Дейна . Если имя звучит знакомо, возможно, потому, что одна из его публикаций в 10K + на весенних форумах помогла вам.

Если вы используете конфигурацию XML, вы можете добавить все заголовки по умолчанию, используя  элемент <headers /> Spring Security  без дочерних элементов, чтобы добавить все заголовки по умолчанию в ответ:

<http ...>
    ...
    <headers />
</http>

Если вы используете конфигурацию Java Spring Security, по умолчанию добавляются все заголовки безопасности по умолчанию. Их можно отключить с помощью конфигурации Java ниже:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
   WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .headers().disable()
      ...;
  }
}

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

Контроль кеша

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

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache

Простое добавление элемента <headers /> без дочерних элементов автоматически добавит Cache Control и несколько других средств защиты. Однако, если вы хотите только управление кэшем, вы можете включить эту функцию, используя пространство имен Spring Security XML с  элементом <cache-control /> .

<http ...>
...
<headers>
<cache-control />
</headers>
</http>

Точно так же вы можете включить только управление кэшем в Java Configuration следующим образом:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.cacheControl()
.and()
...;
}
}

Если вы действительно хотите кэшировать конкретные ответы, ваше приложение может выборочно вызывать HttpServletResponse.setHeader (String, String)  для переопределения заголовка, установленного Spring Security. Это полезно для обеспечения правильного кэширования таких вещей, как CSS, JavaScript и изображения.

При использовании Spring Web MVC это обычно делается в вашей конфигурации. Например, следующая конфигурация гарантирует, что заголовки кэша установлены для всех ваших ресурсов:

@EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/")
.setCachePeriod(31556926);
}
// ...
}

Параметры типа контента

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

Есть много дополнительных вещей, которые нужно сделать (например, отображать документ только в отдельном домене, убедиться, что установлен заголовок Content-Type, очистить документ и т. Д.) При разрешении загрузки контента. Однако эти меры выходят за рамки того, что предоставляет Spring Security. Также важно указать, что при отключении отслеживания содержимого необходимо указать тип содержимого, чтобы все работало правильно.

Исторически браузеры, в том числе Internet Explorer, пытались угадать тип содержимого запроса, используя  анализатор содержимого . Это позволило браузерам улучшить взаимодействие с пользователем, угадав тип контента на ресурсах, которые не указали тип контента. Например, если браузер обнаружил файл JavaScript, для которого не указан тип содержимого, он сможет угадать тип содержимого и затем выполнить его.

Проблема с перехватом контента заключается в том, что это позволило злонамеренным пользователям использовать полиглоты (то есть файл, действительный как несколько типов контента) для выполнения XSS-атак. Например, некоторые сайты могут разрешать пользователям отправлять действительный документ postscript на веб-сайт и просматривать его. Злонамеренный пользователь может создать  документ postscript, который также является допустимым файлом JavaScript,  и выполнить с ним XSS-атаку.

Отслеживание содержимого можно отключить, добавив следующий заголовок в наш ответ:

X-Content-Type-Options: nosniff

Как и в случае с элементом управления кэшем, директива nosniff добавляется по умолчанию при использовании элемента <headers /> без дочерних элементов. Однако если вы хотите больше контролировать, какие заголовки добавляются, вы можете использовать   элемент <content-type-options />, как показано ниже:

<http ...>
...
<headers>
<content-type-options />
</headers>
</http>

Заголовок X-Content-Type-Options добавляется по умолчанию с настройкой Spring Security Java. Если вы хотите больше контроля над заголовками, вы можете явно указать параметры типа контента с помощью следующего:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.contentTypeOptions()
.and()
...;
}
}

Строгая транспортная безопасность HTTP (HSTS)

Когда вы вводите веб-сайт вашего банка, вы вводите mybank.example.com или https://mybank.example.com? Если вы пропустите протокол https, вы потенциально уязвимы для атак Man in the Middle . Даже если веб-сайт выполняет перенаправление на https://mybank.example.com, злоумышленник может перехватить первоначальный HTTP-запрос и манипулировать ответом (т. Е. Перенаправить на https://mibank.example.com и украсть свои учетные данные).

Многие пользователи опускают протокол https, и именно поэтому  была создана HTTP Strict Transport Security (HSTS) . После добавления mybank.example.com в качестве  хоста HSTS браузер может заранее знать, что любой запрос к mybank.example.com должен интерпретироваться как https://mybank.example.com. Это значительно снижает вероятность возникновения атаки «Человек посередине».

Примечания HSTS

В соответствии с 
RFC6797 заголовок HSTS внедряется только в ответы HTTPS. Чтобы браузер подтвердил заголовок, браузер должен сначала доверять центру сертификации, подписавшему SSL-сертификат, используемый для установления соединения (а не только SSL-сертификат).

Один из способов пометить сайт как хост HSTS — предварительно загрузить хост в браузер. Другой способ — добавить к ответу заголовок «Strict-Transport-Security». Например, следующее будет указывать браузеру обрабатывать домен в качестве хоста HSTS в течение года (примерно 31536000 секунд в году):

Strict-Transport-Security: max-age=31536000 ; includeSubDomains

Необязательная директива includeSubDomains инструктирует Spring Security о том, что дочерние домены (т.е. secure.mybank.example.com) также должны рассматриваться как домен HSTS.

Как и в случае с другими заголовками, Spring Security добавляет предыдущий заголовок к ответу, когда указан элемент <headers /> без дочерних элементов. Он также автоматически добавляется при использовании конфигурации Java. Вы также можете использовать только заголовки HSTS с   элементом <hsts />, как показано ниже:

<http ...>
...
<headers>
<hsts />
</headers>
</http>

Точно так же вы можете включить только заголовки HSTS с конфигурацией Java:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.hsts()
.and()
...;
}
}

X-Frame-Options

Политика безопасности контента

Другим современным подходом к решению проблем с кликбэком является использование 
политики безопасности контента . Spring Security не обеспечивает поддержку этого, так как спецификация не выпущена, и это немного сложнее. Чтобы быть в курсе этой проблемы и узнать, как ее реализовать с помощью Spring Security, обратитесь к 
SEC-2117.

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

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

Более современный подход к решению проблемы clickjacking заключается в использовании   заголовка X-Frame-Options :

X-Frame-Options: DENY

Заголовок ответа X-Frame-Options инструктирует браузер предотвращать отображение любого сайта с таким заголовком в ответе во фрейме. Как и в случае других заголовков ответов, это автоматически включается, когда указан элемент <headers /> без дочерних элементов. Вы также можете явно указать   элемент <frame-options /> для управления тем, какие заголовки добавляются в ответ.

<http ...>
    ...
    <headers>
        <frame-options />
    </headers>
</http>

Точно так же вы можете включить только параметры фрейма в Java Configuration со следующими параметрами:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.frameOptions()
.and()
...;
}
}

X-XSS-Protection

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

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

X-XSS-Protection: 1; mode=block

Этот заголовок включен по умолчанию, когда указан элемент <headers /> без дочерних элементов. Мы можем явно указать это, используя  элемент <xss-protection />,  как показано ниже:

<http ...>
...
<headers>
<xss-protection />
</headers>
</http>

Точно так же вы можете включить только защиту xss в Java Configuration с помощью следующего:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.xssProtection()
.and()
...;
}
}

ОБРАТНАЯ СВЯЗЬ ПОЖАЛУЙСТА

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

Пожалуйста, регистрируйте любые проблемы или запросы функций в  Spring Security JIRA . После регистрации в JIRA мы рекомендуем (но не обязываем) отправлять изменения в запросе на включение. Подробнее о том, как это сделать, вы можете прочитать в  Руководстве для участников.

Если у вас есть вопросы о том, как что-то сделать, используйте  форумы Spring Security  или Stack Overflow с тегом spring-security  (я буду внимательно следить за ними). Если у вас есть конкретные комментарии по поводу этого блога, не стесняйтесь оставлять комментарии. Использование соответствующих инструментов поможет сделать это проще для всех.

ВЫВОД

Вы должны хорошо разбираться в новых функциях Spring Security 3.2.RC1.