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 cualquier encabezado cuando iniciaban 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 | aprobadas, no aprobadas |
De Chrome 83 a Chrome 85 | incluida en la lista de entidades permitidas |
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 aprobadas y no aprobadas
El uso compartido de recursos multiorigen (CORS) permite que una aplicación web de un origen solicite recursos de un origen diferente. La lista de encabezados aprobados por CORS se mantiene en el Estándar 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 |
content-type | Indica el tipo de contenido multimedia del recurso. |
Tabla 2: Ejemplo de encabezados de CORS aprobados.
Los encabezados de la lista de entidades aprobadas se consideran seguros porque no contienen información sensible del usuario y es poco probable que hagan 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 iniciar páginas web en una pestaña del navegador personalizada. 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 una vinculación 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
Existen 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
La vinculación del servicio lo inicia y, con el tiempo, se llamará a onCustomTabsServiceConnected()
de la conexión. 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 de GitHub de android-browser-helper para ver una app de ejemplo funcional.
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 que no están en la lista de entidades aprobadas 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.