Volver al Blog
Plataforma

Política de mismo origen y aislamiento de sitios

Comprende la identidad del origen, las restricciones entre orígenes, el contenido incrustado y el aislamiento sin confundir navegador y servidor.

BotBrowser Team

Documentación

Quieres la documentación estructurada de Plataforma?

Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.

Dos orígenes intercambian un mensaje permitido a través del límite de la política del navegador

La política de mismo origen es una regla del navegador que limita cómo un documento o script puede leer y manipular otro origen. Un origen combina esquema, host y puerto. Una página en https://app.example.test comparte origen con otra página situada exactamente en ese origen, pero cambiar el esquema, el host o el puerto crea un origen diferente. La política establece un límite para los datos visibles desde scripts y las relaciones entre documentos. No es un cortafuegos de red, no sustituye la autorización del servidor ni garantiza que una respuesta no pueda enviarse por la red.

El aislamiento de sitios es una arquitectura del navegador y una defensa de seguridad que mantiene los documentos de sitios distintos en espacios de ejecución separados cuando el navegador puede hacerlo. Reduce el impacto de una intrusión en el proceso de renderizado y ayuda a contener los datos entre sitios, mientras la política de mismo origen sigue decidiendo qué pueden leer los scripts. Estas ideas se refuerzan, pero responden a preguntas distintas. Una frontera entre procesos no valida al cliente de una API, y una restricción de scripts no decide cómo asigna procesos el navegador.

Esta distinción importa al depurar. Una solicitud puede llegar al servidor mientras JavaScript no puede leer la respuesta. Un iframe puede renderizarse aunque su documento padre no pueda inspeccionar el DOM hijo. El navegador puede colocar las páginas en espacios de ejecución separados mientras la aplicación sigue aceptando una solicitud no autorizada que cambia el estado. Registra por separado la observación del navegador, la respuesta del servidor y el resultado de la aplicación. Así, el informe de compatibilidad sigue siendo útil sin insinuar una propiedad de seguridad que no se haya probado.

Cómo se identifica un origen

El modelo de orígenes HTML de WHATWG define un origen mediante esquema, host y puerto para los documentos de red ordinarios. https://shop.example.test:443 y https://shop.example.test normalmente resuelven al mismo puerto efectivo, mientras que http://shop.example.test es diferente porque cambia el esquema. https://cdn.example.test es diferente porque cambia el host, aunque la misma organización controle ambos. Por tanto, un alias de desarrollo, un nombre de host de staging o un puerto no predeterminado pueden crear un límite que no existe en un fixture local.

Algunos documentos tienen un origen opaco. Un iframe en sandbox sin el token de origen adecuado, un documento data: o un documento creado desde una URL blob: puede tener un origen que no se representa mediante la URL visible como ocurre con un documento de red. Trata el valor de origen del navegador y la relación de incrustación documentada como entradas de prueba. No deduzcas confianza de un nombre de host conocido, un certificado o el control del dominio padre.

Las cookies, el almacenamiento, los permisos, los service workers y muchas API web usan conceptos de origen o sitio con reglas relacionadas, pero no idénticas. Una cookie puede limitarse a un dominio registrable, mientras que localStorage se limita a un origen. Un sitio puede contener varios orígenes, y un frame cross-origin puede seguir siendo del mismo sitio según una definición de sitio que tenga en cuenta el esquema. Cuando una prueba cambie el host o el protocolo, define las expectativas para cada almacén de estado y registra el location.origin final. La guía del modelo de almacenamiento del navegador explica con más detalle estos límites.

La comparación de orígenes debe ser una aserción explícita. En un fixture propio, informa de location.origin para el documento de nivel superior y para cada frame probado. Para un mensaje recibido de otra ventana, compara event.origin con el valor esperado antes de usar sus datos. La comprobación demuestra que el mensaje procede del origen declarado; no demuestra que la aplicación remota haya autorizado la acción ni que el contenido sea seguro. Valida el esquema de los datos y el estado actual del flujo como comprobaciones de aplicación independientes.

Qué permite la política de mismo origen

La referencia de MDN sobre la política de mismo origen describe la regla general: los scripts de un origen tienen acceso restringido a los documentos y datos de otro origen. Los scripts del mismo origen pueden leer nodos del DOM, la mayor parte del almacenamiento de ese origen y los cuerpos de respuesta devueltos a su propio contexto JavaScript. Los scripts cross-origin a menudo pueden navegar una ventana o enviar un formulario, pero no pueden leer directamente el DOM de destino ni bytes arbitrarios de la respuesta. Las concesiones exactas dependen de la API y su especificación, así que clasifica la operación en vez de tratar «cross-origin» como un único resultado de sí o no.

