Berços de segurança: CSRF

imagem

Apesar do fato de que na última lista publicada de vulnerabilidades dos ataques do CSRF entre os 10 principais da OWASP em 2017 são classificados como “Excluídos, mas não esquecidos”, decidimos que não seria supérfluo lembrar novamente como se defender contra ataques de CSRF, contando com esses as mesmas regras fornecidas pela OWASP.

Usando token CSRF

O uso de um token (métodos sem estado e sem estado) é o método de proteção principal e mais popular. O token deve ser exclusivo para cada sessão do usuário, gerado por um gerador de números pseudo-aleatórios criptograficamente robustos. A OWASP também recomenda o uso dos algoritmos AES256-GCM e SHA256 / 512 para criptografia ao usar o HMAC.

Existem várias abordagens para trabalhar com tokens: Token de Sincronizador, Padrão de Token Baseado em Criptografia, Token Baseado em HMAC

Token de sincronizador

Usando a abordagem do token de sincronização (método statefull), significa enviar um token a cada solicitação, o que implica algumas alterações no lado do servidor. Se o token não for válido, o servidor rejeitará a solicitação.
Ao enviar uma solicitação ao servidor, é recomendável adicionar um token aos parâmetros da solicitação, e não ao cabeçalho. No entanto, se você inserir um token no cabeçalho da solicitação, verifique se ele não está conectado ao servidor. O token recebido pode ser armazenado no lado do cliente em um campo oculto:

<form action="/post.php" method="post"> <input type="hidden" name="CSRFToken" value="l5824xNMAYFesBxing975yR8HPJlHZ"> ... </form> 


nos cabeçalhos:

 POST /page HTTP/1.1 Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36 Content-Type: application/json Host: example.com X-CSRF-TOKEN: l5824xNMAYFesBxing975yR8HPJlHZ 


ou em cookies

 POST /page HTTP/1.1 Host: example.com Set-Cookie: CSRFToken=l5824xNMAYFesBxing975yR8HPJlHZ; Content-Type: application/x-www-form-urlencoded 


A OWASP recomenda armazenar o token nos cabeçalhos, explicando que, mesmo que o token seja aberto ou expirado, o invasor ainda não poderá falsificar a solicitação, devido aos navegadores.

Além disso, para aumentar o nível de segurança do método proposto, é proposto gerar um nome de parâmetro de token aleatório e / ou o próprio token para cada solicitação. Com essa abordagem, o tempo durante o qual o invasor pode usar o token roubado é mínimo. No entanto, isso pode levar a problemas de usabilidade. Por exemplo, clicar no botão "Voltar" pode levar ao envio de um token inválido para o servidor, que estava contido na página anterior.

O envio de um token usando uma solicitação GET não é recomendado, pois com essa abordagem o token pode ser revelado: no histórico do navegador, arquivos de log, cabeçalhos do referenciador.

Token baseado em criptografia

Essa abordagem é sem estado, porque usa criptografia / descriptografia para validar o token e, portanto, não requer armazenamento do token no lado do servidor.

O servidor gera um token que consiste em um identificador de sessão e um carimbo de data / hora (para evitar um ataque de reprodução). Para criptografia, é recomendável usar o algoritmo de criptografia AES256 no modo de criptografia de bloco GSM / GSM-SIV. O uso do modo BCE é altamente desencorajado. O token criptografado pelo servidor é retornado ao cliente da mesma maneira que no caso de “Token de sincronizador” no campo de formulário oculto ou no cabeçalho / parâmetro de resposta. Após o recebimento do token, o servidor deve descriptografá-lo, verificar o identificador da sessão e também verificar o registro de data e hora com o horário atual e garantir que ele não exceda a vida útil do token definido.
Se a verificação do identificador da sessão for bem-sucedida, mas o mapa de tempo não for, a solicitação poderá ser considerada válida. Em todos os outros casos, é recomendável rejeitar a solicitação e registrá-la para entender melhor como responder a essas solicitações.

Token baseado em HMAC

Ele também não requer armazenamento de token, o princípio de operação é semelhante ao Token baseado em criptografia, exceto que, em vez de criptografar o token, a função HMAC (código de autenticação de mensagem baseada em hash) é usada para gerar o token (é recomendável usar o SHA256 ou um algoritmo mais forte). Nesse caso, o token é o resultado da função HMAC do identificador de sessão do usuário + registro de data e hora.

Automação de token

O principal problema para combater os ataques CSRF é que os desenvolvedores simplesmente esquecem de adicionar funcionalidades para trabalhar com tokens. Para evitar esses problemas, vale a pena automatizar este processo:

• escreva um wrapper que adicione automaticamente um token às solicitações por meio da tag de formulário ou ao usar o ajax. Por exemplo, o Spring Security adota uma abordagem semelhante sempre que a tag <form: form> é usada.

• escreva um gancho que intercepte o tráfego e adicione tokens a todos os recursos vulneráveis. Como é bastante difícil analisar qual solicitação a alteração de estado está executando, exigindo um token, é recomendável incluir tokens em todas as respostas POST, mas vale a pena considerar o custo do desempenho

