Skip to main content

Fundamentos de segurança do AngularJS

Escrito por
Cheat Sheet AngularJS

17 de março de 2020

0 minutos de leitura

Neste guia de boas práticas de segurança do AngularJS, abordamos o AngularJS e apresentamos dicas e orientações para garantir práticas de codificação seguras. Em essência, este guia reúne os fundamentos de segurança do AngularJS para desenvolvedores web.

Material de consulta com 10 boas práticas de segurança para AngularJS, incluindo proteção contra XSS, injeção de código, redirecionamentos abertos e dependências vulneráveis.

Baixe Fundamentos de segurança do AngularJS

Confira as 10 principais boas práticas de segurança do AngularJS abordadas nesta publicação:

  1. A abordagem do Angular protege você contra XSS

  2. Evite injeções de entrada relacionadas ao DOM do Angular

  3. Evite carregar dinamicamente templates do Angular de fontes não confiáveis

  4. Vulnerabilidades de redirecionamento aberto no AngularJS

  5. Injeção de código Angular no servidor

  6. Evite usar a API do Angular .element, compatível com jQuery, para manipular o DOM

  7. Use linters de segurança para Angular

  8. Analise e corrija vulnerabilidades em componentes de terceiros do Angular

  9. Proteção integrada contra CSRF para aplicações Angular

  10. Compatibilidade integrada do Angular com CSP

Por que é tão importante falar sobre boas práticas de segurança do AngularJS?

De acordo com nosso estudo anterior sobre segurança de frameworks JavaScript, o Angular v1.x representa aproximadamente 30% de todos os downloads de versões do Angular e pouco mais de 2 milhões de downloads em julho de 2019.

Gráfico de linhas que mostra os downloads do Angular v1.x em torno de 1,5 a 2 milhões e o aumento dos downloads das versões mais recentes do Angular, de 3 para 5 milhões, entre junho de 2018 e julho de 2019.

fonte: https://snyk.io/blog/javascript-frameworks-security-report-2019/


Angular é melhor que AngularJS?

Angular é a versão sucessora do AngularJS. Vale destacar que não encontramos vulnerabilidades de segurança reportadas no conjunto principal de componentes do Angular. No entanto, há 23 vulnerabilidades do AngularJS registradas em todas as versões de lançamento da série 1.x.

Qual versão do AngularJS devo usar?

Você deve sempre optar pela versão mais recente do AngularJS — AngularJS 1.7, no momento em que este texto foi escrito —, que está sempre atualizada com correções de segurança e terá suporte até 30 de junho de 2021.

Agradecemos muito a Lewis Arden, que já havia compartilhado pesquisas abrangentes e informações úteis sobre segurança do AngularJS. Aqui está a palestra dele sobre como proteger o AngularJS na OWASP London.

Teste seu projeto AngularJS no GitHub / Bitbucket para encontrar vulnerabilidades de segurança

1. A abordagem do Angular protege você contra XSS

Por padrão, o AngularJS aplica codificação automática de saída e sanitização de entrada com reconhecimento de contexto a todos os valores de dados enviados ao DOM. Desde que você siga a abordagem do Angular, poderá contar com essa proteção.

Vamos conferir alguns exemplos.

Usando ng-bind do Angular

A diretiva ng-bind do Angular permite vincular o valor de um elemento HTML ao valor definido no código Angular, por exemplo, no controlador.

O arquivo view.html a seguir contém o template do Angular, que usa ng-bind para interpolar uma expressão no código Angular e exibir seu valor no elemento div do HTML:

<div class="jumbotron" ng-controller="AboutController as about">
 <h1>About</h1>
 <p>
   Signed by:
 </p>
 <div ng-bind="about.signature"></div>
</div>

O controlador que fornece o valor para essa view é AboutController:

(function() {
 "use strict";
 angular.module("angularjs-starter").controller("AboutController", function() {
   this.signature =
     'Yours truly, Angle <img src="x" onError="alert('its me!')"/>> Bob';
 });
})();

Como você pode ver, o valor da assinatura contém uma tentativa simulada de injetar elementos HTML que acionam uma mensagem de alerta do navegador. No entanto, quando isso é exibido na tela, o Angular codifica caracteres como < em suas entidades HTML. Assim, o conteúdo é exibido como texto, em vez de ser inserido no DOM como um elemento HTML de verdade.

