Suponha que eu tenha uma API REST que também seja usada para definir / redefinir senhas. Suponhamos também que isso funcione em conexões HTTPS. Existe algum bom motivo para não colocar essa senha no caminho da chamada, digamos também que eu a codificarei no BASE64?
Um exemplo seria redefinir uma senha como esta:
http://www.example.com/user/joe/resetpassword/OLDPASSWD/NEWPASSWD
Entendo que o BASE64 não é criptografia, mas só quero proteger a senha para navegar no ombro neste caso.
resetpassword/OLDPASSWD/NEWPASSWD
não é um recurso. É uma invocação de um processo. Você não precisa colocar tudo em um URL.Respostas:
Um bom servidor registra todas as solicitações enviadas a ele, incluindo URLs (geralmente, sem parte variável após '?'), IP de origem, tempo de execução ... Deseja realmente que esse log (potencialmente lido por um amplo grupo de administradores) contenha informações criticamente seguras como senhas? Base64 não é uma rolha contra eles.
fonte
O que você está propondo não é seguro nem RESTful.
O @Netch já mencionou o problema nos logs, mas também existe outro problema, no qual você está mostrando senhas enviadas por HTTP, tornando trivial capturar senhas com qualquer tipo de farejador de fio ou ataque man-in-the-middle.
Quando você faz uma solicitação GET usando REST, os diferentes elementos na URL representam elementos mais refinados. Seu URL parece que você está retornando uma parte NEWPASSWD de um OLDPASSWD que faz parte de uma senha redefinida. Isso não faz nenhum tipo de sentido semântico. GETs não devem ser usados para salvar dados.
Você deveria estar fazendo algo assim:
POST porque você está gravando dados e https porque você não deseja que ele cheire.
(Essa é realmente a segurança de barra baixa. O mínimo absoluto que você deve fazer.)
fonte
/user/joe/password
é um pouco melhor, mas não é o ideal.PUT
, porquePUT
é idempotente. Mas quando a senha for alterada desecret
para comsupersecret
êxito, a mesma solicitação falhará na segunda vez, portanto,POST
está correta aqui. Obviamente, como @whirlwin disse, esse recurso não é bem conhecido.O esquema proposto tem problemas em várias áreas.
Segurança
Os caminhos de URL são freqüentemente registrados; colocar senhas unidas no caminho é uma prática ruim.
HTTP
As informações de autenticação / autorização devem aparecer no cabeçalho da autorização. Ou, potencialmente, para itens baseados em navegador, o cabeçalho Cookie.
DESCANSAR
Os verbos como
resetpassword
no seu URL geralmente são um sinal claro de um paradigma de transferência de estado não representacional. Um URL deve representar um recurso. O que significa GETresetpassword
? Ou excluir?API
Esse esquema exige sempre o conhecimento da senha anterior. Você provavelmente desejará permitir mais casos; por exemplo, a senha é perdida.
Você pode usar a autenticação Básica ou Digest , que são esquemas bem compreendidos.
Ele não coloca informações ultra-sensíveis no caminho e segue as convenções HTTP e REST.
Se você precisar permitir algum outro modo de autorização (por exemplo, algum token enviado por um canal verificado para redefinir a senha), você pode simplesmente usar um cabeçalho de Autorização diferente sem precisar alterar mais nada.
fonte
Além da segurança, o problema é que não é uma abordagem muito RESTful.
OLDPASSWD
eNEWPASSWD
não represente nada na hierarquia de recursos e, pior ainda, a operação não é idempotente.Portanto, você só pode usar
POST
como seu verbo e não deve incluir as duas senhas no caminho do recurso.fonte
PUT
é desqualificada como verbo. Poderia ser rejeitado para trabalhar,PUT
mas na sua forma atual não funciona.O problema é evitar senhas de texto sem formatação em suas solicitações. Existem duas opções para atender aos requisitos de serviço da web.
1. Hash do lado do cliente
2. Criptografia
Nota: HTTPS é necessário para ambas as opções!
fonte
Quais são os recursos de uma operação de redefinição de senha?
O ponto 1 aqui significa que você não pode usar GET, você deve POST algo representando a operação de alteração de senha em um URI que representa um recurso que lida com alterações de senha ou PUT algo que representa a nova senha em um URI que representa a senha ou representa algo (por exemplo, o usuário) cuja senha é um recurso.
Geralmente, nós POSTAMOS, não menos importante, porque pode ser estranho COLOCAR algo que não podemos obter mais tarde e, é claro, não podemos obter a senha.
O ponto 2, portanto, serão os dados que representam a nova senha, no que é POSTADO.
O ponto 3 significa que precisaremos autorizar a solicitação, o que significa que, se o usuário for o usuário atual, precisaremos que a senha atual seja comprovada (embora não necessariamente receba a senha atual, se, por exemplo, um desafio baseado em hash foi usado para provar o conhecimento dele sem enviá-lo).
O URI deve, portanto, ser algo como
<http://example.net/changeCurrentUserPassword>
ou<http://example.net/users/joe/changePassword>
.Podemos decidir que queremos receber a senha atual nos dados do POST, bem como no mecanismo de autorização geral que está sendo usado.
fonte