BLOG

A proteção de SPAs é um esporte de equipe

Miniatura de Lori MacVittie
Lori MacVittie
Publicado em 05 de agosto de 2019

Uma das coisas interessantes - e mais frustrantes - que notei ao longo dos anos é a diferença entre como os engenheiros de rede e os desenvolvedores de aplicativos veem os aplicativos. Vimos isso na maneira como os aplicativos são representados em diagramas de rede e, inversamente, na maneira como as redes são mostradas em diagramas de arquitetura de aplicativos. 

POV Dev vs Net

Nem é preciso dizer que cada um tem uma visão muito simplista do outro. 

Isso também é verdade para a segurança, cujo papel na proteção não apenas de redes e aplicativos, mas do próprio negócio, tornou-se primordial. É importante que as equipes de segurança pensem fora da caixa nos diagramas arquitetônicos típicos para realmente entender os aplicativos. Uma porcentagem significativa de ataques (bem-sucedidos) é executada na camada de aplicação. Quanto mais tempo não conseguirmos reconhecer as características únicas de vários tipos de aplicações, mais tempo essas aplicações permanecerão vulneráveis. 

A discussão de hoje vai se concentrar nos SPAs. Isso é "Single Page Applications" para aqueles que estão se perguntando o que esse TLA em particular significa. 

Uma introdução aos SPAs 

Um aplicativo de página única é exatamente isso: uma única página da web que serve como uma estrutura para todas as tarefas relacionadas ao aplicativo. Essa arquitetura remonta aos dias da Web 2.0 e ao surgimento do AJAX como um método de "atualizar" elementos DOM (Document Object Model) individuais em vez de recarregar a página inteira. O desempenho foi bastante aprimorado com essa técnica, que é a precursora do aplicativo moderno de página única.

Esses aplicativos refletem mais de perto o comportamento de um aplicativo móvel, em que a interface do usuário do cliente é carregada quando ele é aberto pela primeira vez e a comunicação com o servidor envolve apenas dados. Isso significa que cada chamada para o servidor contém nada mais do que dados, e quaisquer alterações na interface do usuário acontecem no cliente. Isso reduz drasticamente a quantidade de dados enviados e recebidos e, como você pode imaginar, significa melhor desempenho. Esses tipos de aplicativos usam APIs para trocar dados.

Em geral, operamos sob a suposição de que a maioria dessas APIs são implementadas usando princípios REST. Isso significa que cada objeto (geralmente considerado vinculado a um único elemento da interface do usuário) tem sua própria API que pode ser invocada para executar transações CRUD (criar, ler, atualizar e excluir). Do ponto de vista da segurança, isso torna as coisas um pouco mais fáceis porque você pode esperar dados em formatos específicos para uma determinada chamada de API (URI). Os dados enviados para "/update/product/123" serão consistentemente o mesmo objeto serializado, enquanto os dados enviados para "/delete/order/4433" serão um objeto serializado diferente. Isso significa que práticas tradicionais de vincular políticas específicas a URIs específicos podem ser usadas para proteger essa API. 

O Padrão URI Único 

Agora, os SPAs podem - ou não - seguir esse padrão. Práticas emergentes em torno de SPAs podem usar e usam a mesma API para conduzir transações, bem como um mapeamento mais tradicional de função para URI. Com um único padrão de URI SPA, o URI não muda, mas os objetos serializados enviados e recebidos entre os servidores mudam.

Isso lembra as transações SOA/XML, nas quais um único ponto de extremidade (URI) seria usado para invocar diversas funções. A função (endpoint) visada estava contida nos dados XML serializados ou, às vezes, inserida em um cabeçalho HTTP personalizado. Esse modelo levou à necessidade de gateways SOA/XML que fossem responsáveis por receber a solicitação e determinar qual função estava sendo invocada antes de roteá-la para o ponto final correto (servidor). 

Com SPAs, você pode estar lidando com várias chamadas de API ou apenas algumas. Em todos os casos, você provavelmente está lidando com a necessidade de proteger dados em algum formato (talvez XML, mais provavelmente JSON). Isso significa que você precisa estar ciente de que o conteúdo traz riscos. Como alguns dados podem ser usados para gerar elementos de IU dinamicamente (ou manipular o DOM de volta no cliente), é importante procurar e destruir códigos potencialmente maliciosos em cada envio. 

A desconexão da segurança 

Infelizmente, se um único URI for usado para trocar dados para funções variadas, a prática tradicional de anexar políticas aos URIs não funcionará. Na verdade, isso pode quebrar a segurança porque essas políticas geralmente são treinadas para esperar formatos de carga específicos. Gateways de API também frequentemente vinculam políticas (roteamento, medição, acesso) a um URI específico. Isso significa que a prática de usar apenas alguns URIs (chamadas de API) para lidar com muito mais funções com formatos de dados variados pode quebrar a segurança existente.

Este é um exemplo de por que é cada vez mais importante que a segurança e o desenvolvimento (não o DevOps, mas os desenvolvedores) trabalhem mais próximos desde a primeira linha de código até a implantação. Há coisas que os desenvolvedores podem fazer desde o início para facilitar a implementação das proteções adequadas pela segurança, como inserir um cabeçalho HTTP com um indicador que possibilite a execução da política correta. Algo tão simples como "X-Code: 'order'" enriqueceria as solicitações de forma que as soluções de segurança pudessem identificar — e posteriormente escanear — os dados em busca de possíveis explorações.

Em termos de arquitetura, isso pode exigir um proxy L7 inteligente que possa extrair o código e reescrever o URI antes de rotear a solicitação para a solução de segurança apropriada (WAF, API Gateway, etc.). Essa abordagem também funciona se o proxy L7 inteligente puder falar a linguagem de formato de dados, como JSON, e os desenvolvedores incluírem em cada troca algum código ou nome de ponto de extremidade que possa ser usado para reescrever e rotear para o lugar certo. 

Arquitetura de Spa Segura

O ideal seria incorporar a segurança da camada de aplicação no próprio aplicativo para obter o melhor equilíbrio entre desempenho e segurança. No entanto, isso nem sempre é possível e, às vezes, soluções arquitetônicas criativas são necessárias para atingir o objetivo de segurança. 

Segurança é um esporte de equipe

De modo geral, mudanças na maneira como os desenvolvedores distribuem diversas responsabilidades entre o cliente e o servidor têm um impacto significativo na maneira como a infraestrutura de serviço do aplicativo interage com as solicitações e respostas subsequentes. É importante que as equipes de segurança, desenvolvedores e infraestrutura de serviços de aplicativos estejam envolvidas em todo o SDLC. Uma solução arquitetônica também leva tempo para ser implementada. Se for deixado "para o final", você estará adicionando dias — ou semanas, ou talvez até meses — de tempo adicional para colocar o produto no mercado. Ou você vai comercializar sem serviços de segurança, o que tem seu próprio conjunto de riscos (e consequências).  

A colaboração desde o primeiro dia de desenvolvimento é a melhor - e mais rápida - maneira de garantir que os aplicativos estejam disponíveis, rápidos e seguros quando forem lançados em produção.