Supongamos que tengo una API REST que también se usa para establecer / restablecer contraseñas. Supongamos también que esto funciona sobre conexiones HTTPS. ¿Hay alguna buena razón para no poner esa contraseña en la ruta de llamada, también digamos que la codificaré en BASE64?
Un ejemplo sería restablecer una contraseña como esta:
http://www.example.com/user/joe/resetpassword/OLDPASSWD/NEWPASSWD
Entiendo que BASE64 no es encriptación, pero solo quiero proteger la contraseña para navegar por el hombro en este caso.
resetpassword/OLDPASSWD/NEWPASSWD
no es un recurso. Es una invocación de un proceso. No necesita insertar todo en una URL.Respuestas:
Un buen servidor registra todas las solicitudes que se le envían, incluidas las URL (a menudo, sin parte variable después de '?'), IP de origen, tiempo de ejecución ... ¿Realmente desea que este registro (potencialmente leído por un amplio grupo de administradores) contenga ¿Información críticamente segura como contraseñas? Base64 no es un obstáculo contra ellos.
fuente
Lo que está proponiendo no es seguro ni RESTful.
@Netch ya ha mencionado el problema con los registros, pero también hay otro problema en el que muestra las contraseñas enviadas por HTTP, por lo que es trivial capturar contraseñas con cualquier tipo de sniffer de cable o ataque de hombre en el medio.
Cuando realiza una solicitud GET utilizando REST, los diferentes elementos en la URL representan elementos más específicos. Su URL se lee como si estuviera devolviendo una parte NEWPASSWD de una OLDPASSWD que es parte de una contraseña de restablecimiento. Eso no tiene ningún sentido semántico. Los GET no deben usarse para guardar datos.
Deberías estar haciendo algo como esto:
PUBLICA porque estás escribiendo datos, y https porque no quieres que los analice.
(Esta es realmente la seguridad de barra baja. El mínimo absoluto que debe hacer).
fuente
/user/joe/password
es un poco mejor pero no óptimo.PUT
, porquePUT
es idempotente. Pero cuando la contraseña se ha cambiado desecret
a consupersecret
éxito, la misma solicitud fallará la segunda vez, por lo quePOST
es correcto aquí. Por supuesto, como dijo @whirlwin, este recurso no está bien nombrado.El esquema propuesto tiene problemas en varias áreas.
Seguridad
Las rutas de URL se registran con frecuencia; poner contraseñas sin usar en el camino es una mala práctica.
HTTP
La información de autenticación / autorización debe aparecer en el encabezado de Autorización. O potencialmente, para cosas basadas en el navegador, el encabezado Cookie.
DESCANSO
Los verbos como
resetpassword
en su URL son generalmente un signo claro de un paradigma de transferencia de estado no representativo. Una URL debe representar un recurso. ¿Qué significa OBTENERresetpassword
? O ELIMINAR?API
Este esquema requiere saber siempre la contraseña anterior. Probablemente desee permitir más casos; Por ejemplo, la contraseña se pierde.
Puede usar la autenticación básica o implícita , que son esquemas bien entendidos.
No pone información ultrasensible en la ruta, y sigue las convenciones HTTP y REST.
Si necesita permitir algún otro modo de autorización (por ejemplo, algún token enviado a través de un canal verificado para restablecer la contraseña), simplemente puede usar un encabezado de Autorización diferente sin tener que cambiar nada más.
fuente
Además de la seguridad, el problema con esto es que no es un enfoque RESTANTE.
OLDPASSWD
yNEWPASSWD
no represente nada en su jerarquía de recursos y, lo que es peor, la operación no es idempotente.Por lo tanto, solo puede usar
POST
como verbo, y no debe incluir las dos contraseñas en su ruta de recursos.fuente
PUT
se descalifica como verbo. Podría ser modificado para trabajar,PUT
pero en su forma actual no lo hace.El problema es evitar contraseñas de texto sin formato en sus solicitudes. Hay dos opciones para cumplir con los requisitos de servicio web reparador.
1. Hashing del lado del cliente
2. Cifrado
Nota: ¡ Se requiere HTTPS para ambas opciones!
fuente
¿Cuáles son las características de una operación de restablecimiento de contraseña?
El punto 1 aquí significa que no puede usar GET, debe PUBLICAR algo que representa la operación de cambio de contraseña en un URI que representa un recurso que maneja los cambios de contraseña, o PONER algo que representa la nueva contraseña en un URI que representa la contraseña o que representa algo (p. Ej. usuario) de los cuales esa contraseña es una característica.
En general, PUBLICAREMOS, sobre todo porque puede ser incómodo PONER algo que no podemos OBTENER más tarde y, por supuesto, no podemos OBTENER la contraseña.
El punto 2, por lo tanto, serán datos que representan la nueva contraseña, en lo que se PUBLICA.
El punto 3 significa que necesitaremos autorizar la solicitud, lo que significa que si el usuario es el usuario actual, necesitaremos que nos demuestren la contraseña actual (aunque no necesariamente recibamos la contraseña actual, por ejemplo, si se trata de un desafío basado en hash) se usó para probar su conocimiento sin enviarlo).
Por lo tanto, el URI debe ser algo como
<http://example.net/changeCurrentUserPassword>
o<http://example.net/users/joe/changePassword>
.Podríamos decidir que queremos recibir la contraseña actual en los datos POST, así como en el mecanismo de autorización general que se utiliza.
fuente