Exemplo de codificação de saída do AngularJS mostrando uma seção Sobre com uma mensagem assinada que contém HTML escapado e um payload de alerta onerror.

Usando as chaves duplas do Angular

Outra maneira de vincular um valor de dados aos elementos HTML é usar a convenção do Angular com chaves duplas. A diretiva ngBind e a notação com chaves duplas funcionam da mesma forma, com algumas diferenças sutis de experiência do usuário.

Veja um exemplo de como o Angular codifica dados maliciosos ao usar chaves duplas. Primeiro, adicionamos um valor de descrição à view:

<div class="jumbotron" ng-controller="AboutController as about">
 <h1>About</h1>
 <p>
   {{ about.description }}
 </p>

 <p>
   Signed by:
 </p>
 <div ng-bind="about.signature"></div>
</div>

E o controlador correspondente, que fornece um valor com a intenção maliciosa de injetar ataques de Cross-site Scripting na página:

(function() {
 "use strict";
 angular.module("angularjs-starter").controller("AboutController", function() {
   this.signature =
     'Yours truly, Angle <img src="x" onError="alert('its me!')"/>> Bob';
   this.description =
     "hello there you <a href="javascript:alert('hello')">crazy</a> diamond";
 });
})();

Como seguimos a abordagem do Angular, você pode ver como ele aplica sua contramedida de codificação de saída contra ataques de Cross-site Scripting quando as chaves duplas e as diretivas ngBind são usadas com entradas de usuário potencialmente maliciosas:

Exemplo de codificação de saída e sanitização do AngularJS, exibindo marcação escapada de link JavaScript e imagem em uma seção Sobre

Conclusão:Aproveite as proteções padrão do Angular para reduzir vulnerabilidades de Cross-site Scripting (XSS): interpole dados pela abordagem do Angular usando diretivas ngBind ou chaves duplas, como {{ data }}, para que o Angular aplique a codificação de saída e a sanitização por padrão.

2. Evite injeções de entrada relacionadas ao DOM do Angular

Abuso da vinculação de HTML não seguro do Angular

Versões mais antigas do AngularJS, como a 1.2 e anteriores, tinham a diretiva ng-bind-html-unsafe, que permitia inserir dados HTML no DOM e criar novos elementos. Uma das práticas para usá-la era criar elementos DOM diretamente a partir de dados de entrada e, em seguida, filtrar determinadas strings, como links, entre outras.

Usar essa abordagem para criar uma lista de bloqueio de dados é propenso a erros e nem sempre é seguro, pois novos vetores e métodos de ataque são descobertos com o tempo, exigindo a manutenção dessa lista.

Vamos ver um exemplo de como ng-bind-html-unsafe injeta elementos HTML no DOM.

Um template do Angular:

<div ng-controller="AboutController" ng-app>
  <span>{{email}}</span>
  <div ng-bind-html-unsafe="link">
  </div>
</div>

E o controlador Angular associado à view:

function AboutController($scope) {
  $scope.email = 'Email me:'
  $scope.link = "<a href='javascript:alert(1)'>Contact me</a>"
}

A view HTML renderizada incluirá "Entre em contato comigo" como um link de verdade que, ao ser clicado, aciona um alerta:

Envie um e-mail: entre em contato comigo

Abuso do Strict Contextual Escaping do Angular

A versão 1.2 do AngularJS descontinuou a diretiva ng-bind-html-unsafe e introduziu o Strict Contextual Escaping (SCE). O SCE permite escapar e sanitizar dados com base no contexto, mas não nos dados de um elemento HTML específico.

Ainda assim, existem formas de contornar essa proteção e dispensar a codificação, presumindo que os dados fornecidos são seguros. Isso é possível com os métodos do Angular $sce.trustAsHtml() e $sce.trustAs(type, value).

Além disso, é possível usar $sceProvider.enabled(false) para desativar globalmente o escape contextual estrito e ignorar toda a sanitização, confiando na entrada. Essa também é uma prática ruim. Recomendamos que você faça isso somente se tiver motivos realmente bons e se certifique de incluir outras contramedidas e defesas.

Vamos considerar o exemplo a seguir, que pretende permitir que usuários criem links, mas acaba introduzindo vulnerabilidades de Cross-site Scripting. O template do Angular para esse caso:

