quinta-feira, 6 de fevereiro de 2020

10 mandamentos da segurança em APIs REST

Durante os meus muitos anos de experiências com APIs, sejam elas #SOAP ou #REST, já vi muitas falhas de segurança, que acabam deixando os dados dos usuários expostos. Nestes tempos de #LGPD é melhor prestar atenção:




Hackers são ninjas!

Sim, eles são! Para começar, esqueça aquela ideia de garotos espinhentos, sem namorada, que ficam varando noite em seus computadores. Hacking é um negócio altamente lucrativo, com profissionais de ponta atuando nisso.

O que você pensar para proteger sua API, pode ter certeza que os hackers também pensaram.

Você, pobre desenvolvedor, sofrendo pressão do "Product Owner", do "Scrum Master" e de vários outros idiotas, preocupados apenas em ENTREGAR, acaba deixando "rabos" do lado de fora, e pode ter certeza que serão exploitados!

Para começar, não assuma nada sobre a segurança! Contrate uma empresa especializada para testar a sua aplicação. Insista nisso e, caso os gênios ágeis não concordem, registre isso. Deixe claro que eles resolveram correr o risco, de preferência com evidências físicas.

Todos adoram tirar fotinho sorridentes e se abraçando na hora da "entrega", mas, na hora do "pega pra capar", pode ter certeza que você, Desenvolvedor, será o culpado de tudo. Nessa hora, a galera "tira o corpo fora" e te joga na fogueira.

O que você pode fazer

Não quero pintar um quadro mais feio do que realmente é. Existem atitudes que você pode e deve tomar, durante o desenvolvimento da sua API, que podem dificultar as coisas para os hackers e te proteger quando os idiotas vierem lhe culpar.

Veja bem: Mesmo tomando todas essas atitudes, ainda é possível que sua API seja atacada e utilizada para o mal. 

1 - Siga as restrições REST à risca!

