Seguridad en las APIs

Índice

  • HTTPS
  • Data leaks
  • IDs predecibles
  • Authentication
  • Control de acceso
  • SQL Injection
  • CORS
  • XSS

HTTPS

Aunque pueda resultar obvio, utilizar HTTPS es siempre el primer paso para securizar una web.

 

- Todo va cifrado, previniendo sniffing en la red.

 

- Dificulta ataques tipo Man in the Middle.

¿Qué es el cifrado?

a b c d e f g h i j k l m n o p q r s t u v w x y z

z a b c d e f g h i j k l m n o p q r s t u v w x y

david

czuhc

a b c d e f g h i j k l m n o p q r s t u v w x y z

w x y z a b c d e f g h i j k l m n o p q r s t u v

david

zwrez

Cifrado César

Desplazamiento

1

Desplazamiento

4

¿Cómo funciona el HTTPS?

Cliente

Servidor

¿Desplazamiento?

Desplazamiento X

GET /url

Respuesta cifrada

Network Sniffing

Router

Tu

ordenador

Ordenador

sniffer

Tu tráfico

Tu tráfico

Data Leaks

Muchas veces exponemos por defecto todos los datos que contienen nuestros recursos, exponiendo información que no debería estar disponible para cualquier usuario.

 

Apliquemos el SRP a los endpoints:

- Más endpoints

- Más pequeños

Bien

Mal

{
  "name": "David",
  "link": "/user/david",
  "avatar": "/img/david.png",
  "mail": "david.hernandez@politicalwatch.es",
  "pass": "password"
}
{
  "name": "David",
  "link": "/user/david",
  "avatar": "/img/david.png"
}

IDs predecibles

Normalmente en la base de datos tenemos IDs secuenciales. Cuando tenemos un endpoint para obtener estos datos, es común usar ese ID para acceder a estos datos.

Mal

Bien

GET /usuario/1

{
  "name": "David",
  "link": "/user/david",
  "avatar": "/img/david.png",
  "id": 1
}

GET /usuario/1234-ABCD

{
  "name": "David",
  "link": "/user/david",
  "avatar": "/img/david.png",
  "uuid": "1234-ABCD"
}

Authentication

Al igual que en una web no todo es público y tenemos inicios de sesión para controlar el acceso, en las APIs también es necesario controlar quién puede acceder a qué endpoint.

 

Aunque podemos implementar un sistema de autentificacion de 0, ya existen sistemas preparados para hacerlo:

- OAuth

- JWT

¿Cómo funciona?

Cliente

Servidor

Servicio de autentificación

Endpoints

HTTP Request con credenciales

HTTP Response con token

Request con token

Response con datos

Request sin token

401: Unauthorized 

OAuth VS JWT

PROs:

- Externalizamos la auth.

- Mejor con varios clientes.

 

CONs:

- Damos info a terceros.

- Más complejo de montar.

PROs:

- Mejor con solo un cliente.

- Queda todo en local.

 

CONs:

- No sirve para no APIs.

Control de acceso

Si yo como usuario, no debería poder acceder a la información de otro usuario, ¿porque en las APIs si que puedo?

 

Una vez tenemos implementado un sistema de autentificación, debemos hacer otros controles de acceso.

 

- ¿El usuario tiene acceso a ese recurso?

- ¿Puede ver todos los campos?

Y si juntamos todo esto...

SQL Injection

Este ataque puede ocurrir cuando los parámetros que usa el endpoint se utilizan para realizar operaciones en la base de datos y estos no son debidamente sanitizados.

 

Es importante que cualquier dato que se mande a la API no se utilice directamente contra la base de datos.

Ejemplo

const mysql = require('mysql');

const connection = mysql.createConnection(config);

app.get('/user/:id', (req, res) => {
  const id = req.params.id
  const sql = 'SELECT * FROM users WHERE id = ' + id
  connection.query(sql)
}));

GET /user/1

GET /user/1; DELETE FROM users WHERE 1=1

CORS

Significa `Cross-origin resource sharing` y es un mecanismo de los servidores que impide responder a una request que no viene de un dominio autorizado.

 

Por defecto, el único dominio autorizado es el que use la API.

 

Es importante no desactivar el CORS a menos que sea estrictamente necesario.

XSS

Significa `Cross-site scripting` y es cuando un atacante consigue inyectar código malicioso en el HTML que se renderiza al usuario.

 

Por ejemplo, un atacante podría inyectar un minero de cryptomonedas o un script para robar datos del usuario.

Ejemplo

app.get('/user/:id', (req, res) => {
  const id = req.params.id
  res.send('Usuario: ' + id)
}));

GET /user/1

GET /user/<script src="cryptominer.js"/>

¿Preguntas?

Seguridad en las APIs

By david_hernandez

Seguridad en las APIs

  • 828