<html>
  <body ng-app='myApp'>
    <div ng-controller="AboutController">
      <span>{{email}}</span>
      <div ng-bind-html="link | stripDangerousHTML">
      </div>
    </div>
  </body>
</html>

O controlador Angular é:

var myApp = angular.module('myApp', []);

myApp.filter('stripDangerousHTML', function($sce) {
  return function(value) {
    let dataInput = value
    dataInput = dataInput
      .replace(/javascript/g, '')
      .replace(/alert/g, '');
    return $sce.trustAsHtml(dataInput);
  }
})

myApp.controller('AboutController', function($scope) {
  // this is filtered ok:
  // const emailAddress = 'javascript:alert(1)'
  // but is this??
  const emailAddress = `jav
ascript:al
ert(1);`
  $scope.email = 'Email me:'
  $scope.link = `Hi there, <a href="${emailAddress}">Contact me</a>`
});

Ao criar um filtro Angular stripDangerousHTML, o desenvolvedor garante que nenhum código JavaScript malicioso seja inserido no atributo href e que o conteúdo seja sanitizado para permitir somente e-mails.

Se a entrada fornecida pelo usuário para emailAddress for 'javascript:alert(1)', a correspondência de padrões baseada em expressão regular funciona bem. Porém, se o valor fornecido pelo usuário for jav ascript:al ert(1);, ela não funciona tão bem. Essa entrada específica contorna a correspondência de padrões e resulta em uma instrução JavaScript válida, causando um XSS.

Conclusão:Evite injeções de entrada relacionadas ao DOM do Angular, pois elas podem introduzir vulnerabilidades.

  • No Angular 1.2 e em versões anteriores, evite usar a diretiva ng-bind-html-unsafe

  • No Angular 1.2 e em versões posteriores, evite confiar cegamente na entrada do usuário usando métodos do Strict Contextual Escaping, como $sce.trustAsHtml(value)

3. Evite carregar dinamicamente templates do Angular de fontes não confiáveis

O código Angular usa templates do Angular o tempo todo. Esses templates HTML são assim:

<div>
  Hello, {{ name }}
</div>

Na maioria das vezes, você compõe templates do Angular com arquivos vinculados a uma aplicação Angular durante o processo de build. No entanto, também é possível carregar esses templates HTML sob demanda durante a execução no lado do cliente, enviando uma solicitação para baixá-los e avaliá-los dinamicamente.

Ainda assim, isso traz o risco de carregar templates de forma insegura por domínios não confiáveis, fora do controle e da confiança da aplicação web. Além disso, os desenvolvedores devem garantir que os templates sejam acessados por protocolos seguros, como versões atualizadas do TLS, para reduzir o risco de ataques Man-in-the-Middle.

Veja um exemplo de carregamento dinâmico de um template Angular pela rede:

angular.module(‘myModule’)
  .component(‘myComponent’, {
     templateUrl: ‘/path/to/template.html’,
     controller: function() {}
   });

O Angular oferece uma maneira de controlar os recursos de templates. A documentação oficial explica isso muito bem:

O $sceDelegateProvider permite obter e definir as listas de permissões e de bloqueio usadas para garantir que os URLs utilizados para carregar templates do AngularJS e outros URLs que executam scripts sejam seguros (todos os locais que usam o contexto $sce.RESOURCE_URL)

Se o código da sua aplicação Angular usar o provedor de delegação SCE, você deverá verificar se a configuração da lista de permissões de recursos foi definida corretamente:

  • use HTTPS como meio seguro para buscar templates remotos e garanta que o endpoint remoto tenha uma configuração TLS atualizada.

  • evite usar o curinga de asteriscos duplos ** para domínios ou protocolos.

  • quando necessário, crie uma lista de bloqueio para adicionar uma camada extra de defesa.

4. Vulnerabilidades de redirecionamento aberto no AngularJS

As APIs nativas do navegador permitem navegar entre páginas, por exemplo, com $window.location. O Angular abstrai o gerenciamento da navegação com o provedor de serviço $location e oferece métodos como $location.url(), $location.path() e $location.hash(), entre outros, para acessar o URL de navegação atual e sincronizá-lo conforme necessário.

