Agregando a la apariencia de alto nivel el buen diseño de API que proporcionó @Daisetsu, la mejor manera de realmente asegurar una API REST basada en la web se reduce a dos opciones:
1 Enviar todo a través de HTTPS. Permitir que el usuario se autentique con la API para obtener una clave de sesión, e incluirla en cada consulta futura.
BUENO : todo es seguro.
BAD : el costo de negociar la conexión HTTPS requiere más recursos del servidor (no es un problema a menos que tenga una API de uso intensivo) y el tiempo de respuesta de una llamada será más prolongado.
2 Utilice un HMAC (firma) y envíelo junto con cada solicitud.
2 es lo que usan gran parte de las API de los servicios web de Amazon y el método más popular para implementar el enfoque suele denominarse "OAuth de dos patas".
2 puede parecer confuso / aleatorio / increíblemente complejo dado su nivel de comodidad con seguridad, por lo que describiré la esencia de cómo funciona:
- El SERVIDOR y el CLIENTE comparten 2 valores: una clave pública y privada.
- La clave pública puede ser conocida por más personas, eso está bien.
- La clave privada NO PUEDE. Solo debe ser conocido por el servidor y el cliente.
- Cuando el cliente realiza una solicitud al servidor, envía 2 cosas importantes: la clave pública y un HMAC (también conocido como "firma")
La firma representa un hash de los parámetros incluidos en la solicitud: /search.json?public_key=123456&term=shritam&range=180days&sig=dKdjalkjDKd97daskdDKl2
- El hash se calcula combinando todos los parámetros que conforman la consulta en una cadena, luego ejecutando la cadena y la clave secreta a través de un algoritmo de hashing como MD5, SHA-1, SHA-256, etc.
- El servidor recibe la solicitud y, antes de hacer cualquier otra cosa, utilizando la clave pública que figura en la solicitud, busca la clave secreta del usuario.
- Luego, el servidor vuelve a combinar todos los parámetros de solicitud EXACTAMENTE DE LA MISMA MANERA que el cliente lo hizo, y los codifica con la clave secreta que acaba de extraer de la base de datos para ese usuario.
- Si los hashes coinciden, se ejecuta la solicitud. Si los hashes no coinciden, se deniega la solicitud.
Dado lo pedante y delicado que es la naturaleza de generar un hash (si la entrada es 1 carácter diferente, como un espacio adicional, el hash resultante es diferente) tiene que haber reglas REALMENTE específicas sobre cómo se combinan los parámetros, cómo están codificados, cómo se combinan con la clave secreta, etc.
Afortunadamente, la especificación OAuth 1.0 (Secciones 3.4.1 a 3.4.2) hace exactamente eso; establecen exactamente el proceso que el servidor y el cliente deben seguir al generar ese hash, de modo que cualquier cliente o servidor compatible con OAuth puede comunicarse entre sí de manera más efectiva.
Nota al margen: OAuth 2.0 está fuera, ¡cógelo!
Independientemente de si usa OAuth o no, solo debe asegurarse de que sus clientes y el servidor estén de acuerdo en CÓMO se crea y firma la cadena. Amazon Web Services utiliza un método ligeramente diferente para generar la cadena para firmar al insertar nuevas líneas donde OAuth simplemente concatena todo junto.
He visto algunas API en línea que generan el HMAC haciendo que la persona tenga su clave pública con su clave secreta y la envíe; en ese caso, básicamente, está convirtiendo el HMAC en un ID de sesión y corre el riesgo de sufrir los mismos problemas de conexión lateral que sufren las APIs de overs-unsecured de sesiones.
Tenga en cuenta que cualquier parámetro que incluya en la generación HMAC no se puede cambiar mediante una intercepción de hombre en el medio y reenviando su consulta.
Cualquier parámetro que NO ES parte del cálculo de HMAC, puede ser modificado por un intermediario y reenviado porque no forma parte de la firma, por lo que cuando el servidor va a recalcular el HMAC, no lo hará. vea los hash mal emparejados causados por el cambio.
Estos son los aspectos más destacados de la protección de una API REST basada en HTTP (no HTTPS).