Недавно я видел выступление Майка Винсера SpringOne2GX о подводных камнях безопасности приложений . Это очень информативно и стоит посмотреть, если вы используете стек Spring в контейнере сервлета.
Это напомнило мне одну серьезную неверную конфигурацию Spring Security, с которой я однажды столкнулся. Расскажу об этом в руководстве проекта Spring под названием «Защита веб-приложения» . В этом проекте используются Spring Boot, Spring Integration и Spring MVC.
Проект использует эти представления:
01
02
03
04
05
06
07
08
09
10
11
12
|
@Configuration public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController( "/home" ).setViewName( "home" ); registry.addViewController( "/" ).setViewName( "home" ); registry.addViewController( "/hello" ).setViewName( "hello" ); registry.addViewController( "/login" ).setViewName( "login" ); } } |
Если URL-адреса «/ home», «/» и «/ login» должны быть общедоступными, а «/ hello» — только для аутентифицированного пользователя. Вот оригинальная конфигурация Spring Security из Руководства:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
@Configuration @EnableWebMvcSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers( "/" , "/home" ).permitAll() .anyRequest().authenticated(); http .formLogin() .loginPage( "/login" ) .permitAll() .and() .logout() .permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser( "user" ).password( "password" ).roles( "USER" ); } } |
Хороший и объяснительный, как и все руководства весны. Первый метод «configure» регистрирует «/» и «home» как публичные и указывает, что все остальное должно быть аутентифицировано. Он также регистрирует логин URL. Второй метод «configure» определяет метод аутентификации для роли «USER». Конечно, вы не хотите использовать это в производстве!
Теперь я собираюсь немного изменить этот код.
1
2
3
4
5
6
7
8
9
|
@Override protected void configure(HttpSecurity http) throws Exception { //!!! Don't use this example !!! http .authorizeRequests() .antMatchers( "/hello" ).hasRole( "USER" ); //... same as above ... } |
Все является публичным и частные конечные точки должны быть перечислены. Вы можете видеть, что мой исправленный код имеет то же поведение, что и оригинал. Фактически это спасло одну строку кода.
Но есть серьезная проблема с этим. Что делать, если мне нужно ввести новую частную конечную точку? Допустим, я не в курсе того факта, что он должен быть зарегистрирован в конфигурации Spring Security. Моя новая конечная точка будет публичной. Такое неправильное конфигурирование действительно трудно уловить и может привести к нежелательному раскрытию URL-адресов.
Итак, вывод таков : всегда проверяйте подлинность всех конечных точек по умолчанию.
Ссылка: | Неверная конфигурация Spring Security от нашего партнера по JCG Любоса Крнаца в |