Aprimorando a Segurança em JavaScript

Cada linguagem de programação vem com seu próprio conjunto de vulnerabilidades de segurança, e o JavaScript não é exceção. Explorar vulnerabilidades do JavaScript pode levar à manipulação de dados, sequestro de sessão, acesso não autorizado a dados e muito mais. Embora comumente associados à funcionalidade do lado do cliente, os riscos de segurança do JavaScript também podem representar ameaças significativas em ambientes do lado do servidor.

Para qualquer aplicativo, a confiança do cliente é muito importante. Manter essa confiança requer proteger os dados do cliente e garantir a segurança das aplicações. Felizmente, implementar salvaguardas adequadas pode mitigar esses riscos e aprimorar a segurança de sua aplicação. 

Neste artigo, exploraremos algumas das ameaças de segurança do JavaScript mais comuns e discutiremos ferramentas e estratégias eficazes para proteger sua aplicação de possíveis ataques.

Scripting entre Sites

O scripting entre sites (XSS) é uma exploração de segurança que permite a um atacante injetar código malicioso do lado do cliente em um site. De acordo com o Projeto de Segurança de Aplicações Web Abertas (OWASP) Principais 10 vulnerabilidades em 2021, o XSS está classificado como o terceiro vetor de ataque mais comum.

Como Mitigar XSS

Validação de Entrada

Assegure-se de que a entrada do usuário siga os tipos de dados, formatos e intervalos esperados. Remova ou escape caracteres potencialmente prejudiciais para evitar injeção.

JavaScript

 

function validateInput(input) {
  return input.replace(/[^a-zA-Z0-9]/g, ''); // Allow only alphanumeric characters
}

Codificação de Saída

Converta os caracteres especiais na saída para seus equivalentes de entidade HTML para neutralizar scripts potencialmente maliciosos antes de renderizar.

JavaScript

 

