Статьи

Неправильная конфигурация Spring Security

Недавно я видел выступление Майка Винсера 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 Любоса Крнаца в