
A project demonstrating an app that is vulnerable to Spring Security authorization bypass CVE-2022-31692
Uma aplicação Spring Boot simples demonstrando uma configuração vulnerável ao CVE-2022-31692.
Essa vulnerabilidade pode atrair atenção devido à sua gravidade - possui uma pontuação base CVSS 3.x de 9.8, pois permite bypass de autenticação. O propósito deste projeto é demonstrar as condições descritas no aviso, que levam à aplicabilidade da vulnerabilidade.
AuthorizationFilter manualmente ou através do método authorizeHttpRequests().FilterChainProxy para se aplicar a requisições forward e/ou include (ex: spring.security.filter.dispatcher-types = request, error, async, forward, include).authorizeHttpRequests().shouldFilterAllDispatcherTypes(true)Para referência, tenho certeza de que este é o commit que corrige a vulnerabilidade.
A aplicação possui três URLs:
/ A página inicial/admin Uma página de administração, que exige que o usuário forneça autenticação Basic (credenciais "user"/"pass") e tenha a função ROLE_ADMIN atribuída/forward Um encaminhamento (forward) do lado do servidor para a página de administraçãoOs controles de acesso são especificados via authorizeHttpRequests() na classe SecurityConfig.
.authorizeHttpRequests((authz) -> authz
.antMatchers("/").permitAll()
.antMatchers("/forward").permitAll()
.antMatchers("/admin").hasAuthority("ROLE_ADMIN")
.shouldFilterAllDispatcherTypes(true)
)
O usuário acessa / e não está autenticado (graças a permitAll())
O usuário acessa /admin. Ele não fornece autenticação, e a requisição é rejeitada (401 Não autorizado).
O usuário acessa /admin. Ele fornece autenticação válida, mas a requisição ainda é rejeitada (403 Não autorizado)
porque não possui a função necessária .hasAuthority("ROLE_ADMIN").
O usuário acessa /forward. Suas requisições passam pela cadeia de filtros de segurança para GET /forward, que é aprovada
como válida (graças a permitAll()). O controlador processa a requisição e retorna forward:/admin para o Dispatcher.
Conforme instruído pelas configurações spring.security.filter.dispatcher-types e .shouldFilterAllDispatcherTypes(true),
isso é um tipo FORWARD, portanto deve passar novamente pela cadeia de filtros. Esta segunda passagem pelo filtro resulta
na rejeição da requisição (novamente, graças a hasAuthority("ROLE_ADMIN")).
O usuário acessa /forward, a requisição passa pela cadeia de filtros uma vez e é aprovada como válida. O forward é
processado, mas ao invés de passar novamente pela cadeia, é apenas aceito como válido, e a página de administração é
retornada.