Ao trabalhar com um site baseado em recursos (como um aplicativo MVC ou serviço REST), temos duas opções principais quando um cliente tenta GET
um recurso ao qual não tem acesso:
- 403 , que diz que o cliente não é autorizado ; ou
- 404 , que diz que o recurso não existe (ou não pôde ser localizado).
O senso comum e a prática comum parecem ser responder com a verdade - isto é, um 403. Mas estou me perguntando se isso é realmente a coisa certa a se fazer.
Os sistemas de logon seguro nunca informam o motivo de uma falha no logon. Ou seja, no que diz respeito ao cliente, não há diferença detectável entre um nome de usuário inexistente e uma senha incorreta. O objetivo é não tornar identificações de usuário - ou, pior, endereços de email - detectáveis.
Do ponto de vista da privacidade , parece muito mais seguro retornar um 404. Lembro-me do incidente em que alguém supostamente descobriu os vencedores de um reality show (acho que o Survivor) observando quais recursos não existiam no site. site versus quais. Estou preocupado com o 403 potencialmente fornecer informações confidenciais como um número de série ou número de conta.
Existem razões convincentes para não retornar um 404? Uma política 404 poderia ter efeitos colaterais negativos em outro lugar? Caso contrário, por que a prática não é mais comum?
fonte
Respostas:
Existe um equívoco geral (e uso indevido) associado
403 Forbidden
: ele não deve revelar nada sobre o que o servidor pensa sobre a solicitação. Foi projetado especificamente para dizer,Qualquer UA ou cliente deve interpretar isso para significar que a solicitação nunca funcionará e responder adequadamente.
Isso tem implicações para os clientes que manipulam solicitações em nome dos usuários: se um usuário não estiver logado ou digitar errado, o cliente que manipula a solicitação deverá responder: "Sinto muito, mas não posso fazer nada" depois da primeira vez. ele obtém
403
oe deixa de manipular solicitações futuras. Obviamente, se você deseja que um usuário ainda possa solicitar acesso a suas informações pessoais após uma falha, esse é um comportamento hostil ao usuário.403
está em contraste com401 Authorization Required
, que não dar que o servidor irá processar o pedido, desde que você passar as credenciais corretas. Geralmente é isso que as pessoas pensam quando ouvem403
.Também está em contraste com o
404 Page Not Found
que, como outros apontaram, foi projetado não apenas para dizer "Não consigo encontrar essa página", mas para sugerir ao cliente que o servidor não faz reivindicações de sucesso ou fracasso para solicitações futuras.Com
401
e404
, o servidor não diz nada ao cliente ou ao UA sobre como eles devem proceder: eles podem continuar tentando na esperança de obter uma resposta diferente.Assim
404
é a maneira apropriada de lidar com uma página que você não deseja mostrar a todos, mas não quer revelar nada sobre o motivo de não mostrá-la em determinadas situações.Obviamente, isso pressupõe que o cliente que faz a solicitação se preocupe com a mesquinha mesquinha RFC. Um cliente mal-intencionado não se preocupa com o código de status retornado, exceto de maneira incidental. Alguém saberá que é uma página de usuário oculta (ou uma possível página de usuário oculta) comparando-a com outras páginas de usuário conhecidas.
Ou seja, digamos que seu manipulador seja
users/*
. Se eu seiusers/foo
,users/bar
eusers/baaz
trabalho, o servidor retornar um401
,403
ou404
porusers/quux
não significa que eu não vou experimentá-lo, especialmente se eu tenho razão para acreditar que não é umquux
usuário. Um cenário de exemplo padrão é o Facebook: meu perfil é privado, mas meus comentários em perfis públicos não. Um cliente mal-intencionado sabe que eu existo, mesmo que você retorne404
à minha página de perfil.Portanto, os códigos de status não são para casos de uso mal-intencionados, são para os clientes que seguem as regras. E para esses clientes, uma
401
ou uma404
solicitação é mais apropriada.fonte
quux
existe. Mas nem sempre haverá evidências externas, especialmente em sites não sociais onde os dados do cliente são realmente privados . Um usuário intrometida ou hostil pode, eventualmente, ser capaz de deduzir que você está mentindo, mas não necessariamente que recursos você está deitado sobre . Eu acho que o ponto mais importante aqui é realmente, não se preocupe com os recursos 404, a menos que não haja outros métodos de descoberta disponíveis.De acordo com a RFC2616
Observe também que, ao acessar recursos Proibidos, a autorização não ajuda .
fonte
HttpUnauthorizedResult
que se destina a ser usado para recursos privilegiados . Também percebo (obviamente) que 404 pode ser usado; minha pergunta é se é ou não deve ser usado, eo que deve ser considerado quando tomar essa decisão.Você deveria? Sim .
Você mesmo disse, trair o mínimo possível. Se eu estivesse atacando um sistema e percebesse que o servidor respondeu com 403 códigos, eu me concentraria neles, em vez de seguir em frente. Melhor uma porta proclamar que ela não existe do que proclamar que está sendo barrada.
A desvantagem do uso de solicitações 404 é que, externamente, ela aparecerá como se a página não existisse, e isso poderia ter conflitos quando comparado às páginas que deveriam existir, mas que estão ausentes. Se você não está preocupado com os rastreadores da Web (os sistemas autenticados devem ser totalmente negados de qualquer maneira), você deve absolutamente fazê-lo. Toda API que manipule o acesso não autorizado exatamente da mesma maneira, assim como o StackOverflow . Não consegue ver essa página? Eu lhe asseguro que faz existir, mesmo que ele não afirma.
Você deve reconhecer pedidos quando o recurso é conhecido de existir e o acesso é negado. Um logon com falha não deve resultar em uma mensagem 404. Você não deve aceitar solicitações quando a existência do recurso em si deve ser protegida. O acesso à região existe em público, mas os grupos ou funções de segurança nela não são.
Os desenvolvedores devem ter acesso aos logs, o que indicará uma tentativa de acessar um recurso protegido. Clientes / Usuários / Testadores gerarão feedback que acabará atingindo um desenvolvedor.
Isso não é segurança pela obscuridade. Você está usando a obscuridade , além das medidas de segurança adequadas.
Eles não são solicitações válidas, são solicitações não autorizadas . Você está mudando uma pequena parte (retorne 404 em vez de 403) para obter uma vantagem substancial em qualquer possível atacante.
fonte
Realmente depende das informações fornecidas pelo código de status 403. Se você tiver um terminal da API respondendo
GET /myresource/{id}
com um 404 quando o recurso não existir, o código de status retornado pelo terminal quando o recurso existir, mas não estiver autorizado para o usuário atual, dependerá da previsibilidade doid
parâmetro e da quantidade das informações que ele contém por si só.id
for um campo particular como um endereço de email ou um número de conta bancária, provavelmente sempre deve estar oculto atrás de um 404. No caso de um endereço de email, isso pode impedir que os bots de spam compilem uma lista de endereços de email válidos registrados no seu site.id
for um nome de usuário público, não se preocupe, existem outros meios para obter acesso a essas informações (por exemplo, apenas navegando na página do fórum do seu site).id
for um identificador opaco, mas previsível (por exemplo, um número inteiro com incremento automático), você não fornece nenhuma informação ao invasor que ele não poderia obter por outros meios. Portanto, na minha opinião, é seguro retornar um código de status 403.id
é um identificador opaco e imprevisível (como um GUID aleatório), a questão é mais sutil. Pessoalmente, acho que não há problema em retornar um código de status 403. Essas informações só poderiam ser exploradas se houver outro ponto de extremidade defeituoso na sua API usando esse ID, mas a falha real É o seu outro ponto de extremidade.Você pode supor que é melhor prevenir do que remediar em qualquer caso e ocultar as informações em qualquer contexto, mas na verdade não pode confiar nesse tipo de comportamento para fornecer qualquer forma de segurança . Por outro lado, pode fornecer confidencialidade (ou privacidade, como outros já disseram).
Um mecanismo de segurança não deve ser apenas uma lombada para o invasor, caso contrário, é simplesmente inútil. Nesse caso, pode até impedir que você use outros recursos corretamente (rastreadores, firewall de aplicativos da Web procurando quantidades anormais de códigos de status 403 para bloquear usuários ...).
fonte