Saltar al contenido
Meeko
Escribe para buscar en las guías y en la referencia de la API. Ábrela desde cualquier página con / o Ctrl K; muévete con las flechas y entra con Intro.
Empezar

Contenidos

En esta página

SessionSecurityError

Una mutación no superó la comprobación de Origin o de CSRF de la sesión, con el código INVALID_ORIGIN o INVALID_CSRF; las respuestas de API y RPC la convierten en 403.

servidor Desde 1.0.0 @meekojs/meeko/server Código fuente
ts
import { SessionSecurityError } from "@meekojs/meeko/server";

SessionSecurityError señala que una petición que cambia datos no superó una comprobación de la sesión. Su code es:

  • INVALID_ORIGIN: la cabecera Origin falta, es null o no es el origen de la aplicación ni uno de SessionManager.allowedOrigins;
  • INVALID_CSRF: la petición trae la cookie de sesión, pero no la cabecera x-meeko-csrf con el token de esa sesión.

La lanzan SessionManager.assertMutationAllowed y, desde 1.2, session.create() en una mutación sin un Origin permitido. API, RPC y errorResponse la convierten en 403 con su código.

Uso#

ts
import { MemorySessionStore, SessionManager, SessionSecurityError } from "@meekojs/meeko/server";

const sessions = new SessionManager({ store: new MemorySessionStore(), secure: false });

export async function guard(request: Request): Promise<Response | undefined> {
  const session = await sessions.load(request);
  try {
    sessions.assertMutationAllowed(request, session);
    return undefined;
  } catch (error) {
    if (error instanceof SessionSecurityError) return Response.json({ code: error.code }, { status: 403 });
    throw error;
  }
}

Tipo#

ts
class SessionSecurityError extends Error {
  constructor(code: 'INVALID_ORIGIN' | 'INVALID_CSRF');
}

Parámetros#

new SessionSecurityError(code):

Parámetro Tipo Descripción
code "INVALID_ORIGIN" | "INVALID_CSRF" El motivo; también es el message.

Valor devuelto#

Un Error con code. No hereda de ApiError, pero errorResponse lo reconoce: 403 {"code":"INVALID_CSRF","status":403,"requestId":"…"}.

Ejemplos#

Una petición de otro origen#

http
POST /api/profile HTTP/1.1
Host: app.example.com
Origin: https://evil.example
Cookie: __Host-meeko.sid=…

Respuesta: 403 {"code":"INVALID_ORIGIN",…}, antes de validar la entrada o ejecutar el handler.

js
// Desde el navegador, en la misma aplicación: el cliente api.* ya lo hace.
const token = document.querySelector('meta[name="meeko-csrf-token"]').content;
await fetch("/api/profile", {
  method: "PUT",
  headers: { "content-type": "application/json", "x-meeko-csrf": token },
  body: JSON.stringify({ name: "Ada" }),
});

El navegador añade Origin por sí mismo. Tras cada respuesta que rota la sesión, el token nuevo llega en x-meeko-csrf-token.

Aceptar el panel de otro subdominio#

ts
new SessionManager({ store, production, allowedOrigins: ["https://admin.example.com"] });

Errores comunes#

Llamar a la API con fetch sin el token#

Incorrectojs
await fetch("/api/profile", { method: "PUT", body: JSON.stringify({ name: "Ada" }) });

Con sesión, la respuesta es 403 INVALID_CSRF. Use el cliente generado (api.profile.put({ body })), que envía el token, o añada x-meeko-csrf.

Correctots
await api.profile.put({ body: { name: "Ada" } });

Un proxy sin MEEKO_PUBLIC_ORIGIN#

Incorrectotexto
Navegador → https://app.example.com → proxy TLS → http://127.0.0.1:4173 (sin MEEKO_PUBLIC_ORIGIN)

La aplicación ve su propio origen como http://127.0.0.1:4173; el Origin del navegador (https://app.example.com) no coincide y cada mutación autenticada responde 403 INVALID_ORIGIN.

Correctotexto
MEEKO_PUBLIC_ORIGIN=https://app.example.com

Un cliente nativo sin Origin#

Incorrectosh
curl -X POST https://app.example.com/api/auth/login -d '{…}'

Desde 1.8, toda mutación sin Origin responde 403 INVALID_ORIGIN, también sin sesión (antes, sólo con origin: "required" o en session.create()). Envíe el origen de la aplicación, o declare origin: "none" en una ruta que no puede recibirlo y verifique otra prueba, como una firma.

Correctosh
curl -X POST https://app.example.com/api/auth/login -H 'origin: https://app.example.com' -H 'content-type: application/json' -d '{…}'

Notas#

  • Qué protege. Origin y CSRF son la defensa frente a una web ajena que envía formularios o fetch con la cookie del usuario. Una petición sin cookie no tiene token, así que desde 1.8 sólo se comprueba su Origin, en toda mutación salvo con origin: "none".
  • Métodos. GET, HEAD y OPTIONS no se comprueban: no deben cambiar datos.
  • Socket. Un upgrade con un Origin ajeno responde 403 INVALID_ORIGIN por HTTP y nunca llega a la sesión.
  • Respuesta prevista. Un 403 no llega a onError del runtime.

Relacionado#

¿Te sirvió esta página?

Añadir un comentario

Se envía al elegir «Sí» o «No». Solo se guardan la página, tu respuesta y el comentario: ni cookies ni datos tuyos.

0 de 2000 caracteres

Editar en GitHub: docs/reference/server/sessionsecurityerror.md