Las solicitudes de red cross-origin ilustran este límite. El navegador puede enviar una solicitud y el servidor devolver un estado correcto, mientras Fetch oculta la respuesta al script que llama si la respuesta no cumple CORS. Por eso el panel de red puede mostrar 200 junto con un error CORS en la página. CORS es un contrato para compartir respuestas; no concede autorización del servidor ni vuelve confiable un endpoint. Consulta la guía de límites CORS del navegador cuando la cuestión sea la legibilidad de la respuesta y no el acceso al documento.

Las relaciones entre ventanas también están limitadas. Una página puede conservar una referencia a una ventana emergente cross-origin y usar un conjunto reducido de operaciones, pero no puede inspeccionar propiedades arbitrarias de esa ventana. postMessage ofrece un canal de comunicación intencionado. El receptor debe comprobar event.origin, validar event.source cuando sea posible y analizar una estructura de mensaje restringida. Al enviar, usa un origen de destino concreto. Un destino comodín puede ser adecuado para un mensaje deliberadamente público, pero no debe usarse para datos de sesión o de cuenta.

Los frames tienen un origen de documento independiente. Un padre puede renderizar un iframe cross-origin sin obtener permiso para leer su DOM, y el hijo no puede leer el DOM del padre por el simple hecho de estar incrustado. Un iframe del mismo origen sí comparte muchas superficies visibles para scripts con su padre, por lo que una página comprometida puede afectar a ambos documentos. Define un límite claro de propiedad y confianza para cada frame. Si un frame necesita una función del navegador, evalúa Permissions Policy, los requisitos de contexto seguro y el permiso del usuario por separado de la decisión de mismo origen.

Contenido incrustado y comunicación

Trata una relación incrustada como un conjunto de contratos. Primero identifica los orígenes del padre y del hijo después de las redirecciones. Después identifica la operación necesaria: renderizado visual, navegación, envío de formularios, intercambio de mensajes, lectura de respuestas o acceso al DOM. Por último, documenta la regla del navegador y la comprobación de autorización de la aplicación para esa operación. Una página que solo necesita mostrar una imagen no debería recibir los mismos privilegios que un frame que intercambia el estado de una cuenta.

Relación u operaciónEvidencia del navegadorDecisión de la aplicación y lo que no demuestra
Acceso al DOM del mismo origenAmbos documentos informan del mismo esquema, host y puertoPermite solo código propio; valida aun así el estado y la autorización
Renderizado de frame cross-originEl frame carga e informa de su origen finalRenderizar no concede acceso al DOM ni a la respuesta
Lectura de respuesta cross-originRespuesta CORS y modo de solicitudLa legibilidad no equivale a autorización del servidor ni éxito de negocio
Mensaje de ventanaevent.origin, origen y esquema esperadosAcepta solo el mensaje declarado; no confíes únicamente en el origen
Documentos aislados por sitioContexto visible del navegador y compilación declaradaSeparar procesos no demuestra la seguridad de la aplicación

Las redirecciones merecen especial atención. La URL con la que comienza una prueba puede no ser el origen que devuelve el documento. Sigue la respuesta final y cualquier navegación del frame, y luego afirma el origen final. Un servidor también puede redirigir a otro sitio, cambiando el comportamiento de cookies, almacenamiento y CORS. Mantén las comprobaciones de redirección en el fixture para que un cambio posterior de infraestructura no desplace silenciosamente un flujo de confianza a través de un límite.

No uses document.domain como plan moderno de integración. Históricamente relajó el acceso entre subdominios, pero cambia el modelo de origen efectivo, tiene costes de compatibilidad y seguridad, y se está retirando de las recomendaciones de la plataforma web. Prefiere mensajería explícita, una carcasa de aplicación del mismo origen o una API mediada por el servidor con autenticación y autorización normales. Si una integración antigua aún depende de ello, registra la dependencia y prueba tanto la ruta heredada como su sustituta.

Qué aporta el aislamiento de sitios

La introducción al aislamiento de sitios de Chromium describe el aislamiento de sitios como una defensa que separa páginas de sitios distintos en espacios de ejecución del navegador. En varios contextos de la plataforma web, un sitio es una agrupación más amplia que un origen. Dos subdominios pueden ser orígenes diferentes y pertenecer al mismo sitio, mientras que las páginas con dominios registrables distintos pertenecen a sitios diferentes. La planificación del navegador es una decisión de implementación que puede cambiar según la plataforma, la presión de memoria, la versión del navegador y las relaciones entre documentos.

