Melhores práticas de APIs para integração com ferramentas de segurança

Artigo criado pelo time de Research da Tenchi Security

Nos últimos meses, temos recebido muitos pedidos para integrar aplicações SaaS com o Zanshin, a solução de gestão de riscos cibernéticos de terceiro da Tenchi Security, fazemos o possível para garantir que essas integrações aconteçam da melhor forma - mas às vezes esbarramos em alguns problemas que dificultam ou até impossibilitam esse trabalho. Por exemplo: nós, diferente de outras plataformas, só aceitamos acessar APIs de serviços onde é possível ter um acesso sem privilégios de modificação ou de leitura de dados sensíveis. Infelizmente, isso já impediu a integração com alguns produtos no passado. 

Esses entraves também geram risco e dificultam evoluções importantes na infraestrutura cibernética global, como a automação e centralização de controles de segurança e a visibilidade ao longo da cadeia de suprimentos. Organizações com acesso em múltiplas contas de um serviço via API, tais como CSPMs e outras ferramentas de segurança, podem acabar se tornando alvos extremamente visados por atacantes se essas conexões não forem feitas de forma segura.

Por isso, resolvemos reunir neste artigo as melhores práticas para desenhar e criar APIs do ponto de vista de integração com ferramentas de segurança. No entanto, estas não são “exigências” específicas de ferramentas de segurança, mas sim medidas sensatas que deveriam ser seguidas sempre. Se a sua aplicação SaaS seguir as dicas que vamos dar aqui, ela será mais segura, e vai ser bem mais fácil integrá-la com o Zanshin.

Melhores práticas para uma API moderna

Granularidade no escopo de acesso

Aqui na Tenchi Security, temos um princípio não negociável de design para o nosso produto Zanshin - ele não pode introduzir riscos aos ambientes testados. Em resumo, mesmo que nossa plataforma seja comprometida, isso não deveria levar ao vazamento de dados regulados ou ao comprometimento da segurança dos ambientes que estejamos testando.  

Nós fazemos isso garantindo o princípio do privilégio mínimo. Só construímos integrações com outras tecnologias se podemos garantir acesso apenas de leitura, e que mesmo essa leitura esteja restrita a metadados (configurações) e não a dados de negócios armazenados no ambiente. Por exemplo, devemos ser capazes de listar bases de dados que existam em um ambiente IaaS, e como estão configurados. Estão expostas à Internet? Possuem logs e criptografia em trânsito e armazenamento habilitados? Estão com todas as atualizações de software aplicadas? Porém sem jamais termos privilégios ou acessos que nos permitam ler o conteúdo armazenado dentro destas bases de dados, como dados pessoais, transações financeiras ou dados médicos.  

Já encontramos mais de uma API onde o acesso é sempre administrativo em todos os serviços, sem opções de restringi-lo. Dessa forma, qualquer automação integrada com a plataforma pode causar vazamentos de dados ou deleção de informações em casos de falha técnica ou ação maliciosa. 

Também é  importante evitar aglutinar muitas ações em uma única permissão, especialmente se forem de níveis de acesso diferentes. Por exemplo, não é adequado que a permissão mais básica em um serviço permita modificações. No geral, quanto mais granularidade de escopos e permissões disponível, melhor. 

Outro ponto importante é diferenciar entre a leitura de dados sensíveis (como dados de negócio, PIIs, conteúdo de discos de instância e afins) e de dados de configuração ou metadados (configurações de IAM, dados sobre instâncias, etc.), que são usados para finalidades diferentes.

Por exemplo, o Github permite que você crie tokens com permissões granulares, escolhendo entre liberar leitura e/ou escrita apenas para serviços específicos:

Por outro lado, a API do FreshDesk só permite que você se autentique através de chaves de API de usuário, e só existem 4 escopos pré-definidos e imutáveis. Assim, é impossível bloquear a leitura de dados sensíveis. 

Outra feature que pode reduzir o excesso de permissões concedidos a usuários da API é explicitar quais são os escopos faltantes em casos de falta de permissão ao realizar uma chamada. Por exemplo, se o usuário tentou visualizar uma regra de firewall mas não tem permissões para tal, retornar uma explicação junto com o código de erro: “Acesso não autorizado - faltam as permissões x, y e z para esta ação”. Caso contrário, usuários tendem a adicionar privilégios excessivos e desnecessários até que a chamada funcione. 

Finalmente, recomendamos possuir pelo menos um método que permita obter informações sobre o escopo de acesso do usuário atual. Quando se preza pelo acesso mínimo em um ambiente externo, torna-se necessária uma maneira de verificar se o escopo de acesso foi concedido corretamente, sem permissões adicionais nem faltantes.

Métodos de autenticação à API

A escolha de métodos de autenticação adequados para uma API é fundamental  para minimizar riscos e facilitar a gestão de acessos do ambiente.

Os métodos de autenticação à APIs mais comuns são:

Tokens ou Chaves: É gerado um pedaço de texto, chamado de token, chave ou termos semelhantes, que é usado como “senha” para se conectar à API. O criador do token define quais serão as permissões associadas à ele.

Acesso via conta externa: O acesso é concedido para contas de serviço gerenciadas por outras organizações. O administrador da organização define quais permissões essa conta terá dentro de seu ambiente, e o dono da conta de serviço, por sua vez, decide como gerenciar e utilizar as credenciais da conta.

