Tudo que estiver desta cor, foi escrito com dúvida e deve ser revisitado para entender ou explicar melhor.
O que é?
É um framework escrito em cima do Spring Framework. É altamente customizavel. E atualmente é a solução mais completa do mercado Java.
Estratégias de Autenticação
- Basic and Form
- OAuth2
- OpenID Connect
- LDAP
- JWT
- Digest Authentication
- X.509 certificates
Proteções Out of the Box
O Spring Security, sem nenhuma configuração extra, consegue nos proteger contra:
- Session fixation: a vítima utiliza um token pré-instalado na sua máquina para se autenticar e acaba dando acesso ao atacante.
- Clickjacking: engana o usuário a clicar em um elemento invisível ou disfarçado.
- Cross-site Request Forgery (CSRF): comandos não-autorizados são enviados através de um usuário que a aplicação confia.
- Cross-site Scripting (XSS): injeção de scripts executados no cliente e disponibilizados para outros usuários. (Script na descrição do seu perfil de uma rede social.)
- URL e HTTP verb tamepring: o atacante faz requisições para inúmeras URLs que aplicações normalmente utilizam com métodos HTTP que os desenvolvedores raramente utilizam.
Arquitetura

- Construído em cima do Spring e utiliza algumas de suas funcionalidades
- É voltado para aplicativos Web e utiliza Filter/Servlet entry-point
- Funciona com múltiplos modelos de autenticação
- Encoraja a utilização de salts
- Possuí alguns mecanismos que protegem aplicações contra ataques de sessão (Man in the-middle)
- Possuí uma caralhada de funcionalidades
Autenticação é o processo que garante que o usuário é quem diz que é.
Autorização diz o que o usuário pode fazer.
Autenticação via Basic e Form
Se não tivermos nenhum Bean que estenda de
WebSecurityConfigurationAdpater
, o Spring Boot irá utilizar um padrão que viabiliza a autenicação via Form e Basic. Via Form
Essa implementação padrão do Spring Security é realizada através de uma chamda
POST
para /login
. No corpo dessa requisição são enviados os campos username
e password
. Via Basic
Realizada através da concateção do
username
e password
utilizando o :
(i.e. username:password
). Pode ser transmitido via URI, mas essa modadilidade, embora suportada pelo Spring, está depreciada por questões de segurança. Quando é transmitida via Header, o texto concatenado é convertido para Base64. Essa codificação em Base64 não tem nenhum caratér de segurança. Sua utilidade é possibilitar a transmissão de caracteres não suportados por HTTP.
Permitindo apenas uma via de autenticação
Quando criarmos um
@Configuration
Bean que estenda de WebSecurityConfigurationAdpater
estaremos dizendo ao Spring Boot que queremos utilizar nossa própria configuração de autenticação.Sobrescrevendo o método
configure(HttpSecurity http)
conseguimos definir nossa estratégia de autenticação e autorização de requisições HTTP. Com o seguinte trecho de código conseguimos liberar apenas autenticação via Basic:@Configuration public class SecurityConfiguration extends WebSecurityConfigurationAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated() .and().httpBasic(); } }
configure(WebSecurity)
vs configure(HttpSecurity)
methods
O
configure(WebSecurity)
nos permite criar paths que serão completamente ignorados pelo Spring Security. Utilizando web.ignoring().mvcMatchers("/css/**", "/webjars/**")
mandamos o Spring criar filterChains
separadas para cada argumento utilizado no mvcMatchers
. Utilizando o
configure(HttpSecurity)
podemos então fazer http.authorizeRequests().mvcMatchers("/login").permitAll()
para possibilitar o acesso anônimo a rota /login
. Com essa abordagem ainda temos acesso aos recursos do Spring Security.Multiple Filter Chains
Podemos ter a necessidade de que hajam diferentes tipos de autenticação na nossa aplicação (e.g. todas requisições para
/admin/**
são via Form; todos outros endpoints são via Basic). Para isso precisamos criar diferentes FilterChains.Conseguimos utilizar diferentes FilterChains no Spring Security criando múltiplos Beans que estendam
WebSecurityConfigurerAdapter
.
Ordem das FilterChains
Antes das nossas requisições passarem pelas nossas Filter Chains, o
FilterChainProxy
itera sobre todas Filter Chains que temos definidas, seguindo a @Order
estabelecida. Não pode haver duas Filter Chains com a mesma ordem.Escolhendo a Filter Chain
Vamos analisar o seguinte cenário:
- Uma FilterChain A que lida com qualquer requisição e aceita autenticação via Form.
- Uma FilterChain B que lida com requisições para
/admin/**
e aceita autenticação via Basic.
Quando as requisições chegam no
FilterChainProxy
ele itera sobre nossas FilterChains (seguindo a @Order
) até encontrar alguma que consiga lidar com a requisição. Então, se a nossa FilterChain A tiver uma @Order(1)
e a FilterChain B @Order(2)
, nenhuma requisição para /admin/**
se quer chegará na FilterChain B. Todas passarão pela FilterChain A.Podemos, porém, inverter a orderm. Deixando a FilterChain mais genérica por último. Ou seja, FilterChain B terá
@Order(1)
e FilterChain A terá @Order(2)
.Headers
Spring Security inclui por padrão diversos Headers para instruir o browser em como se comunicar de maneira mais segura com a aplicação. Eles são adicionados pelo
HeaderWriterFilter
.Podemos configurar esse filtro utilizando o
http.headers()
. Com http.headers().disabled()
conseguimos remover o HeaderWriterFilter
, consequentemente removendo quaisquer Headers adicionado por esse filtro. Também podemos utilizar http.headers().defaultsDisabled()
para desabilitar apenas os Headers padrão; deixando apenas os Headers que tenhamos definido.Cache-Control
Em aplicações com server-side rendering, o cache pode ser uma falha de segurança. Imagine que você está acessando a página privada do seu banco. Nela estão informações como seu nome, email, saldo da conta, número da conta... Se essa página for cacheada no seu browser, um atacante pode então acessar seu computador e acessar essas páginas cacheadas.
Para contornar esse problema, o Spring desabilita o cache de todas páginas por padrão. Isso não é o ideal, já que queremos a melhora de performance que o Cache nos dá. Então o que podemos fazer é habilitar o cache em páginas específicas. Assim, podemos cachear apenas as páginas que não contêm informações sensíveis.
X-XSS-Protection: 1; mode=block
Utilizado para instruír o browser a ativar o mecanismo de proteção contra XSS, caso ele exista. O
mode=block
previne que os browsers tentem executar alguma ação para identificar o tipo verdadeiro do arquivo. X-Content-Type-Options: nosniff
Utilizado para desabilitar o content sniffing. Isso evita possíveis ataques XSS utilizando arquivos poliglótas.
Synchronizer Token Pattern
Para proteger os usuários contra ataques CRSF, Spring Security segue o Syncrhonizer Token Pattern. Esse padrão altera a forma como a sessão de um usuário é reutilizada.
O normal é que as sessões dos usuários fiquem armazenadas em Cookies do seu browser. Esses cookies são retornados na primeira comunicação com o servidor. Nas comunicações seguintes o browser apenas envia o cookie que contém as informações de autenticação do usuário. Porém, utilizando apenas o cookie, que fica sob controle do browser, pode acontecer de um atacante capturar esse cookie e se comunicar com o servidor utilizando ele. O servidor então vai acreditar que é o usuário dono do cookie que está se comunicando.
O padrão de Synchronizer Token adiciona um token CRSF nessa lógica de sessão. Na primeira comunicação com o servidor, esse retorna, junto do cookie, um token randômico. Esse token é então armazenado pela aplicação. Agora, para que o usuário consiga se autenticar no servidor, ele precisa enviar ambos cookie e token CRSF. Se esse token não estiver presente, a aplicação não autentica o usuário.
Obs: essa proteção pode ser violada utilizado Clickjacking
Clickjacking Protection
Clickjacking acontece quando o usuário acessa um site malicioso, que embute o site real. Se o usuário estiver logado no site real, o atacante conseguirá manipular ações que o usuário está tomando "no site real" e utiliza-las no seu site malicioso.
Spring Security utiliza o header
X-Frame-Options: DENY
para instruir o browser que o site dele não deve ser renderizado em <frame>
, <iframe>
ou <object>
. Assim como os outros Headers, Spring Security permite que customizemos ele.- Podemos adicionar Handlers para executar alguma ação caso a autenticação seja bem sucedida ou tenha falhado.
- Content Sniffing: para melhorar a experiência do usuário, os browsers analisam uma stream de bytes identificando qual o seu content-type.
- Atacantes exploraram essa funcionalidade com arquivos poliglótas. Esses são arquivos válidos em diferentes formatos. Por exemplo, um arquivo que é
.js
mas também pode ser lido como um.png
. Para esses arquivos, o content sniffing é uma loteria; pode ser que o browser aceite o upload do arquivo como um.png
, mas quando tentar exibi-lo, acabe entendendo como um.js
e o execute.