Segurança em APIs REST: Níveis, OAuth e Boas Práticas
Classificado em Computação
Escrito em em português com um tamanho de 13 KB.
Nível 0 – POX
Modelo muito simples de comunicação
Neste nível, utiliza-se XML para comunicação com o padrão envelope, enviando arquivos sem padrões e sem segurança.
Apesar de ser o nível mais distante do que de fato REST propõe, muitas APIs ditas como RESTful se encontram neste nível de maturidade.
Neste nível, as mensagens podem ser serializadas em formatos como XML, JSON ou outros.
Um outro problema constantemente encontrado é a manipulação incorreta dos códigos de resposta do HTTP.
Códigos e mensagens de erros são frequentemente manipulados nas mensagens geradas pela aplicação, o que impede que elementos de gateway e proxy trabalhem de forma adequada.
GET /buscarCliente/1 HTTP/1.1 200 OK <status>CLIENTE NÃO ENCONTRADO</status> <codigo>404</codigo> |
Apesar da mensagem sugerir que o cliente solicitado não foi encontrado, a resposta HTTP apresenta uma informação totalmente diferente (200 OK). Ou seja, existe uma diferença semântica entre o protocolo HTTP e a representação gerada pela aplicação.
Nível 1 – Recursos
Uso de recursos
Nesse nível, apesar do mapeamento dos recursos estar correto, existe uma incoerência na semântica, uma vez que não é necessário indicar o tipo de operação no recurso.
No nível 1, passamos a usar recursos como forma de modelar e organizar a API. Neste nível, não precisamos conhecer a funcionalidade de cada método e sim apenas o recurso ao qual temos acesso.
Modelando corretamente os recursos, precisamos usar os métodos HTTP da forma certa, para que possamos criar todas as interações necessárias sob um recurso.
Recurso | Verbo |
/salvarCliente | POST |
/nomeCliente | DELETE |
/consultaCliente | GET |
Nível 2 – Verbos HTTP
Uso correto dos verbos HTTP
Nesse nível, o mapeamento dos recursos já está mais conciso e sem incoerência na semântica, uma vez que não é indicado o tipo de operação no recurso. Isso porque existe a abstração por meio do verbo HTTP. Ou seja, se utiliza um verbo POST, subentende-se que criará algo e não é necessariamente preciso indicar o tipo de operação.
Nesse nível, o HTTP deixa de exercer um papel apenas de transporte e passa a exercer um papel semântico na API. Ou seja, seus verbos passam a ser utilizados com o propósito no qual foram criados.
A utilização dos métodos mais conhecidos (GET, POST, PUT e DELETE), bem como a tratativa correta dos códigos de resposta, permitem a modelagem e interação com os recursos presentes em uma API.
Enviando | Recebendo |
POST /cliente <Nome>Manoel da Silva</Nome> | 201 Created Location: /cliente/1 |
É importante notar dois aspectos nessa resposta: o primeiro é a utilização correta da resposta “201 Created”. Como foi solicitada a criação de um recurso, nada mais adequado que uma resposta que informe que o recurso foi criado com sucesso. Além disso, um importante aspecto é a presença do header “Location”. Esse header informa em qual endereço o recurso criado se encontra disponível.
Nível 3 – HATEOAS
Controles de hipermídia
Nesse nível, além do mapeamento dos recursos, existe um reconhecimento de todas as dependências relacionadas à rota utilizada. Em outras palavras, pode-se mapear, além da rota principal, outras rotas que têm vínculo com a rota principal de alguma forma. Ou seja, utiliza-se de um controle de hipermídias, sugerindo rotas adicionais à rota principal.
OBS: sistemas ESB (Enterprise Serial Bus) são softwares de gestão de serviços que entendem o comportamento de um serviço.
Apesar de aparentemente ser algo não muito familiar, HATEOAS é um conceito presente no dia a dia de todos os usuários da web.
Ele tem como elemento principal uma representação hypermedia, que permite que um documento descreva seu estado atual e quais os seus relacionamentos com outros futuros estados.
GET /cliente/1 HTTP/1.1 200 OK <Id>1</Id> <Nome>Manoel da Silva</Nome> |
No exemplo, o cliente da API deverá entender o significado dos relacionamentos “deletar” e “notificar” para que ele consiga de fato consumir de forma adequada esses links.
Resumo dos Níveis de Maturidade REST
- Nível 0: Não utiliza o HTTP corretamente.
- Nível 1: Utiliza recursos.
- Nível 2: Utiliza os verbos HTTP corretamente.
- Nível 3: Utiliza controles de hipermídia (HATEOAS).
Middleware
Camada de interceptação entre client e server. É possível criar vários middlewares, podendo ser personalizados e podendo assumir, por exemplo, as funções de segurança em autenticação. Não é necessário implementar um middleware para cada endpoint, pois o middleware está em nível de servidor e fará o rastreio de todas as requisições.
- Segurança -> Headers
- Autorização / Autenticação
- Basic -> Base64 -> Basic user:password
- Digest -> MD5 -> “CustomKey Hash” -> (usuário+senha+email)
- OBS: Basic pode ser visto como um algoritmo de serialização e não de criptografia por ser um algoritmo simples, já Digest possui um meio mais sofisticado e pode ser considerado como um algoritmo de criptografia.
- Autorização / Autenticação
OAuth 1.0 e 2.0
Protocolo de segurança para autenticação e autorização
OAuth faz uso de tokens de acesso, fazendo com que diferentes aplicações client possam se autenticar a um servidor de autenticação sem que o usuário final tenha que compartilhar suas credenciais com as aplicações client.
Um outro fator é que o OAuth avisa ao usuário quais informações as aplicações clientes estão solicitando acesso. Isso evita que aplicações mal-intencionadas obtenham acesso indevido.
No OAuth, existem três partes envolvidas em uma conversação: o proprietário do recurso (usuário final), o client (aplicação de terceiro) e o servidor onde estão armazenados os recursos.
Fluxo padrão do protocolo
- A aplicação solicita autorização para acessar recursos do serviço do usuário.
- Se o usuário autorizar a solicitação, a aplicação recebe uma concessão de autorização.
- A aplicação solicita um token de acesso ao servidor de autorização (API) através da autenticação de sua própria identidade e da concessão de autorização.
- Se a identidade da aplicação está autenticada e a concessão de autorização for válida, o servidor de autorização (API) emite um token de acesso para a aplicação. A autorização está completa.
- A aplicação solicita o recurso ao servidor de recursos (API) e apresenta o token de acesso para autenticação.
- Se o token de acesso é válido, o servidor de recurso (API) fornece o recurso para a aplicação.
OAuth define quatro tipos de concessão, cada um dos quais é útil em diferentes casos:
- Código de autorização: Usa um código de autorização intermediário para delegar a autorização de maneira segura a partir de um servidor de autorização para um client por meio do agente de usuário (navegador) do proprietário do recurso.
- Implícita: O client adquire diretamente um token de acesso a partir do servidor de autorização. Isso elimina boa parte da complexidade do código de autorização intermediário, mas apresenta a desvantagem de que o proprietário do recurso pode potencialmente obter o token de acesso.
- Credenciais de senha do proprietário do recurso: O proprietário do recurso compartilha as credenciais diretamente com o client, que as utiliza para obter um token de acesso de maneira direta, em uma única transação.
- Credenciais de client: Nesse fluxo, o client usa suas próprias credenciais para acessar um recurso. Dessa maneira, os direitos existentes do client estão realmente sendo utilizados.
Diferenças entre OAuth 1.0 e 2.0
O OAuth 2.0 é uma reescrita completa do OAuth 1.0 desde o início, compartilhando apenas objetivos gerais e experiência geral do usuário. O OAuth 2.0 não é compatível com o OAuth 1.0 ou 1.1 e deve ser pensado como um protocolo completamente novo.
Vantagens do OAuth
- Elimina a necessidade do usuário preencher longos formulários, apenas autorizando seu aplicativo a colher informações de um provedor.
- Em quase totalidade das vezes, os dados do usuário são verdadeiros, uma vez que já estão sendo utilizados pelo usuário no provedor.
- O desenvolvedor pode criar uma funcionalidade para manter os dados atualizados com o provedor, verificando-os sempre que o usuário autorizar (ao fazer login, por exemplo).
Desvantagens do OAuth
- Possível receio do usuário em compartilhar suas informações em sites desconhecidos.
- Dependência da API do provedor, a qual pode ser atualizada e originar falhas na autenticação, além de transtornos ao usuário.
Cross-Domain
Também conhecido como domínio cruzado, permite a criação de uma whitelist ou blacklist onde não só somente os domínios ou IPs que constam nessa lista podem acessar (ou seja, consumir o serviço da API em questão), como também é possível restringir o tipo de verbo HTTP a ser utilizado por um determinado domínio ou IP. O uso do cross-domain é um aspecto de segurança que possibilita, além de barrar acessos não autorizados, a prevenção, por exemplo, de ataques DDoS que causam instabilidades no serviço e, em casos mais críticos, a queda do serviço em questão.
Cross-domain pode ser implementado de três formas: restringindo um domínio específico a um verbo específico, restringindo um grupo de domínios a um verbo específico ou restringindo todos os domínios a um verbo específico.
É possível fazer a implementação do lado webserver ou no cabeçalho. A vantagem de fazer no cabeçalho é que te dá independência em relação ao tipo de servidor, enquanto que a implementação no lado server precisa seguir os padrões do servidor em uso.
REST e RESTful
Endereçamento
É um princípio do REST que diz que todo recurso em um sistema deve ser acessado através de um identificador único. A identificação de um recurso é feita através do uso de URIs.
O formato de URI descrito possui alguns elementos importantes:
- scheme: indica o protocolo que será usado para realizar a comunicação, os mais comuns são HTTP ou HTTPS.
- host: responsável pelo IP ou DNS do servidor para o qual a requisição está sendo feita.
- port: porta do servidor para o qual a requisição está sendo feita.
- path: expressa um conjunto de segmentos de texto delimitados pelo caractere “/”. Um exemplo seria a estrutura de diretórios em um servidor.
- ?: caractere que separa o path da queryString.
- queryString: é uma lista de parâmetros representada por chave/valor.
Interface Uniforme
O princípio da arquitetura REST afirma que deve existir um conjunto bem definido de operações para manipulação dos recursos e, com isso, faz uso dos métodos do protocolo HTTP. Os mais utilizados são: GET, PUT, POST, DELETE, HEAD e OPTIONS.
Autenticação
Autenticação se refere a quem está interagindo com o sistema. É o processo de identificar um usuário, geralmente através de um nome de usuário e senha.
Autorização
Autorização é um termo que se refere ao que um usuário ou app autenticado pode fazer. Em sistemas de informação, autorização se refere a permissões de acesso e privilégios que um determinado usuário tem ao sistema em que está conectado.
Conclusão
Segurança é algo crucial no desenvolvimento de qualquer aplicação, principalmente quando as informações são sigilosas e trafegadas através da rede. Garantir a segurança é fundamental para gerar confiança aos usuários de um sistema.