OAuth: É um protocolo aberto que permite que um aplicativo acesse informações de um usuário em outro serviço sem que o usuário precise fornecer suas credenciais de login, como senha, para o aplicativo. 

Dentre essas, recomendamos o uso de Oauth pelos seguintes motivos:

Tokens são simples, mas podem facilmente ser copiados e armazenados de maneira insegura, aumentando o risco de vazamento de credenciais. A gestão deles também pode se tornar complexa se não houver diligência na documentação dos propósitos e locais de armazenamento de cada token. Além disso,  eles necessitam de rotação regular, que vem a ser um processo manual e complexo.

O acesso via contas externas é um pouco melhor, mas quando há necessidade de um serviço se conectar em vários ambientes (como é comum em ferramentas de segurança), todos esses acessos ficam centralizados em uma única conta, ou alternativamente cria-se uma conta para cada ambiente - sendo que nenhuma das duas situações é ideal. Também não há garantias que o detentor da conta externa está gerenciando e utilizando as credenciais dela com segurança.

O OAuth, por sua vez, é um protocolo aberto, maduro, e amplamente utilizado. O escopo de permissões é definido pelo aplicativo e aprovado pelo usuário, e só pode ser alterado através de uma nova aprovação; isso garante que não há possibilidade do usuário conceder permissões incorretas para o serviço. Além disso, as credenciais de acesso têm vida curta, reduzindo o impacto de vazamentos de chave, e as informações sobre integrações existentes são centralizadas - tornando mais fácil a revisão de integrações existentes e suas permissões.

Cobertura de serviços da API

Muitas APIs só oferecem acesso a um subconjunto das informações ou serviços oferecidos na interface gráfica da plataforma. 

Exemplificando, é comum encontrarmos plataformas onde é possível visualizar configurações de segurança do ambiente pelo navegador, mas não pela API.

É importante tentar conciliar a interface gráfica e a API para que as duas tenham o máximo de visibilidade e atuadores em comum. A falta de suporte para certos serviços na API afeta não apenas ferramentas de análise de segurança como o Zanshin, mas também outras automações como rotinas de extração e centralização de informações, ou ferramentas de gestão e monitoração de ambiente.

Outro ponto importante é que os objetos devem exibir as mesmas informações na API e na interface gráfica. Por exemplo, se a interface gráfica mostra a data de criação de um objeto, tal informação também deve ser retornada pela API, pois pode ser importante. Invertendo, se a API mostra a versão específica de um servidor, ela deveria ser exibida na interface gráfica também. Informações segregadas podem fazer com que usuários tenham que coletar dados tanto da API quanto da interface gráfica para obter uma visão completa - o que é péssimo para a experiência de usuário.

E, finalmente, também vale unificar as APIs da plataforma em uma única API. Isso significa que uma única chave pode ser configurada para acessar todos os serviços se o usuário desejar. Já encontramos plataformas onde certos serviços possuem APIs próprias mas que requerem uma autenticação separada. Tais divisões geralmente são causadas por integrações não finalizadas, onde uma empresa adquire ou revende um serviço, oferece-o, mas não unifica a API dele com sua API já existente.

Essa separação dificulta a visão unificada de uma plataforma e leva aos mesmos problemas já discutidos nesta seção.

Melhores práticas para gestores de plataformas

Adicionalmente, também deixaremos, neste artigo, algumas dicas para aqueles que são responsáveis por gerir plataformas cloud / SaaS e suas integrações: 

Não insira informações confidenciais em metadados

Campos como nomes de objetos (instâncias, bancos de dados, etc.), tags ou comentários podem ser pouco restritos ou até mesmo públicos. Portanto, evite incluir informações confidenciais nesses campos. 

Por exemplo, não dê o nome para uma instância de “projeto-aquisição-com-empresa-x” se tal projeto for secreto. Não insira um comentário em um disco como “usado na instância x, senha 123456”. Ao invés disso, use codinomes para projetos sensíveis, garanta que informações de autenticação como senhas estão em cofres protegidos, e corrija tais erros assim que percebê-los.

Revise e higienize suas integrações

Nem toda integração é permanente. Conforme o tempo passa, sua organização pode deixar de usar certos serviços ou encerrar parcerias. Portanto, é importante regularmente revisar quais são as integrações habilitadas para suas plataformas e seus escopos de acesso. Ao remover acessos desnecessários, você reduz a superfície de risco de sua organização.

E como qualquer atividade de revisão de acessos, quanto menos você faz, mais difícil e trabalhosa é cada revisão.

Para auxiliar nesse processo, possuir uma documentação sobre integrações existentes é útil. Tenha anotado, no mínimo, qual o propósito de cada integração e quem é seu ponto focal dentro da organização.

Mantenha um inventário atualizado de chaves de API

Conforme mencionamos, algumas integrações são feitas através de chaves de API - que são utilizáveis por qualquer um que as possua, podendo ser facilmente copiadas ou armazenadas incorretamente, e devem ser rotacionadas regularmente.

Para minimizar esses pontos negativos, mantenha um inventário atualizado das chaves de API que sua plataforma gerou e utiliza. Informações importantes para se ter aqui são: qual foi a demanda que levou à criação da chave, quem é o ponto focal interno que solicitou a chave, onde e como ela é usada, quais permissões ela tem, e quando foi sua última rotação.

No caso de vazamento da chave, essas informações serão cruciais para garantir uma resposta de incidente rápida e eficiente.