Ao projetar uma API ou serviço REST, existem práticas recomendadas para lidar com segurança (autenticação, autorização, gerenciamento de identidades)?
Ao criar uma API SOAP, você tem o WS-Security como guia e muita literatura existe sobre o tópico. Encontrei menos informações sobre a proteção de terminais REST.
Embora eu entenda que o REST intencionalmente não tem especificações análogas ao WS- *, espero que surjam as melhores práticas ou os padrões recomendados.
Qualquer discussão ou link para documentos relevantes seria muito apreciado. Se isso importa, estaríamos usando o WCF com mensagens serializadas POX / JSON para nossas APIs / Serviços REST criados usando a v3.5 do .NET Framework.
wcf
security
rest
authorization
rest-security
Nathan
fonte
fonte
Respostas:
Como o tweakt disse, o Amazon S3 é um bom modelo para se trabalhar. Suas assinaturas de solicitação possuem alguns recursos (como incorporar um carimbo de data / hora) que ajudam a proteger contra a reprodução acidental e maliciosa de solicitações.
O bom do HTTP Basic é que praticamente todas as bibliotecas HTTP o suportam. É claro que você precisará exigir SSL nesse caso, porque enviar senhas de texto sem formatação pela rede é quase universalmente uma coisa ruim. O Basic é preferível ao Digest ao usar SSL porque, mesmo que o chamador já saiba que as credenciais são necessárias, o Digest exige uma ida e volta extra para trocar o valor de nonce. Com o Basic, os chamadores simplesmente enviam as credenciais pela primeira vez.
Uma vez que a identidade do cliente é estabelecida, a autorização é realmente apenas um problema de implementação. No entanto, você pode delegar a autorização para outro componente com um modelo de autorização existente. Novamente, o mais interessante do Basic aqui é que o servidor acaba com uma cópia em texto sem formatação da senha do cliente, que você pode simplesmente passar para outro componente da infraestrutura, conforme necessário.
fonte
"sending plaintext passwords over the net is almost universally a bad thing"
- Você pode elaborar sobre o "quase"? Quando não é uma má ideia?Não há outros padrões para o REST além do HTTP. Existem serviços REST estabelecidos por aí. Sugiro que você dê uma olhada nelas e tenha uma ideia de como elas funcionam.
Por exemplo, emprestamos muitas idéias do serviço S3 REST da Amazon ao desenvolver as nossas. Mas optamos por não usar o modelo de segurança mais avançado, com base em assinaturas de solicitação. A abordagem mais simples é a autenticação HTTP Basic sobre SSL. Você tem que decidir o que funciona melhor na sua situação.
Além disso, eu recomendo o livro RESTful Web Services da O'reilly. Explica os conceitos principais e fornece algumas práticas recomendadas. Geralmente, você pode pegar o modelo que eles fornecem e mapeá-lo para seu próprio aplicativo.
fonte
Você também pode dar uma olhada no OAuth , um protocolo aberto emergente para autorização baseada em token voltada especificamente para apis http.
É muito semelhante à abordagem adotada pelo flickr e lembre-se das apis de "descanso" do leite (não necessariamente bons exemplos de apis repousantes, mas bons exemplos da abordagem baseada em token).
fonte
Existe uma ótima lista de verificação encontrada no Github :
Autenticação
Não reinvente a roda na autenticação, geração de token e armazenamento de senha. Use os padrões.
Use
Max Retry
e prenda recursos no Login.Use criptografia em todos os dados confidenciais.
JWT (Token da Web JSON)
Use uma chave complicada aleatória (JWT Secret) para dificultar a força bruta do token.
Não extraia o algoritmo da carga útil. Força o algoritmo no back-end (HS256 ou RS256).
Torne a expiração do token (
TTL
,RTTL
) o mais curta possível.Não armazene dados confidenciais na
JWT
carga, eles podem ser decodificados facilmente.OAuth
Valide sempre o
redirect_uri
servidor para permitir apenas URLs na lista de permissões.Sempre tente trocar por código e não por tokens (não permita
response_type=token
).Use o parâmetro state com um hash aleatório para impedir
CSRF
oOAuth
processo de autenticação.Defina o escopo padrão e valide os parâmetros de escopo para cada aplicativo.
Acesso
Solicitações de limite (limitação) para evitar ataques DDoS / força bruta.
Use HTTPS no lado do servidor para evitar MITM (Man In The Middle Attack)
Use o
HSTS
cabeçalho com SSL para evitar o ataque da tira SSL.Entrada
Use o método HTTP adequado de acordo com a operação:
GET
(leia),POST
(crie),PUT/PATCH
(substitua / atualize) eDELETE
(para excluir um registro) e responda com405 Method Not Allowed
se o método solicitado não for apropriado para o recurso solicitado.Validar tipo de conteúdo a pedido
Accept
cabeçalho (Negociação de Conteúdo) para permitir que apenas o seu formato suportado (por exemploapplication/xml
,application/json
, etc) e responder com406 Not Acceptable
resposta se não correspondido.Validar
content-type
de publicado dados que você aceitar (por exemploapplication/x-www-form-urlencoded
,multipart/form-data
,application/json
, etc).Valide a entrada do usuário para evitar vulnerabilidades comuns (por exemplo, XSS, injeção de SQL, execução remota de código etc.).
Não use dados confidenciais (credenciais, senhas, tokens de segurança ou chaves de API) no URL, mas use o
Authorization
cabeçalho padrão .Use um serviço API Gateway para habilitar o cache, as
Rate Limit
políticas (por exemplo, Cota, Spike Arrest, Limite de Taxa Simultânea) e implante recursos de APIs dinamicamente.Em processamento
Verifique se todos os terminais estão protegidos por trás da autenticação para evitar um processo de autenticação quebrado.
O ID do recurso próprio do usuário deve ser evitado. Use / me / orders em vez de / user / 654321 / orders.
Não incremente IDs automaticamente. Use UUID em vez disso.
Se você estiver analisando arquivos XML, verifique se a análise de entidades não está ativada para evitar XXE (ataque de entidade externa XML).
Se você estiver analisando arquivos XML, verifique se a expansão da entidade não está ativada para evitar a bomba Billion Laughs / XML por meio de um ataque de expansão exponencial da entidade.
Use uma CDN para upload de arquivos.
Se você estiver lidando com uma quantidade enorme de dados, use Trabalhadores e Filas para processar o máximo possível em segundo plano e retornar a resposta rapidamente para evitar o bloqueio de HTTP.
Não esqueça de desligar o modo DEBUG .
Resultado
Enviar
X-Content-Type-Options: nosniff
cabeçalho.Enviar
X-Frame-Options: deny
cabeçalho.Enviar
Content-Security-Policy: default-src 'none'
cabeçalho.Remover fingerprinting cabeçalhos -
X-Powered-By
,Server
,X-AspNet-Version
etc.Forçar
content-type
a sua resposta, se você retornar,application/json
então o tipo de conteúdo da resposta éapplication/json
.Não retorne dados confidenciais, como credenciais, senhas, tokens de segurança.
Retorne o código de status adequado de acordo com a operação concluída. (por exemplo
200 OK
,400 Bad Request
,401 Unauthorized
,405 Method Not Allowed
, etc.).fonte
Estou surpreso com o SSL com certificados de cliente ainda não mencionado. Concedido, essa abordagem só é realmente útil se você puder contar com a comunidade de usuários que está sendo identificada por certificados. Mas vários governos / empresas os emitem para seus usuários. O usuário não precisa se preocupar em criar mais uma combinação de nome de usuário / senha, e a identidade é estabelecida em todas as conexões para que a comunicação com o servidor possa ser totalmente sem estado, sem necessidade de sessões do usuário. (Para não implicar que qualquer / todas as outras soluções mencionadas exijam sessões)
fonte
Todos nestas respostas ignoraram o verdadeiro controle / autorização de acesso.
Se, por exemplo, suas APIs / serviços REST da Web forem sobre registros médicos de POST / GETing, convém definir uma política de controle de acesso sobre quem pode acessar os dados e sob quais circunstâncias. Por exemplo:
Para definir e implementar essas autorizações refinadas, você precisará usar uma linguagem de controle de acesso baseada em atributo chamada XACML, a eXtensible Access Control Markup Language.
Os outros padrões aqui são os seguintes:
XACML é independente de tecnologia. Pode ser aplicado a aplicativos java, .NET, Python, Ruby ... serviços da web, APIs REST e muito mais.
A seguir, são recursos interessantes:
fonte
Eu usei o OAuth algumas vezes e também usei outros métodos (BASIC / DIGEST). Sugiro sinceramente OAuth. O link a seguir é o melhor tutorial que eu já vi sobre o uso do OAuth:
http://hueniverse.com/oauth/guide/
fonte
Uma das melhores postagens que eu já vi sobre Segurança no que se refere ao REST terminou em 1 RainDrop . As APIs do MySpace usam o OAuth também por segurança e você tem acesso total aos canais personalizados no código RestChess, com o qual eu fiz muita exploração. Isso foi demonstrado no Mix e você pode encontrar a postagem aqui .
fonte
Obrigado pelo excelente conselho. Acabamos usando um cabeçalho HTTP personalizado para passar um token de identidade do cliente para o serviço, em preparação para integrar nossa API RESTful à futura estrutura Zermatt Identity da Microsoft. Eu descrevi o problema aqui e nossa solução aqui . Também segui os conselhos de tweakt e comprei o RESTful Web Services - um livro muito bom se você estiver criando uma API RESTful de qualquer tipo.
fonte
OWASP (Projeto de segurança de aplicativos da Web abertos) tem algumas dicas sobre todos os aspectos do desenvolvimento de aplicativos da Web. Este projeto é uma fonte de informações muito valiosa e confiável. Em relação aos serviços REST, você pode verificar isso: https://www.owasp.org/index.php/REST_Security_Cheat_Sheet
fonte
Eu recomendaria o OAuth 2/3. Você pode encontrar mais informações em http://oauth.net/2/
fonte
Eu pesquisei bastante sobre segurança tranquila e também acabamos usando token via cookie do cliente para o servidor para autenticar as solicitações. Usei a segurança de primavera para autorização de solicitações em serviço, pois tive que autenticar e autorizar cada solicitação com base nas políticas de segurança especificadas que já estavam no DB.
fonte
O fato de o mundo SOAP estar muito bem coberto por padrões de segurança não significa que ele é seguro por padrão. Em primeiro lugar, os padrões são muito complexos. A complexidade não é muito amiga das vulnerabilidades de segurança e implementação, como ataques de quebra de assinatura de XML, são endêmicas aqui.
Quanto ao ambiente .NET, não ajudarei muito, mas “Construir serviços da Web com Java” (um bloco com ~ 10 autores) me ajudou muito entender a arquitetura de segurança WS- * e, principalmente, suas peculiaridades.
fonte
O próprio REST não oferece padrões de segurança, mas coisas como OAuth e SAML estão rapidamente se tornando os padrões nesse espaço. No entanto, autenticação e autorização são apenas uma pequena parte do que você precisa considerar. Muitas das vulnerabilidades conhecidas relacionadas a aplicativos da web se aplicam muito às APIs REST. Você deve considerar a validação de entrada, quebra de sessão, mensagens de erro inadequadas, vulnerabilidades internas dos funcionários e assim por diante. É um grande assunto.
fonte
Quero adicionar (de acordo com o stinkeymatt), a solução mais simples seria adicionar certificados SSL ao seu site. Em outras palavras, verifique se o seu URL é HTTPS: //. Isso cobrirá a segurança do seu transporte (economize dinheiro). Com os URLs RESTful, a idéia é mantê-lo simples (diferente do WS * security / SAML), você pode usar oAuth2 / openID connect ou mesmo Basic Auth (em casos simples). Mas você ainda precisará de SSL / HTTPS. Verifique a segurança da API da Web do ASP.NET 2 aqui: http://www.asp.net/web-api/overview/security (artigos e vídeos)
fonte
Como o @Nathan acabou com um simples cabeçalho HTTP, e alguns disseram certificados OAuth2 e SSL do lado do cliente. A essência disso é esta ... sua API REST não deve ter que lidar com segurança, pois isso realmente deve estar fora do escopo da API.
Em vez disso, uma camada de segurança deve ser colocada em cima, seja um cabeçalho HTTP atrás de um proxy da Web (uma abordagem comum como SiteMinder, Zermatt ou mesmo Apache HTTPd) ou tão complicada quanto o OAuth 2.
O principal é que as solicitações devem funcionar sem nenhuma interação do usuário final. Tudo o que é necessário é garantir que a conexão com a API REST seja autenticada. No Java EE, temos a noção de
userPrincipal
que pode ser obtida em umHttpServletRequest
. Também é gerenciado no descritor de implementação que um padrão de URL pode ser seguro para que o código da API REST não precise mais verificar.No mundo do WCF, eu usaria
ServiceSecurityContext.Current
para obter o contexto de segurança atual. Você precisa configurar seu aplicativo para exigir autenticação.Há uma exceção à declaração que tive acima e é o uso de um nonce para impedir replays (que podem ser ataques ou alguém apenas enviando os mesmos dados duas vezes). Essa parte só pode ser manipulada na camada de aplicativo.
fonte
Para Segurança de aplicativos Web, você deve dar uma olhada no OWASP ( https://www.owasp.org/index.php/Main_Page ), que fornece dicas para vários ataques de segurança. Você pode incorporar o maior número possível de medidas para proteger seu aplicativo. Com relação à segurança da API (autorização, autenticação, gerenciamento de identidades), há várias maneiras, como já mencionado (Basic, Digest e OAuth). Existem brechas no OAuth1.0, portanto você pode usar o OAuth1.0a (o OAuth2.0 não é amplamente adotado devido a preocupações com a especificação)
fonte
Já faz um tempo, mas a pergunta ainda é relevante, embora a resposta possa ter mudado um pouco.
Um gateway de API seria uma solução flexível e altamente configurável. Eu testei e usei o KONG um pouco e gostei muito do que vi. O KONG fornece uma API REST de administração própria, que você pode usar para gerenciar usuários.
O Express-gateway.io é mais recente e também é um gateway de API.
fonte