Las solicitudes HTTP contienen encabezados como User-Agent o Content-Type. Además de los encabezados que adjuntan los navegadores, las apps para Android pueden agregar encabezados adicionales, como Cookie o Referrer, a través del intent adicional EXTRA_HEADERS
. Por motivos de seguridad, Chrome filtra algunos de los encabezados adicionales según cómo y dónde se inicia un intent.
Las solicitudes entre orígenes requieren una capa adicional de seguridad, ya que el cliente y el servidor no pertenecen a la misma parte. En esta guía, se explica cómo iniciar esas solicitudes a través de las pestañas personalizadas de Chrome, es decir, los intents que se inician desde apps que abren una URL en la pestaña del navegador. Hasta Chrome 83, los desarrolladores podían agregar encabezados al iniciar una pestaña personalizada. A partir de la versión 83, Chrome comenzó a filtrar todos los encabezados de origen cruzado, excepto los que se encuentran en la lista de entidades aprobadas, ya que los que no se encuentran en la lista representaban un riesgo de seguridad. A partir de Chrome 86, es posible adjuntar encabezados que no están en la lista de entidades aprobadas a las solicitudes entre orígenes cuando el servidor y el cliente están relacionados mediante un vínculo de recursos digitales. Este comportamiento se resume en la siguiente tabla:
Versión de Chrome | Encabezados de CORS permitidos |
---|---|
antes de Chrome 83 | En la lista de aprobación, no aprobados |
De Chrome 83 a Chrome 85 | en la lista de aprobación |
a partir de Chrome 86 | aprobada o no aprobada cuando se configura un vínculo de recursos digitales |
Tabla 1: Filtrado de encabezados de CORS que no están en la lista de entidades aprobadas
En este artículo, se muestra cómo configurar una conexión verificada entre el servidor y el cliente y usarla para enviar encabezados HTTP de listas de entidades aprobadas y no aprobadas. Puedes ir a Cómo agregar encabezados adicionales a los intents de pestañas personalizadas para ver el código.
Segundo plano
Encabezados de solicitud de CORS en la lista de entidades seguras y no en la lista de entidades seguras
El uso compartido de recursos multiorigen (CORS) permite que una aplicación web de un origen solicite recursos de otro. La lista de encabezados aprobados por CORS se mantiene en el estándar de HTML. En la siguiente tabla, se muestran ejemplos de encabezados de la lista de entidades aprobadas:
Encabezado | Descripción |
---|---|
accept-language | Anuncia los lenguajes naturales que comprende el cliente. |
content-language | describe el lenguaje destinado al público actual |
tipo de contenido | Indica el tipo de contenido multimedia del recurso. |
Tabla 2: Ejemplo de encabezados de CORS de la lista de entidades aprobadas.
Los encabezados incluidos en la lista de aprobación se consideran seguros porque no contienen información sensible del usuario y es poco probable que provoquen que el servidor realice operaciones potencialmente dañinas.
En la siguiente tabla, se muestran ejemplos de encabezados que no están en la lista de entidades aprobadas:
Encabezado | Descripción |
---|---|
bearer-token | autentica al cliente en un servidor |
origin | Indica el origen de la solicitud. |
galleta | contiene cookies configuradas por el servidor |
Tabla 3: Ejemplos de encabezados de CORS que no están en la lista de entidades aprobadas.
El estándar HTML desaconseja adjuntar encabezados que no estén en la lista de entidades aprobadas a las solicitudes de CORS, y los servidores suponen que las solicitudes entre dominios solo contienen encabezados que están en la lista de entidades aprobadas. El envío de encabezados que no están en la lista de entidades aprobadas desde dominios de origen cruzado permitiría que las apps de terceros maliciosas creen encabezados que usen de forma inadecuada las cookies del usuario que Chrome (o cualquier otro navegador) almacena y adjunta a las solicitudes. Las cookies podrían autenticar transacciones de servidores maliciosas que, de otro modo, no serían posibles.
Cómo adjuntar encabezados de la lista de entidades aprobadas de CORS a las solicitudes de pestañas personalizadas
Las pestañas personalizadas son una forma especial de abrir páginas web en una pestaña personalizada del navegador. Los intents de pestaña personalizada se pueden crear con CustomTabsIntent.Builder()
. También puedes adjuntar encabezados a estos intents con un Bundle
con la marca Browser.EXTRA_HEADERS
:
CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();
Bundle headers = new Bundle();
headers.putString("bearer-token", "Some token");
headers.putString("redirect-url", "Some redirect url");
intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);
intent.launchUrl(Activity.this, Uri.parse("http://www.google.com"));
Siempre podemos adjuntar encabezados de la lista de entidades aprobadas a las solicitudes de CORS de las pestañas personalizadas. Sin embargo, Chrome filtra los encabezados que no están en la lista de entidades aprobadas de forma predeterminada. Si bien es posible que otros navegadores tengan un comportamiento diferente, los desarrolladores deben esperar que los encabezados que no estén en la lista de entidades aprobadas se bloqueen en general.
La forma admitida de incluir encabezados que no están en la lista de entidades aprobadas en las pestañas personalizadas es verificar primero la conexión entre orígenes con un vínculo de acceso digital. En la siguiente sección, se muestra cómo configurarlos y cómo iniciar un intent de pestañas personalizadas con los encabezados necesarios.
Agrega encabezados adicionales a los intents de pestañas personalizadas
Configura vínculos de recursos digitales
Para permitir que los encabezados que no están en la lista de entidades aprobadas se pasen a través de los intents de la pestaña personalizada, es necesario configurar un vínculo de recursos digitales entre la aplicación para Android y la aplicación web que verifique que el autor es propietario de ambas aplicaciones.
Sigue la guía oficial para configurar un vínculo de recursos digitales. Para la relación de vínculo, usa "delegate_permission/common.use_as_origin", que indica que ambas apps pertenecen al mismo origen una vez que se verifica el vínculo.
Crea un intent de pestaña personalizada con encabezados adicionales
Hay varias formas de crear un intent de pestañas personalizadas. Para usar el compilador disponible en AndroidX, agrega la biblioteca a las dependencias de compilación:
MULTI_LINE_CODE_PLACEHOLDER_1
Compila el intent y agrega encabezados adicionales:
MULTI_LINE_CODE_PLACEHOLDER_2
Configura una conexión de pestañas personalizadas para validar el vínculo del recurso
Se usa una conexión de pestañas personalizadas para configurar un CustomTabsSession
entre la app y la pestaña de Chrome. Necesitamos la sesión para verificar que la app y la app web pertenezcan al mismo origen.
La verificación solo se aprobará si los vínculos de recursos digitales se configuraron correctamente.
Se recomienda llamar a CustomTabsClient.warmup()
. Permite que la aplicación del navegador se inicialice previamente en segundo plano y acelere el proceso de apertura de la URL.
MULTI_LINE_CODE_PLACEHOLDER_3
Cómo configurar una devolución de llamada que inicie el intent después de la validación
Se pasó CustomTabsCallback
a la sesión. Configuramos su
onRelationshipValidationResult()
para que inicie el CustomTabsIntent
creado anteriormente una vez que la verificación de origen se realice correctamente.
MULTI_LINE_CODE_PLACEHOLDER_4
Vincula la conexión del servicio de pestañas personalizadas
Cuando vinculas el servicio, se inicia el servicio, y se llamará al onCustomTabsServiceConnected()
de la conexión en algún momento. No olvides desvincular el servicio de forma adecuada. La vinculación y desvinculación suele realizarse en los métodos del ciclo de vida de la actividad onStart()
y onStop()
.
// Bind the custom tabs service connection.
// Call this in onStart()
CustomTabsClient.bindCustomTabsService(this,
CustomTabsClient.getPackageName(MainActivity.this, null), connection);
// …
// Unbind the custom tabs service.
// Call this in onStop().
unbindService(connection);
Código de la aplicación de demostración
Puedes encontrar más detalles sobre el servicio de pestañas personalizadas aquí. Consulta el repositorio android-browser-helper de GitHub para ver una app de ejemplo que funcione.
Resumen
En esta guía, se muestra cómo agregar encabezados arbitrarios a las solicitudes de CORS de las pestañas personalizadas. Los encabezados de la lista de entidades seguras se pueden adjuntar a cada solicitud de CORS de las pestañas personalizadas. Por lo general, los encabezados no aprobados se consideran no seguros en las solicitudes de CORS y Chrome los filtra de forma predeterminada. Solo se permite adjuntarlos a clientes y servidores del mismo origen, verificados por un vínculo de activos digitales.