El aislamiento de sitios ayuda a reducir la cantidad de datos entre sitios expuestos si el proceso de renderizado sufre un problema de seguridad de memoria. No convierte cada sitio en una cuenta independiente del sistema operativo ni transforma una observación del navegador en una garantía de la aplicación. No bases la autorización del producto en una suposición sobre el comportamiento del renderizador. El servidor debe autenticar la solicitud, comprobar el propietario del recurso, aplicar las reglas de CSRF y tokens cuando corresponda y validar las transiciones de estado.

Los grupos de contextos de navegación y las relaciones de apertura pueden afectar al aislamiento. Una ventana emergente abierta entre sitios puede no compartir el mismo grupo o relación de scripts que una ventana emergente del mismo origen. COOP y COEP pueden cambiar además las relaciones entre ventanas y la carga de recursos, como se describe en la guía de aislamiento cross-origin. Estos encabezados son independientes de la política de mismo origen. Una página puede compartir origen con un hijo y seguir sin estar aislada, o ser cross-origin con un hijo que se carga bajo una política compatible.

El aislamiento de sitios también tiene límites relacionados con extensiones, superficies privilegiadas del navegador, service workers y comportamientos específicos del navegador. Una prueba debe indicar la familia del navegador, el rango de versiones, el sistema operativo y las suposiciones sobre funciones. Evita afirmar que un número de procesos o una asignación interna concreta sea estable. La aserción pública útil es el comportamiento de seguridad visible: un documento cross-origin no puede leer los datos protegidos y la aplicación rechaza un cambio de estado no autorizado. Estos resultados siguen siendo significativos aunque el navegador cambie su implementación.

Un fixture de política determinista

El siguiente fixture usa dos páginas propiedad del mismo equipo. La página de control y la candidata crean un marco, intentan un intercambio de mensajes declarado y muestran un resultado visible. El resultado esperado procede de la configuración de la prueba, no de la respuesta del navegador. El fixture no lee contenido privado de terceros, inspecciona procesos internos ni envía credenciales.

async function checkOriginBoundary({ frameUrl, expectedOrigin, expectedMessage }) {
  const host = document.createElement('section');
  const status = document.createElement('output');
  status.setAttribute('aria-live', 'polite');
  const frame = document.createElement('iframe');
  frame.src = frameUrl;
  host.append(frame, status);
  document.body.append(host);

  const result = await new Promise(resolve => {
    const timer = setTimeout(() => resolve({ passed: false, reason: 'timeout' }), 3000);
    window.addEventListener('message', function onMessage(event) {
      if (event.source !== frame.contentWindow) return;
      clearTimeout(timer);
      window.removeEventListener('message', onMessage);
      const originMatches = event.origin === expectedOrigin;
      const messageMatches = event.data?.type === expectedMessage;
      resolve({ passed: originMatches && messageMatches, originMatches, messageMatches });
    });
  });

  try {
    status.textContent = result.passed
      ? 'PASS: declared origin and message'
      : `FAIL: ${result.reason || 'boundary mismatch'}`;
    console.assert(result.passed, status.textContent);
    return { ...result, visibleResult: status.textContent };
  } finally {
    host.remove();
  }
}

await checkOriginBoundary({
  frameUrl: 'https://owned-child.example.test/fixture',
  expectedOrigin: 'https://owned-child.example.test',
  expectedMessage: 'owned-fixture-ready',
});

El fixture hijo debe enviar su mensaje solo cuando su propia página esté lista y usar el origen declarado por el padre como destino de postMessage. El padre verifica la ventana de origen, el origen exacto y el tipo de mensaje antes de actualizar el resultado visible. Un tiempo de espera agotado es un fallo del fixture, no una prueba de bloqueo por mismo origen. Clasifica por separado los errores de navegación, carga del frame, política y aplicación para que una interrupción de red no se informe como una decisión de seguridad del navegador.

Para probar un control del mismo origen y un candidato cross-origin, mantén idénticos el comportamiento de las páginas y el esquema de mensajes, cambiando únicamente la relación de origen. Usa URL estables y propias, y una espera limitada. El control debe mostrar el mensaje esperado. El candidato debe mostrar el comportamiento cross-origin declarado, por ejemplo un mensaje recibido mediante postMessage mientras el acceso directo al DOM sigue sin estar disponible. No intentes obtener datos protegidos como prueba. El resultado visible y el error de acceso documentado por el navegador bastan para esta prueba de límites.