Talvez você tenha código Angular que realiza a navegação com base em parâmetros de consulta do URL ou em outros dados relacionados a ele.

Considere o exemplo a seguir:

myApp.controller('AboutController', function($scope, $location) {
    $scope.submit = function() {
       const referer = $location.hash()
     }

     window.location.href = referer
});

A intenção desse código Angular é analisar um URL, por exemplo, https://www.example.com/path/to/this#referer, e usá-lo como base para navegar até outra página.

No entanto, como o usuário que navega pela aplicação web controla o endereço do URL, ele pode definir o hash como código JavaScript válido — por exemplo, https://www.example.com/path/to/this#javascript:alert(1) — e executar esse URL.

Da mesma forma, definir window.location.href com uma entrada do usuário — por exemplo, o exemplo de injeção JavaScript no hash — teria o mesmo resultado.

Fundamentos de segurança do AngularJS

Boas práticas para evitar redirecionamentos abertos e injeção de código JavaScript:

  1. evite navegar entre páginas com base em entradas absolutas do usuário.

  2. quando precisar navegar entre páginas com base em uma entrada do usuário, use mapas de dicionário para associar essa entrada a uma página ou URL.

  3. nunca concatene entradas do usuário aos URLs de navegação entre páginas.

Conclusão:Evite as armadilhas de redirecionamento aberto usando diretamente entradas do usuário para navegar entre páginas.

  • Evite padrões como window.location.href = $location.hash, que podem levar a ataques de injeção de código JavaScript.

  • Use mapas de dicionário para navegar entre páginas com base em entradas do usuário.

5. Injeção de código Angular no servidor

Embora o código no servidor sanitize ou codifique entidades HTML maliciosas, como scripts, ele não reconhece o contexto do AngularJS no lado do cliente. Assim, atacantes podem fornecer uma expressão de template Angular — por exemplo, chaves com um payload JavaScript adicional — que será avaliada durante a execução no lado do cliente e causará um ataque de injeção.

Boas práticas para reduzir a injeção de código Angular no servidor:

  • Evite misturar templates do servidor e do cliente. Em vez disso, mantenha os templates em um único contexto de aplicação: no servidor ou no cliente.

  • Reduza o escopo da diretiva ng-app, limitando-a ao contexto de um elemento DOM específico na página, em vez de aplicá-la ao corpo do documento HTML.

  • Vincule os dados do template a ng-bind ou ng-bind-html para garantir que a entrada do usuário seja tratada corretamente com os recursos do Angular de codificação de saída e sanitização dessas diretivas.

  • Use ng-non-bindable para garantir que o Angular não trate os dados como uma expressão a ser avaliada e, assim, reduzir o risco de injeção de código Angular.

Conclusão:Reduza o risco de injeção de código Angular no servidor.

6. Evite usar a API .element do Angular, compatível com jQuery, para manipular o DOM

O Angular oferece a API angular.element() para garantir compatibilidade com uma API semelhante à do jQuery (jqLite) e consultar e manipular o DOM diretamente.

Isso pode parecer uma maneira prática de acessar e interagir com o DOM. No entanto, introduz possíveis vulnerabilidades de injeção devido à inserção insegura no DOM.

Veja este modelo simples do Angular:

    <div ng-controller="AboutController">
      <span id=”content”>{{content}}</span>
    </div>

A seguir, veja o controller do Angular correspondente, que usa angular.element() para manipular a página:

function AboutController($scope) {
  const element = angular.element(‘#content’)
  element.after($scope.content)
}

O problema está em element.after(), que adiciona o conteúdo de $scope.content ao DOM sem codificação nem sanitização, já que é compatível com a própria API after do jQuery. Se essa variável contiver algo malicioso, as proteções do Angular não serão aplicadas, deixando você vulnerável a possíveis ataques de XSS.

Saiba mais sobre angular.element na documentação oficial do Angular: https://docs.angularjs.org/api/ng/function/angular.element.

Em resumo: Evite usar a API angular.element() do Angular, compatível com jQuery, para manipular o DOM. A criação direta de elementos HTML no DOM pode levar a vulnerabilidades de Cross-site Scripting.

7. Use linters de segurança para Angular

Linters são comuns no desenvolvimento JavaScript, e muitos desenvolvedores usam projetos populares como o ESLint com plugins que ampliam seus recursos. O projeto eslint-plugin-angular ajuda a seguir as convenções e diretrizes gerais de programação do Angular. Ele também inclui regras de segurança, como no-jquery-angularelementque impede envolver objetos angular.element com jQuery ou $.

Veja um exemplo de como o plugin do ESLint identifica problemas, de acordo com a documentação oficial:

/*eslint angular/no-jquery-angularelement: 2*/
// invalid
$(angular.element("#id")) // error: angular.element returns already a jQLite element. No need to wrap with the jQuery object

// invalid
jQuery(angular.element("#id")) // error: angular.element returns already a jQLite element. No need to wrap with the jQuery object

Se você não sabe por que usar angular.element() é um problema de segurança, recomendamos a leitura da seção anterior: Evite usar a API .element do Angular, compatível com jQuery, para manipular o DOM.

Em resumo:Use ferramentas de análise estática de código para automatizar a identificação de código inseguro e alertar os desenvolvedores assim que isso acontecer, ainda no início do desenvolvimento. Linters de segurança que fazem parte dos fundamentos de segurança do AngularJS:

8. Analise e corrija vulnerabilidades em componentes de terceiros do Angular

É muito provável que você use pacotes de código aberto além do núcleo e dos componentes estendidos do Angular para criar sua aplicação web. Na verdade, o próprio projeto AngularJS tem vulnerabilidades. Segundo um estudo da Snyk sobre segurança de frameworks JavaScript, há mais de 20 vulnerabilidades de segurança no AngularJS na linha de versões 1.x.

Gráfico de barras que mostra a quantidade de vulnerabilidades por versão do Angular 1.x: a versão 1.1 tem 1, a 1.2 tem 4, a 1.3 tem 3, a 1.4 tem 1, a 1.5 tem 7 e a 1.6 tem 3.

Além disso, as dependências usadas para criar sua aplicação web baseada em Angular também podem ter vulnerabilidades de segurança. Como mostra a tabela a seguir, algumas dessas vulnerabilidades ainda não têm uma correção disponível.

Tabela que compara módulos vulneráveis em Angular e React, vulnerabilidades indiretas, gravidade, downloads anuais e possibilidade de correção.

Analise as vulnerabilidades

Procurando um scanner de segurança para AngularJS? Faça testes de segurança no AngularJS e mantenha-se por dentro das vulnerabilidades de segurança do seu projeto frontend usando a Snyk e conectando seus projetos do GitHub ou Bitbucket — assim, a Snyk encontra vulnerabilidades automaticamente e abre pull requests com correções para você.

Outra maneira rápida de começar e identificar problemas de segurança no AngularJS é usar a CLI da Snyk:

npm install -g snyk
snyk test

Ao executar um teste da Snyk, a ferramenta informa as vulnerabilidades encontradas e exibe os caminhos vulneráveis para que você possa rastrear a árvore de dependências e descobrir qual módulo introduziu uma vulnerabilidade.

Infelizmente, se você usa o npm audit, provavelmente não identificou todas as vulnerabilidades de segurança do AngularJS que a Snyk detecta. O npm audit também não identifica nenhuma das três vulnerabilidades do React, dando aos desenvolvedores uma falsa sensação de segurança.

A saída do terminal relata uma vulnerabilidade de cross-site scripting de alta gravidade no Angular 1.2.32 e 11 caminhos vulneráveis.
fonte: https://snyk.io/blog/angular-vs-react-security-bakeoff-2019/

A Snyk oferece orientações práticas para corrigir vulnerabilidades com a atualização para uma versão corrigida, por meio de um pull request automatizado aberto no seu repositório. Se não houver correção disponível, você também pode aplicar um patch fornecido pela Snyk para reduzir o risco da vulnerabilidade.

Se você procura algo parecido com um scanner de segurança para AngularJS, comece pela Snyk para monitorar suas dependências de código aberto, receber notificações e corrigir vulnerabilidades assim que forem descobertas.

Em resumo:O AngularJS tem mais de 20 vulnerabilidades conhecidas, e há componentes do Angular com milhões de downloads que ainda são vulneráveis.

  • Conecte a Snyk ao GitHub ou a outros SCMs para integrar seus projetos ao CI/CD da melhor forma.

  • A Snyk encontra vulnerabilidades nos componentes de terceiros que você usa e abre pull requests com correções para que você possa mesclar a atualização da versão e reduzir o risco.

9. Suporte integrado a CSRF em aplicações Angular

A falsificação de solicitação entre sites (CSRF, XSRF) é um ataque de segurança na web que induz os usuários a realizar ações que não pretendiam, como enviar uma solicitação de API que envia um formulário.

Uma técnica para reduzir vulnerabilidades de CSRF é usar tokens gerados aleatoriamente ou, melhor ainda, nonces criptográficos para confirmar que uma solicitação é confiável.

O Angular oferece suporte integrado a tokens CSRF: ele lê cookies com nomes específicos, como XSRF-TOKEN, enviados pelo servidor, e adiciona o valor às solicitações HTTP subsequentes feitas pela aplicação Angular.

Todo o tratamento de tokens CSRF é feito pelo serviço $http do AngularJS. Nas versões mais recentes do Angular, esse recurso também é oferecido pelo HttpClient, no módulo @angular/common/http oficialmente compatível. Também é possível configurar o nome do cookie do token CSRF e o comportamento geral por meio da API $http.xsrfCookieName, entre outras.

Em resumo:O Angular oferece suporte integrado no lado do cliente ao tratamento de tokens CSRF por meio do serviço $http. Use esse serviço em vez de criar sua própria solução.

10. Compatibilidade integrada do Angular com CSP

Alguns recursos do Angular entram em conflito com restrições comuns de CSP, como as que proíbem a avaliação de código JavaScript inline. Mas, em vez de desativar completamente a CSP, o que não é recomendado, você pode usar a diretiva ngCsp do Angular, compatível com configurações de CSP.

A Política de Segurança de Conteúdo (CSP) é um padrão da web que permite estabelecer políticas de confiança. Ela é usada principalmente como uma camada adicional de defesa para reforçar a segurança e ajuda a reduzir problemas como injeções de XSS.

O AngularJS tem controles integrados relacionados à CSP, mas, quando ativados, algumas funcionalidades precisam ser desabilitadas — por exemplo, scripts e expressões inline não são permitidos porque eval() é bloqueado. Ainda assim, alguns recursos do AngularJS dependem disso internamente.

A Mozilla oferece uma leitura recomendada sobre CSP, assim como a documentação da API do Angular para a diretiva ngCsp.

Em resumo: Implementar uma Política de Segurança de Conteúdo (CSP) é uma etapa importante para adicionar uma camada extra de segurança, especialmente para ajudar a reduzir ataques de Cross-site Scripting.


10 práticas fundamentais de segurança para AngularJS:

  1. O jeito Angular protege você contra XSS

  2. Evite injeções de entrada no DOM do Angular

  3. Evite carregar dinamicamente modelos do Angular de fontes não confiáveis

  4. Vulnerabilidades de redirecionamento aberto no AngularJS

  5. Injeção de código Angular no lado do servidor

  6. Evite usar a API .element do Angular, compatível com jQuery, para manipular o DOM

  7. Use linters de segurança para Angular

  8. Analise e corrija vulnerabilidades em componentes de terceiros do Angular

  9. Suporte integrado a CSRF em aplicações Angular

  10. Compatibilidade integrada do Angular com CSP

Baixe o guia de práticas recomendadas de segurança para AngularJS!

Leia mais

Blog

Modelos de ponta encontraram as vulnerabilidades. Só o atacante encontrou as cadeias.

A análise estática encontrou as falhas, mas só os testes de ataque em aplicações ativas provaram como elas poderiam ser encadeadas para causar invasões. Uma comparação entre Evo COS, Claude Security e Claude Code Security.

feature insights context
Blog

Os ataques autônomos já chegaram. A defesa precisa acompanhar o ritmo.

Os atacantes autônomos estão reduzindo o tempo disponível para a defesa. Saiba como a descoberta, a correção, a validação e a prevenção contínuas ajudam as equipes de segurança a acompanhar esse ritmo.

Blog

Por que agentes de programação com IA continuam criando falhas de controle de acesso

Agentes de programação com IA podem gerar uma lógica de autorização que compila e passa pela revisão, mas permite que um tenant acesse os dados de outro. Saiba por que é difícil detectar falhas de controle de acesso e como evitá-las.