A arquitetura REST possui algumas restrições importantes (https://restfulapi.net/rest-architectural-constraints/) estude e siga-as à risca, especialmente: "Client-Server" e "Layered System".

A ideia aqui é desacoplar totalmente a API e a estrutura física dos dados que ela serve. O usuário da API deve enxergar apenas os recursos sobre os quais tem permissão, e estes não devem ser mapeados (1 para 1) com as tabelas de bancos de dados.

Recursos não são dados! Não precisam e nem devem estar normalizados, como as tabelas de um SGBD. E tome muito cuidado para não expor relacionamentos, chaves primárias, chaves estrangeiras etc.

2 - Proteja os recursos e o contexto!

É preciso proteger o acesso aos recursos, mesmo nos casos em que são públicos. Isto evita a exposição de dados aos Robôs na Internet. Uma maneira interessante é colocar uma API Gateway entre sua API REST e o mundo, contabilizando acessos e controlando repetições, de modo que impeça os robôs de navegarem repetidamente. REST não tem "captcha", pois isso é coisa de página Web. Tem gente que confia apenas no captcha e deixa a API desprotegida, vulnerável a "scanning" por robôs.

Outra coisa que precisa ser protegida é o Contexto. Contexto são os nomes das propriedades dos objetos, as mensagens de resposta e qualquer outra informação que você trafegue em modo aberto. É claro que os rótulos e informações exibidas na sua página HTML também fazem parte do contexto e devem ser muito bem protegidas. Só exiba informações de contexto sensíveis após o usuário se autenticar.

Sua API não deve retornar coisa alguma antes do usuário estar devidamente autenticado! Campos de autopreenchimento e listas são um verdadeiro perigo, pois, para montá-los, a página HTML faz acesso à APIs REST.

Finalmente, use criptografia! Use SSL! E até certificados digitais de cliente, caso a informação seja muito sensível.

3 - Separe suas APIs internas e externas!

Jamais, mas JAMAIS MESMO exponha suas APIs internas para o HTML!
Se você precisa consumir vários outros serviços para validar ou complementar as informações que o usuário provê, faça isso em seu backend, jamais em seu frontend!

Proteja suas APIs internas com uma API Gateway, expondo apenas a API minimamente necessária para o usuário, de acordo com seu nível de autorização.

E, principalmente, evite expor tudo para usuários que ainda não estejam autenticados.

4 - Não exponha diretamente os seus RESTful services!

Considere proteger seus RESTful services colocando-os atrás de um proxy reverso. Com um simples Nginx você pode ajudar a proteger sua API de vários problemas, como XSS, DDOS, e outros tipos de ataque.

5 - Cuidado com o mapeamento de API

Virou moda disponibilizar mapeamento de API, com o Swagger, por exemplo, para facilitar o desenvolvimento de produtos que a utilizam.  Muito legal, muito interessante, mas eu não recomendo disponibilizar isso abertamente na Internet, pois é um prato cheio para explorar sua API e buscar pontos frágeis.

6 - Cuidado com frameworks de autosserviço web

É sensacional criar um RESTful service em Python ou Java, sem ter que subir um servidor, como o JBoss, por exemplo. Frameworks como Flask (WSGI), Dropwizard (Java) ou Spring Boot (Java) permitem subir seu serviço diretamente, sem necessidade de container.

Só que os Containers como os da plataforma Java EE, embutem vários serviços importantes e configurações de segurança, sendo bem mais robustos e resistentes a ataques.

Leia a documentação do framework que você quer usar. Converse nas comunidades de usuários e busque as vulnerabilidades.

7 - Cuidado com o que armazena no navegador local

APIs REST nada armazenam no navegador local, mas as aplicações de frontend sim. Temos várias maneiras de fazer isso, como: Cookies, Local Storage ou Session Storage. Tome extremo cuidado com o estado que você armazena no navegador. Existem plugins que podem capturar o que está sendo armazenado e ajudar a procurar vulnerabilidades na aplicação como um todo.

8 - Proteja-se de session hijacking

Hoje em dia, as aplicações backend são stateless, significando que não guardam dados da sessão do usuário. Mas isso não é totalmente verdadeiro. Hoje, as aplicações web se baseiam em autenticação por tokens, usando padrões como OAuth para isto.

Porém, continuamos com um problema: Temos um Token que deve ser passado ao servidor, contendo os dados da nossa sessão. No mínimo, ele contém um "salvo-conduto" para podermos consumir as APIs de backend por um tempo. Existem padrões como o JWT que especificam como esse token deve ser estruturado, mas eles não te protegem contra XSS ou CSRF . Mas existem medidas que você pode tomar para proteger-se disso, como validar o Refererer, usar Cookies Http-Only ou diversas outras proteções.

9 - Cuidado com websockets

Websocket é uma tecnologia da moda, e há alguns que defende usar REST APIs baseadas nessa técnica. Porém, há relatos de ataques contra essa tecnologia, como o Cross-Site WebSocket Hijacking, descrito nessa apresentação: https://pt.slideshare.net/0ang3el/whats-wrong-with-websocket-apis-unveiling-vulnerabilities-in-websocket-apis e há várias medidas que podemos usar para proteger nossas conexões Websockets, como esse artigo nos diz: https://www.freecodecamp.org/news/how-to-secure-your-websocket-connections-d0be0996c556/

10 - Rastreie todas as alterações

Eu gosto muito do padrão Event Sourcing, pois ele preserva todas as mudanças de estado dos dados ao longo do tempo. Associando essas mudanças com o log de acesso, temos como rastrear e desfazer transações suspeitas. Podemos até alimentar esses dados em um software de busca, como o ElasticSearch ou o SolR e configurar alertas sobre eventos suspeitos.


Conclusão

Estes 10 mandamentos são importantes como parte da proteção necessária para sua moderna aplicação Web baseada em REST.

Eu já vi ou passei por vários desses problemas que relatei aqui e pode ter certeza, tudo isso acontece mesmo.

Cleuton Sampaio, M.Sc.







Nenhum comentário:

Postar um comentário