• adicionar automaticamente um token ao renderizar uma página. Essa abordagem é usada pelo CSRF Guard: tokens são adicionados a todos os atributos href e src, campos ocultos e de todas as formas

Antes de tentar escrever seu próprio sistema de geração automática de token, é recomendável esclarecer se a estrutura que você usa tem a capacidade de fornecer proteção contra ataques CSRF por padrão. Por exemplo, a mesma estrutura do Django implementa proteção contra o CSRF.


Login CSRF

Usando o CSRF no formulário de login, um invasor pode efetuar login,
disfarçado de vítima. Tais vulnerabilidades foram enfrentadas por gigantes como PayPal e Google.
Você pode lidar com o CSRF no formulário de login, criando pré-sessões criadas antes da autenticação do usuário e incluindo tokens no formulário de login.


Cookie samesite

O SameSite Cookie é um atributo descrito no RFC6265bis cujo objetivo é combater os ataques CSRF. Funciona da seguinte maneira. Um dos métodos de proteção é verificar a origem e os cabeçalhos do referenciador, pelos quais você pode entender de onde veio a solicitação, mas essa abordagem requer a implementação de um mecanismo de verificação. Usando o atributo SameSite, restringimos o envio de cookies com uma solicitação de recursos externos. Este atributo possui vários valores possíveis: Estrito, Relaxado e Nenhum.
Usar o valor estrito significa que o navegador não enviará cookies de nenhuma fonte que não corresponda ao nome de domínio do recurso atual.
O valor negligente torna possível não bloquear cookies de recursos externos, cuja transição foi realizada de maneira segura - usando o protocolo HTTPS. Lax encontra um equilíbrio entre usabilidade e segurança.

Definir um atributo é bastante simples:

 Set-Cookie: JSESSIONID=xxxxx; SameSite=Strict Set-Cookie: JSESSIONID=xxxxx; SameSite=Lax 


No momento da redação deste artigo, o suporte ao atributo pelos navegadores se parece com o seguinte:

imagem


É importante lembrar que esse atributo deve ser usado como uma medida adicional de proteção, e não como uma maneira de fazer sem usar o token CSRF.

Verificando cabeçalhos

Como mencionado acima, um dos métodos de proteção é verificar o referenciador e os valores de origem do cabeçalho da solicitação.
A essência dessa verificação é verificar os valores dos cabeçalhos no lado do servidor. Se eles corresponderem ao recurso, a solicitação será considerada correta, caso contrário, será rejeitada. Se o cabeçalho Origem estiver ausente, você precisará garantir que o valor do Referenciador corresponda ao recurso atual. A OWASP recomenda rejeitar solicitações que não contenham cabeçalhos Origin ou Referrer. Você também pode registrar todas essas solicitações para analisá-las posteriormente e decidir como lidar com elas.

No entanto, as coisas ficam complicadas se o seu aplicativo estiver protegido por um servidor proxy, pois o URL no cabeçalho será diferente. Nesse caso, existem várias opções:
• Configure seu aplicativo para que você sempre saiba a origem da solicitação. O problema dessa abordagem é definir o valor certo se seu aplicativo for implantado em vários ambientes (por exemplo, dev, QA, produção), o que leva a um problema de suporte
• use o cabeçalho Host. Este cabeçalho permitirá que você determine a origem da solicitação, independentemente do ambiente.
• use o cabeçalho X-Forwarded-Host, cujo objetivo é armazenar os cabeçalhos originais recebidos pelo servidor proxy

Todos os métodos descritos funcionam apenas quando os cabeçalhos de origem e de referência estão presentes. Mas há casos em que esses cabeçalhos estão ausentes. Aqui estão alguns casos em que esses cabeçalhos não estão incluídos na solicitação:
• O IE 11 não inclui o cabeçalho Origin para sites confiáveis. Resta confiar apenas no cabeçalho do Referer.
• no caso de um redirecionamento, o Origin não está incluído na solicitação, pois acredita-se que possa conter informações confidenciais que não devem ser enviadas para outra fonte
• O cabeçalho de origem está ativado para todas as solicitações entre sites, mas a maioria dos navegadores o adiciona apenas para solicitações POST / DELETE / PUT

Como regra, uma pequena quantidade de tráfego cai nas categorias descritas, mas geralmente você não deseja perder nem mesmo essa pequena parte de usuários, portanto, é considerado válido solicitar com um valor nulo para origem / referenciador ou com um valor correspondente à lista de domínios confiáveis.

Cookie de envio duplo

Essa abordagem é bastante simples de implementar e não requer armazenamento do token no lado do servidor (sem estado). A essência do método é enviar o token no parâmetro request e nos cookies pelo usuário. Cada solicitação que exige uma alteração de estado, verificamos o valor do token nos cookies e na solicitação. Se a verificação do identificador da sessão for bem-sucedida, mas o mapa de tempo não for, a solicitação poderá ser considerada válida

Source: https://habr.com/ru/post/pt476880/


All Articles