function encodeHTML(input) {
  return input.replace(/&/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
    .replace(/'/g, ''');
}

Clickjacking

Clickjacking é um ataque enganoso que engana os usuários a clicarem em um elemento com o qual não pretendem interagir. Esta técnica envolve embutir um site legítimo dentro de um malicioso — frequentemente usando um <iframe> invisível ou posicionado de forma enganosa — para se apropriar das ações do usuário. Como resultado, os atacantes podem roubar credenciais de login, obter permissões não autorizadas ou até mesmo enganar os usuários para instalar malware sem saber. 

Uma maneira comum de realizar isso é usar CSS para adicionar um botão sobreposto com a propriedade opacity quase em 0. Isso engana o usuário a clicar em um botão ou link não intencional.

Como Prevenir o Clickjacking

O X-Frame-Options instrui o navegador se o site pode ser embutido em um iframe. Possui três opções: 

  1. DENY – Impede que a página seja exibida em um iframe totalmente
  2. SAMEORIGIN – Permite que a página seja embutida somente se a solicitação se originar do mesmo domínio 
  3. ALLOW-FROM – Permite que a página seja embutida somente por um domínio específico e confiável 

No Node.js, você pode usar helmet para configurar essas opções como mostrado abaixo:

JavaScript

 

const helmet = require("helmet");
const app = express();
app.use(
  helmet({
    xFrameOptions: { action: "sameorigin" },
  }),
);

Uma defesa eficaz contra clickjacking é implementar o cabeçalho Content Security Policy (CSP). CSP fornece controle granular sobre como e onde o conteúdo pode ser incorporado, impedindo o enquadramento não autorizado.

Para mitigar os riscos de clickjacking, inclua a diretiva frame-ancestors em seu cabeçalho CSP. Por exemplo:

HTML

 

Content-Security-Policy: frame-ancestors 'self' https://www.example.org;

Esta política garante que o documento protegido só pode ser incorporado por sua própria origem ('self') e domínios explicitamente permitidos, como example.org. Bloqueia todas as tentativas não autorizadas de enquadrar o conteúdo, protegendo os usuários de ataques de clickjacking.

Nota: Se frame-ancestors e X-Frame-Options estiverem ambos definidos, então os navegadores que suportam frame-ancestors ignorarão X-Frame-Options.

Ataque de Solicitação Falsificada entre Sites (CSRF)

CSRF (às vezes também chamado de XSRF) explora a confiança que um site tem no navegador do usuário ao fazer solicitações não autorizadas em nome do usuário. Os atacantes enganam os usuários para executar ações sem o conhecimento deles, potencialmente levando a violações de dados ou transações indesejadas. Alguns exemplos são atualizar os detalhes pessoais da vítima, iniciar uma transferência de fundos da conta bancária da vítima ou até redirecionar a entrega de um pacote para um endereço diferente.

Vamos analisar um exemplo específico disso. Você está visitando o site do seu banco e fez login. Digamos que você receba um e-mail de uma promoção fingindo ser do seu banco. O link leva você a uma página aparentemente inofensiva. Nos bastidores, uma solicitação POST é acionada e enviada para a aplicação legítima do banco.

PowerShell

 

curl --location --request POST 'https://acmebank.com/transfer?routing=852363&fromAccountNumber=123456789&toAccountNo=987654321' \
--header 'Cookie: session=acmebanksessionvalue'

Do lado da aplicação acmebank.com, a tag “script” envia o formulário assim que o usuário carrega a página, sem nenhuma validação do usuário ou mesmo sem o usuário perceber o que está acontecendo, como mostrado abaixo.

HTML

 

<html>
  <body>
    <form action="https://acmebank.com/transfer" method="POST">
      <input type="hidden" routing="852363" fromAccountNo="123456789" toAccountNo="987654321" amount="5000" />
    </form>
    <script>
  	window.addEventListener("DOMContentLoaded", () => {
    document.querySelector("form").submit();
  	});
	</script>
  </body>
</html>

O formulário acima cria a seguinte solicitação para a aplicação real, acmebank. A solicitação contém o cookie de sessão do usuário legítimo, mas contém o número da nossa conta bancária! Como sua sessão com o seu banco ainda está ativa, a transferência do valor será concluída se não houver outra validação em vigor.

Como se Defender Contra CSRF

Defina o atributo SameSite como Strict. Isso controla se um cookie é enviado com solicitações entre sites.

  • Esses cookies de sessão devem ter uma vida útil curta. Exija reautenticação para ações sensíveis a fim de mitigar riscos.

Use tokens únicos de sessão CSRF. Este token pode então ser incluído em um formulário que é enviado pelo navegador. Para cada solicitação, o servidor compara o token enviado pelo cliente com o valor armazenado para a sessão. Use a biblioteca csrf-csrf para configurar tokens únicos.

Roubo de Dados de Sessão

O sequestro de sessão ocorre quando um atacante rouba o token de sessão de um usuário, permitindo que eles se façam passar pelo usuário e obtenham acesso não autorizado à sua conta.

Como Prevenir o Sequestro de Sessão

Use Cookies Seguros

Defina as flags Secure e HttpOnly nos cookies de sessão para evitar acesso não autorizado. Definir o atributo Secure impede que o cookie de sessão seja transmitido em texto simples e permite que seja transmitido apenas em conexões HTTPS. Definir o atributo Http-Only obriga o navegador a não permitir acesso ao cookie a partir do DOM o que impede que ataques baseados em scripts do lado do cliente acessem os dados sensíveis armazenados nesses cookies.

Ativar Autenticação Multi-Fator (MFA)

Adicione uma camada extra de segurança para verificar usuários. Este é um método muito comum que você encontrará na maioria das aplicações seguras. Integrações fáceis estão disponíveis via provedores como Okta e Duo.

Implementar Expiração de Sessão

Expirar automaticamente sessões inativas para reduzir janelas de ataque. 

Práticas de Codificação e Ferramentas para Segurança de Alto Nível

Escaneamento de Vulnerabilidades

Um scanner de vulnerabilidades mantém a segurança da sua aplicação. Escanear suas bibliotecas, rede, aplicações e dispositivos ajuda a descobrir fraquezas que os atacantes poderiam explorar. Ferramentas como Snyk e Sonarqube podem ser facilmente integradas em bases de código JavaScript. Essas ferramentas funcionam em paralelo com listas conhecidas de vulnerabilidades mantidas pela OWASP. Com integração perfeita como parte do processo de desenvolvimento, esses scanners fornecem aos desenvolvedores e equipes de segurança uma visibilidade em tempo real e precisa das vulnerabilidades de código e soluções para corrigi-las.

Testes de Penetração e Avaliações

Os desenvolvedores podem adotar práticas de testes de penetração para sondar e explorar ativamente possíveis vulnerabilidades dentro de uma aplicação. Hackers éticos simulam ataques do mundo real para avaliar a postura de segurança de aplicações web, manipulando código JavaScript e interações do usuário.

Para realizar isso, os desenvolvedores podem escrever código JS personalizado para simular os cenários, ou podem utilizar ferramentas especializadas de teste de penetração que aproveitam o JavaScript para automatizar o processo de verificação de vulnerabilidades comuns como XSS, usando OWASP ZAP. Mais informações sobre teste de penetração estão disponíveis no guia oficial da OWASP

Firewall de Aplicação Web (WAF)

À medida que as aplicações crescem, o tráfego web também aumenta, aumentando a exposição a ataques. Implementar um Firewall de Aplicação Web (WAF) ajuda a proteger contra tráfego malicioso filtrando e monitorando solicitações HTTP. Isso envolve a integração com provedores de WAF de terceiros, como Cloudflare ou AWS WAF. Com o WAF, você pode definir regras como: 

  • País ou localização geográfica de onde as solicitações se originam.
  • Endereço IP, intervalo CIDR e nomes de domínio de onde as solicitações se originam.
  • Limitar o comprimento das solicitações e parâmetros de consulta para prevenir ataques de injeção.
  • Código SQL que é provavelmente malicioso. Os atacantes tentam extrair dados do seu banco de dados incorporando código SQL malicioso em uma solicitação web. Isso é conhecido como injeção de SQL.
  • Detectar e bloquear scripts incorporados que podem fazer parte de ataques XSS.

Um WAF também pode ajudar a mitigar ataques de Negação de Serviço Distribuída (DDoS), garantindo a disponibilidade da aplicação.

Proteger a Integridade dos Dados

Implementar medidas robustas de integridade dos dados é essencial ao armazenar ou acessar informações seguras. As melhores práticas incluem:

  • Impor políticas de senhas fortes e incentivar o uso de gerenciadores de senhas. Além disso, incentive seus usuários a usar um gerenciador de senhas para que possam usar senhas mais complexas e não precisem se preocupar em lembrá-las (Use LastPass ou 1Password).
  • Proteja contra ataques de força bruta em páginas de login com limitação de taxa, bloqueios de conta após um certo número de tentativas malsucedidas e desafios CAPTCHA.
  • Usando cabeçalhos HTTP como:

Conclusão

A segurança em JavaScript é um processo contínuo que requer uma abordagem proativa para proteger aplicações contra ameaças em evolução. Implementar boas práticas, como validação de entrada, cabeçalhos CSP, gerenciamento seguro de sessões e varredura de vulnerabilidades, pode reduzir significativamente o risco de ataques como XSS, CSRF e sequestro de sessões.

Além disso, utilizar ferramentas de segurança como WAFs, testes de penetração e MFA fortalece a resiliência das aplicações. Priorizar a segurança em cada etapa do desenvolvimento permitirá que os desenvolvedores criem aplicações robustas e confiáveis para os usuários, que permaneçam protegidas contra ameaças cibernéticas modernas.

Source:
https://dzone.com/articles/enhancing-security-in-javascript