Seguridad en ExpressJS

CORS

CORS es el acrónimo de Cross-Origin Resource Sharing. Consiste en

el envío de cabeceras que determinan si el cliente bloquea el código de JavaScript de forma que este no pueda acceder a respuestas de orígenes distintos a donde se encuentra alojado el cliente.

CORS prohíbe el acceso a los recursos de orígenes cruzados. Pero CORS permite a los servidores web decir que desean optar por permitir el acceso de origen cruzado a sus recursos.

Preflight

Cuando tenemos una petición web con el método OPTIONS, el módulo cors nos maneja la situación.

Cuando un navegador necesita hacer una petición compleja con origen cruzado1, primero se envía la petición con el método OPTIONS, llamada petición preflight, para comprobar si el servidor entiende CORS. Esta permite comprobar si el servicio permite la petición real que queremos hacer. Esta petición OPTIONS concreta emplea tres cabeceras, Access-Control-Request-Method2, Access-Control-Request-Headers3, y la cabecera Origin4. De esta forma, con estas cabeceras, el servidor podrá determinar ai la petición final es segura y la acepta o la rechaza.

Si la acepta y responde con código 204 (No Content), el cliente procede a realizar la petición.

Módulo CORS en express

El middleware CORS responde a las peticiones preflight con las cabeceras apropiadas según hayamos configurado, Se encarga de manejar las respuestas que espera el cliente añadiendo:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • responde a la petición con 204

Podríamos hacer algo parecido de forma manual, siguiendo el siguiente ejemplo:

this.express.use((req, res, next) => {
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
  res.header('Access-Control-Allow-Origin', 'http://localhost:5173');
  res.header(
    'Access-Control-Allow-Headers',
    'Authorization,Apikey,X-foo-user,content-type,extrahost',
  );
  if (req.method === 'OPTIONS') {
    return res.status(204).end();
  }
  next();
});

pero es más fácil simplemente usar el middleware.

this.express.use(
  cors(
    {
      origin: ['localhost:5173'],
      allowedHeaders: ['Authorization', 'Apikey', 'X-foo-user', 'content-type', 'extrahost'],
      methods: 'GET,PUT,POST,DELETE,OPTIONS'
    }
  )
);

Enlaces


  1. Por ejemplo con un método complejo o con cabeceras customizadas. ↩︎

  2. Cabecera para decirle al servidor qué métodos serán permitidos en la petición real. Es necesario porque la primera, la petición OPTIONS, no usa el método de la petición que el usuario quiere realmente hacer. ↩︎

  3. Para decirle al servidor las posibles cabeceras que podrá lleva la petición final. El servidor responde con la cabecera Access-Control-Allow-Headers↩︎

  4. También usada en POST, no solo en peticiones preflight, le dice al servidor el nombre del servidor que hace la petición. ↩︎