La limpieza debe estar en una ruta finally. Elimina el frame temporal, retira los listeners de eventos, cancela los temporizadores y cierra el contexto aislado del navegador en el ejecutor de pruebas. Si el fixture creó un registro sintético en el servidor, elimínalo mediante un endpoint de pruebas propio e informa de la limpieza por separado. Conserva el primer fallo de aserción si la limpieza también falla. Un desmontaje limpio no demuestra que un sistema remoto haya borrado datos no relacionados.

Desplegar, supervisar y revertir

Empieza con un inventario de orígenes. Enumera los hosts canónicos de la aplicación, los hosts de recursos, los proveedores de identidad, los frames de clientes, los endpoints de analítica y los destinos de redirección. Para cada dependencia, registra si la aplicación necesita renderizado, navegación, mensajería, lectura de respuestas o acceso al DOM. Indica el responsable y el contrato de autorización del servidor. Este inventario evita que una suposición de mismo sitio oculte una relación cross-origin y ofrece al equipo de soporte un punto de partida concreto cuando cambie un despliegue.

Ejecuta el fixture de control y el candidato en staging con los nombres de host y las políticas de respuesta definitivos. Registra el origen final, la versión del navegador, el origen del marco, el estado visible, el estado de red y el resultado de la aplicación. Comprueba que una respuesta HTTP correcta no se confunda con una respuesta legible y que una política del navegador no se confunda con un rechazo del servidor. Mantén los informes sin contenido de cuentas ni credenciales. Repite las comprobaciones tras cambios en CDN, redirecciones, proveedor de identidad o versión del navegador.

Despliega los cambios en una secuencia acotada. Primero publica el fixture propio y la telemetría de los resultados visibles. Después cambia la política de respuesta o incrustación para un origen de staging. Luego prueba ventanas de inicio de sesión, pagos, marcos de clientes, cargas y cualquier flujo que cruce orígenes. Confirma que funciona el canal de mensajes previsto y que el acceso no autorizado al DOM o a respuestas sigue bloqueado. Promueve solo cuando comprendas el flujo visible y su alternativa.

La reversión debe restaurar la combinación anterior de aplicación y políticas, no quitar una aserción. Conserva los encabezados anteriores, el mapa de redirecciones y la configuración de marcos. Si un cambio rompe un flujo esencial, restaura la configuración conocida como válida, ejecuta de nuevo los fixtures de control y candidato y clasifica el límite que falla. Mantén HTTPS, autenticación y autorización durante la reversión. No amplíes una lista de orígenes permitidos ni aceptes orígenes de mensajes arbitrarios solo para que una prueba pase.

Qué puede validar BotBrowser

BotBrowser admite contextos de navegador controlados para ejecutar fixtures autorizados de origen propio, comparar resultados visibles de la política de mismo origen y repetir observaciones de aislamiento de sitios en una compilación declarada. Su documentación de aislamiento multicuenta describe contextos separados para recorridos independientes. Así puedes obtener evidencia repetible del origen final de una página, del resultado de mensajes del marco y de la alternativa de la aplicación, manteniendo el estado sintético limitado a la prueba.

BotBrowser no cambia un origen, no concede autorización del servidor, no desactiva las reglas del navegador, no garantiza una distribución concreta de procesos ni sustituye los controles de seguridad de la aplicación. El navegador, los encabezados de respuesta, la autorización del servidor y el código de la aplicación siguen siendo responsables de sus respectivos límites. Una ejecución controlada correcta muestra lo que el navegador y el despliegue declarados expusieron a la prueba. No certifica todos los navegadores, todos los socios de incrustación ni cada decisión de permisos del servidor.

BotBrowser permite ejecutar fixtures propios autorizados y comparar sus resultados visibles, pero no puede otorgar autorización del servidor ni validar por sí solo una transición de negocio.

Para conocer límites relacionados, consulta la guía del modelo de almacenamiento del navegador, la guía de límites CORS del navegador y la guía de aislamiento cross-origin. Cubren la partición del estado, la legibilidad de respuestas y los encabezados de aislamiento. Este artículo se centra en la identidad de los orígenes, el acceso de scripts, la comunicación incrustada y el papel del aislamiento de sitios.

Consulta la guía CORS del navegador y la guía de aislamiento cross-origin para límites relacionados.

Autor: Equipo de BotBrowser

Fuentes

#Same-Origin Policy#Site Isolation#Web Security#Origins

Lleva BotBrowser de la investigación a producción

Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.