Compartir a través de


Imposición de una directiva de seguridad de contenido para ASP.NET Core Blazor

Nota

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión de .NET 9 de este artículo.

Advertencia

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la directiva de compatibilidad de .NET y .NET Core. Para la versión actual, consulte la versión de .NET 9 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión de .NET 9 de este artículo.

En este artículo se explica cómo usar una directiva de seguridad de contenido (CSP) con aplicaciones Blazor de ASP.NET Core para protegerse frente a determinados tipos de ataques malintencionados, como Cross-Site Scripting (XSS) y ataques de clickjacking (secuestro de clic) . XSS es una vulnerabilidad de seguridad en la que un ciberattacker coloca uno o varios scripts malintencionados del lado cliente en el contenido representado de una aplicación. En un ataque de robo de clics, un usuario es engañado para que interactúe con un sitio web ficticio que tiene tu aplicación incrustada en él.

Un CSP ayuda a protegerse contra estos tipos de ataques informando al navegador sobre cuáles son válidos.

  • Orígenes de contenido cargado, incluidos scripts, hojas de estilo, imágenes y complementos.
  • Acciones realizadas por una página, especificando los destinos de URL permitidos de formularios
  • Cuando la aplicación se puede incrustar en otro sitio web a través de etiquetas <frame>, <iframe>, <object>o <embed>.

Se recomienda leer los siguientes recursos de MDN al implementar un CSP:

Para aplicar una directiva de seguridad de contenido en una aplicación, el desarrollador especifica varias directivas de seguridad de contenido en uno o varios encabezados Content-Security-Policy o etiquetas <meta>. Para ver las instrucciones sobre cómo aplicar un CSP a una aplicación en código C# al iniciarse, consulte la sección Inicio de Blazor en ASP.NET Core y la sección La directiva frame-ancestors que se ve más adelante en este artículo.

El explorador evalúa las directivas mientras una página se carga. El navegador inspecciona los orígenes de la página y determina si cumplen los requisitos de las directivas de seguridad de contenido. Cuando un recurso no cumple estas directivas, el explorador no lo carga. Pensemos, por ejemplo, en una directiva que no permite scripts de terceros. Si una página contiene una etiqueta <script> con un origen de terceros en el atributo src, el explorador impide que el script se cargue.

CSP se admite en la mayoría de los navegadores de escritorio y móviles actualmente, como Chrome, Edge, Firefox, Opera y Safari. Se recomienda CSP para aplicaciones Blazor.

Advertencia

La implementación de un CSP minimiza el riesgo de ciertos tipos de amenazas de seguridad y no garantiza que una aplicación sea completamente segura frente a ataques XSS y clickjacking. Los agentes de usuario, normalmente exploradores, pueden permitir que los usuarios modifiquen o omitan la aplicación de directivas a través de preferencias de usuario, marcadores, extensiones de explorador, adiciones de terceros al agente de usuario y otros mecanismos de este tipo. Además, los CSP solo se centran en corregir un subconjunto de ataques, no todos los ataques que pueden poner en peligro la seguridad, como la inyección de código SQL, la falsificación de solicitudes entre sitios (CSRF), la configuración incorrecta de seguridad y los ataques de denegación de servicio (DoS).

Directivas

Las siguientes directivas y fuentes se usan normalmente para las aplicaciones de Blazor. Añada directivas y fuentes adicionales según sea necesario. Las siguientes directivas se usan en la sección Aplicar la directiva de este artículo, donde se proporcionan directivas de seguridad de ejemplo para aplicaciones Blazor:

  • base-uri: restringe las direcciones URL de la etiqueta <base> de una página. Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
  • default-src: indica una solución alternativa para las directivas de origen que no se especifican explícitamente por la política. Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
  • img-src: indica orígenes válidos para las imágenes.
    • Especifique data: para permitir la carga de imágenes de direcciones URL data:.
    • Especifique https: para permitir la carga de imágenes desde puntos de conexión HTTPS.
  • object-src: indica orígenes válidos para las etiquetas <object>, <embed>y <applet>. Especifique none para no permitir ningún origen de dirección URL.
  • script-src: indica las fuentes válidas para los guiones.
    • Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
    • En una aplicación Blazor del lado cliente:
      • Especifique wasm-unsafe-eval para permitir que funcione el entorno de ejecución Mono Blazor del lado cliente.
      • Especifique hashes adicionales para permitir que se carguen los scripts ajenos al marco necesarios. Por ejemplo, indique unsafe-hashes con un hash de sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0= para permitir JavaScript insertado en el activador de navegación en el componente NavMenu.
    • En una aplicación Blazor del lado servidor, especifique códigos hash para permitir que se carguen los scripts necesarios.
  • style-src: indica orígenes válidos para hojas de estilos.
    • Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
    • Si la aplicación utiliza estilos en línea, especifique unsafe-inline para permitir el uso de sus estilos en línea.
  • connect-src: restringe las direcciones URL que se pueden cargar mediante interfaces de script. Se especifican los orígenes de esquema http:, ws: (protocolo WebSocket) y wss: (protocolo WebSocket Secure).
  • upgrade-insecure-requests: indica que las direcciones URL de contenido de fuentes inseguras (HTTP) deben adquirirse de manera segura a través de HTTPS.
  • base-uri: restringe las direcciones URL de la etiqueta <base> de una página. Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
  • default-src: indica una solución alternativa para las directivas de origen que no se especifican explícitamente por la política. Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
  • img-src: indica orígenes válidos para las imágenes.
    • Especifique data: para permitir la carga de imágenes de direcciones URL data:.
    • Especifique https: para permitir la carga de imágenes desde puntos de conexión HTTPS.
  • object-src: indica orígenes válidos para las etiquetas <object>, <embed>y <applet>. Especifique none para no permitir ningún origen de dirección URL.
  • script-src: indica las fuentes válidas para scripts.
    • Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
    • En una aplicación Blazor del lado cliente:
      • Especifique unsafe-eval para permitir que funcione el entorno de ejecución Mono Blazor del lado cliente.
      • Especifique hashes adicionales para permitir que se carguen los scripts externos al marco necesarios.
    • En una aplicación Blazor del lado servidor, especifique códigos hash para permitir que se carguen los scripts necesarios.
  • style-src: indica orígenes válidos para hojas de estilos.
    • Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
    • Si la aplicación usa estilos en línea, especifique unsafe-inline para permitir el uso de sus estilos en línea.
  • connect-src: restringe las direcciones URL que se pueden cargar mediante interfaces de script. Se especifican los orígenes de esquema http:, ws: (protocolo WebSocket) y wss: (protocolo WebSocket Secure).
  • upgrade-insecure-requests: indica que las direcciones URL de contenido de orígenes no seguros (HTTP) deben adquirirse de forma segura a través de HTTPS.
  • base-uri: restringe las direcciones URL de la etiqueta <base> de una página. Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
  • default-src: indica una solución alternativa para las directivas de origen que no se especifican explícitamente por la política. Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
  • img-src: indica orígenes válidos para las imágenes.
    • Especifique data: para permitir la carga de imágenes de direcciones URL data:.
    • Especifique https: para permitir la carga de imágenes desde puntos de conexión HTTPS.
  • object-src: indica orígenes válidos para las etiquetas <object>, <embed>y <applet>. Especifique none para no permitir ningún origen de dirección URL.
  • script-src: Indica las fuentes válidas para scripts.
    • Especifique el origen de host https://stackpath.bootstrapcdn.com/ para los scripts de Bootstrap.
    • Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
    • En una aplicación Blazor del lado cliente:
      • Especifique unsafe-eval para permitir que funcione el entorno de ejecución Mono Blazor del lado cliente.
      • Especifique hashes adicionales para permitir que se carguen los scripts no pertenecientes al marco necesarios.
    • En una aplicación Blazor del lado servidor, especifique códigos hash para permitir que se carguen los scripts necesarios.
  • style-src: indica orígenes válidos para hojas de estilos.
    • Especifique el origen del host https://stackpath.bootstrapcdn.com/ para las hojas de estilo de Bootstrap.
    • Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
    • Especifique unsafe-inline para permitir el uso de estilos en línea.
  • connect-src: restringe las direcciones URL que se pueden cargar mediante interfaces de script. Se especifican los orígenes de esquema http:, ws: (protocolo WebSocket) y wss: (protocolo WebSocket Secure).
  • upgrade-insecure-requests: indica que las direcciones URL de contenido de orígenes no seguros (HTTP) deben adquirirse de forma segura a través de HTTPS.
  • base-uri: restringe las direcciones URL de la etiqueta <base> de una página. Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
  • default-src: indica una solución alternativa para las directivas de origen que no se especifican explícitamente por la política. Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
  • img-src: indica orígenes válidos para las imágenes.
    • Especifique data: para permitir la carga de imágenes de direcciones URL data:.
    • Especifique https: para permitir la carga de imágenes desde puntos de conexión HTTPS.
  • object-src: indica orígenes válidos para las etiquetas <object>, <embed>y <applet>. Especifique none para no permitir ningún origen de dirección URL.
  • script-src: Indica las fuentes válidas para scripts.
    • Especifique el origen de host https://stackpath.bootstrapcdn.com/ para los scripts de Bootstrap.
    • Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
    • En una aplicación Blazor del lado cliente:
      • Especifique códigos hash para permitir que se carguen los scripts necesarios.
      • Especifique unsafe-eval para usar eval() y métodos para crear código a partir de cadenas.
    • En una aplicación Blazor del lado servidor, especifique códigos hash para permitir que se carguen los scripts necesarios.
  • style-src: indica orígenes válidos para hojas de estilos.
    • Especifique el origen de host https://stackpath.bootstrapcdn.com/ para las hojas de estilo de Bootstrap.
    • Especifique self para indicar que el origen de la aplicación (incluido el esquema y el número de puerto) es un origen válido.
    • Especifique unsafe-inline para permitir el uso de estilos en línea. La declaración en línea es necesaria en la interfaz de usuario para volver a conectar el cliente y el servidor después de la solicitud inicial. En una versión futura, es posible que los estilos en línea se eliminen, de forma que unsafe-inline ya no sea necesario.
  • connect-src: restringe las direcciones URL que se pueden cargar mediante interfaces de script. Se especifican los orígenes de esquema http:, ws: (protocolo WebSocket) y wss: (protocolo WebSocket Secure).
  • upgrade-insecure-requests: indica que las direcciones URL de contenido de orígenes no seguros (HTTP) deben adquirirse de forma segura a través de HTTPS.

Todos los exploradores, excepto Microsoft Internet Explorer, admiten las directivas anteriores.

Para obtener los hash SHA de otros scripts insertados:

  • Aplique la CSP que se muestra en la sección Aplicación de la política.
  • Acceda a la consola de herramientas de desarrollo del explorador mientras ejecuta la aplicación localmente. El explorador calcula y muestra los hashes de los scripts bloqueados cuando existe un encabezado CSP o una etiqueta meta.
  • Copie los hash proporcionados por el navegador en los orígenes script-src. Inserte cada hash entre comillas simples.

Para obtener una matriz de compatibilidad de exploradores de nivel 2 de directiva de seguridad de contenido, vea ¿Puedo usar una directiva de seguridad de contenido de nivel 2?

Aplicación de la directiva

Puede aplicar un CSP a través de:

  • Un encabezado de respuesta emitido por el host (por ejemplo, IIS) o emitido por la aplicación (consulte Encabezados de control en código C# al iniciar).
  • Una etiqueta <meta>. Este artículo solo muestra el enfoque de etiqueta <meta>.

Para usar una etiqueta <meta> para aplicar la directiva:

  • Establezca el valor del atributo http-equiv en Content-Security-Policy.
  • Coloque las directivas en el valor de atributo content. Separe las directivas con un punto y coma (;). No se requiere un punto y coma final para la última directiva de la cadena de la política según la especificación de nivel 3 de la Política de Seguridad de Contenidos .
  • Coloque la etiqueta <meta> en el contenido <head> justo dentro de la etiqueta <head> de apertura. La directiva se evalúa y aplica cuando se analiza el marcado de CSP, por lo que la directiva debe aparecer en la parte superior del marcado de <head> para asegurarse de que se aplica en todas las etiquetas <script> y <link>.

En las secciones siguientes se muestran directivas de ejemplo. Estos ejemplos pertenecen a la versión de Blazor correspondiente a este artículo. Para usar la versión adecuada en su caso, seleccione la versión del documento usando el selector desplegable Versión de esta página web.

Directiva frame-ancestors

La directiva frame-ancestors especifica los padres válidos que pueden insertar una página con etiquetas <frame>, <iframe>, <object>o <embed>. No se puede aplicar una directiva frame-ancestors a través de un CSP basado en etiquetas <meta>. La directiva debe aplicarse mediante un encabezado de respuesta. Un host de servidor puede agregar un encabezado de respuesta de CSP o el código de C# de la aplicación puede agregar o actualizar un CSP con una directiva de frame-ancestors.

Blazor Web Apps (.NET 8 o posterior) incluyen automáticamente un encabezado de respuesta que define el valor como 'self':

Content-Security-Policy: frame-ancestors 'self'

Para cambiar el valor predeterminado al 'none' más restrictivo e impedir que todos los elementos principales inserten la aplicación, cambie la opción ContentSecurityFrameAncestorsPolicy en la llamada a AddInteractiveServerRenderMode en el archivo Program. Lo siguiente solo surte efecto cuando la compresión de WebSocket está habilitada (se establece<xref:Microsoft.AspNetCore.Components.Server.ServerComponentsEndpointOptions.ConfigureWebSocketAcceptContext%2A>, que es el valor predeterminado para las aplicaciones de Blazor).

.AddInteractiveServerRenderMode(o => o.ContentSecurityFrameAncestorsPolicy = "'none'")

En las aplicaciones de Blazor Server, no se agrega una directiva predeterminada de frame-ancestors a la colección de encabezados de respuesta. Puede añadir manualmente un encabezado de CSP con middleware en la canalización de procesamiento de solicitudes.

app.Use(async (context, next) =>
{
    context.Response.Headers.Add("Content-Security-Policy", "frame-ancestors 'none'");
    await next();
});

Advertencia

Evite establecer el valor de la directiva frame-ancestors en 'null' cuando la compresión de WebSocket esté habilitada (la compresión es el valor predeterminado), ya que hace que la aplicación sea vulnerable a la inyección de scripts malintencionadas y ataques de robo de clic.

Para obtener más información, consulte CSP: frame-ancestors (documentación de MDN).

Aplicaciones Blazor del lado servidor

El ejemplo siguiente es un punto de partida para el desarrollo posterior. En la parte superior del contenido <head>, aplique las directivas descritas en la sección Directivas de política, junto con cualquier otra directiva que necesite la especificación de la aplicación.

Para aplicaciones de categoría Blazor Web Appo Blazor Server.

<meta http-equiv="Content-Security-Policy" content="
    base-uri 'self';
    default-src 'self';
    img-src data: https:;
    object-src 'none';
    script-src 'self' 'wasm-unsafe-eval' 'unsafe-hashes' 
        'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0=';
    style-src https:;
    connect-src 'self' http: ws: wss:;
    upgrade-insecure-requests;" />

Blazor Web Apps incluye un controlador de eventos insertado onclick de JavaScript en el componente NavMenu que necesita uno de los siguientes cambios:

  • Agregue un hash a la directiva script-src con la palabra clave unsafe-hashes:

    'unsafe-hashes' 'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0='
    

    Para obtener más información, consulte CSP: script-src: Script insertado no seguro (documentación de MDN).

  • Mueva el controlador de eventos JavaScript en línea a un archivo o módulo de JavaScript que la política permita cargar.

Blazor Web Apptambién incluye un componente ImportMap en el contenido de <head> que representa una etiqueta <script> de asignación de importación insertada. Para modificar la directiva para permitir que se cargue la asignación de importación, consulte la sección Resolución de vulneraciones de CSP con integridad de subrecursos (SRI) o un nonce criptográfico.

Para aplicaciones de Blazor Server:

<meta http-equiv="Content-Security-Policy" content="
    base-uri 'self';
    default-src 'self';
    img-src data: https:;
    object-src 'none';
    script-src 'self';
    style-src 'self';
    connect-src 'self' http: ws: wss:;
    upgrade-insecure-requests">

Para aplicaciones de Blazor Server:

<meta http-equiv="Content-Security-Policy" content="
    base-uri 'self';
    default-src 'self';
    img-src data: https:;
    object-src 'none';
    script-src 'self' https://stackpath.bootstrapcdn.com/;
    style-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com/;
    connect-src 'self' http: ws: wss:;
    upgrade-insecure-requests">

Para aplicaciones de Blazor Server:

<meta http-equiv="Content-Security-Policy" content="
    base-uri 'self';
    default-src 'self';
    img-src data: https:;
    object-src 'none';
    script-src 'self' https://stackpath.bootstrapcdn.com/ 
        'sha256-34WLX60Tw3aG6hylk0plKbZZFXCuepeQ6Hu7OqRf8PI=';
    style-src 'unsafe-inline' https://stackpath.bootstrapcdn.com/;
    connect-src 'self' http: ws: wss:;
    upgrade-insecure-requests">

Nota

El hash SHA256 anterior es para fines de demostración. Es posible que tenga que calcular un nuevo hash para su CSP.

Agregue los códigos hash script-src y style-src adicionales según lo requiera la aplicación. Durante el desarrollo, use una herramienta en línea o las herramientas para desarrolladores del navegador a fin de calcular los códigos hash. Por ejemplo, el siguiente error de la consola de herramientas del explorador notifica el hash de un script necesario no incluido en la directiva:

Se ha rechazado ejecutar el script en línea porque viola la siguiente directiva de seguridad de contenido: " ... ". Para habilitar la ejecución en línea se requiere la palabra clave "unsafe-inline", un hash ("sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA =") o un nonce ("nonce-...").

El script concreto asociado al error se muestra en la consola junto a dicho error.

Para obtener instrucciones sobre cómo aplicar una CSP a una aplicación en código de C# al inicio, vea Inicio de Blazor de ASP.NET Core.

Aplicaciones Blazor del lado cliente

El ejemplo siguiente es un punto de partida para el desarrollo posterior. En el <head> contenido, debe aplicar las directivas descritas en la sección de Directivas de la política:

<meta http-equiv="Content-Security-Policy" content="
    base-uri 'self';
    default-src 'self';
    img-src data: https:;
    object-src 'none';
    script-src 'self' 'wasm-unsafe-eval';
    style-src 'self';
    connect-src 'none';
    upgrade-insecure-requests">
<meta http-equiv="Content-Security-Policy" content="
    base-uri 'self';
    default-src 'self';
    img-src data: https:;
    object-src 'none';
    script-src 'self' 'unsafe-eval';
    style-src 'self';
    connect-src 'none';
    upgrade-insecure-requests">
<meta http-equiv="Content-Security-Policy" content="
    base-uri 'self';
    default-src 'self';
    img-src data: https:;
    object-src 'none';
    script-src 'self' 'unsafe-eval' 
        'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=';
    style-src 'self';
    connect-src 'none';
    upgrade-insecure-requests">

Nota

El hash sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA= representa el script insertado que se usa para las aplicaciones Blazor del lado cliente. Esto puede quitarse en el futuro.

<meta http-equiv="Content-Security-Policy" content="
    base-uri 'self';
    default-src 'self';
    img-src data: https:;
    object-src 'none';
    script-src 'self' 'unsafe-eval' https://stackpath.bootstrapcdn.com/ 
        'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=';
    style-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com/;
    upgrade-insecure-requests">
<meta http-equiv="Content-Security-Policy" content="
    base-uri 'self';
    default-src 'self';
    img-src data: https:;
    object-src 'none';
    script-src 'self' 'unsafe-eval' https://stackpath.bootstrapcdn.com/ 
        'sha256-v8ZC9OgMhcnEQ/Me77/R9TlJfzOBqrMTW8e1KuqLaqc=' 
        'sha256-If//FtbPc03afjLezvWHnC3Nbu4fDM04IIzkPaf3pH0=' 
        'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=';
    style-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com/;
    upgrade-insecure-requests">

Agregue los códigos hash script-src y style-src adicionales según lo requiera la aplicación. Durante el desarrollo, use una herramienta en línea o las herramientas para desarrolladores del navegador para que se calculen los hashes por usted. Por ejemplo, el siguiente error de la consola de herramientas del explorador notifica el hash de un script necesario no incluido en la directiva:

Se ha rechazado ejecutar el script en línea porque infringe la siguiente directiva de seguridad de contenido: " ... ". Para habilitar la ejecución en línea se requiere la palabra clave "unsafe-inline", un hash ("sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA =") o un nonce ("nonce-...").

El script concreto asociado al error se muestra en la consola junto a dicho error.

Resolución de vulneraciones de CSP con integridad de subrecursos (SRI) o un nonce criptográfico

Dos enfoques para resolver infracciones de CSP, que se describen en las dos secciones siguientes, son:

Adoptar integridad de subrecursos (SRI)

La integridad de subrecursos (SRI) permite a los exploradores confirmar que los recursos capturados no se manipulan en tránsito. Un hash criptográfico proporcionado en el recurso debe coincidir con el hash calculado por el explorador para el recurso capturado y el hash enumerado en el CSP. La compatibilidad del navegador se puede examinar en ¿Se puede usar la integridad de subrecursos?.

En el siguiente ejemplo de una aplicación de Blazor Server, se calcula la integridad usando una herramienta de terceros y se especifica en el script de Blazor (blazor.server.js) y CSP. El script de Blazor no cambia dinámicamente en este escenario y tiene un hash SHA estable, por lo que puede codificar de forma dura el valor del atributo integrity.

Precaución

⚠️ Cree el atributo crossorigin en un subrecurso que se carga a través de un origen diferente sin Uso compartido de recursos entre orígenes (CORS). Si el origen de la aplicación es diferente de donde se carga un subrecurso, se requiere un encabezado Access-Control-Allow-Origin que permita que el recurso se comparta con el origen solicitante o, de lo contrario, el atributo crossorigin debe aplicarse a la etiqueta del subrecurso de la aplicación. De lo contrario, el explorador adopta la directiva "fail-open" para el subrecurso, lo que significa que el subrecurso se carga sin comprobar su integridad.

El atributo crossorigin no se agrega a la etiqueta Blazor<script> en el ejemplo siguiente porque el script de Blazor se carga desde el origen de la aplicación.

Para obtener más información, consulte Uso compartido de recursos entre orígenes e integridad de subrecursos (documentación de MDN).

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Security-Policy" content="
        base-uri 'self';
        default-src 'self';
        img-src data: https:;
        object-src 'none';
        script-src 'sha256-FyuamsHhg0nWZUnu/f5qrt2DlL1XKt5AX+cgRhtxtfg=';
        style-src https:;
        connect-src 'self' http: ws: wss:;
        upgrade-insecure-requests;" />
    ...
</head>
<body>
    ...
    <script src="_framework/blazor.server.js" 
        integrity="sha256-FyuamsHhg0nWZUnu/f5qrt2DlL1XKt5AX+cgRhtxtfg="></script>
</body>
</html>

En el ejemplo siguiente de un Blazor Web App (.NET 8 o posterior), se calcula una integridad para el componente de ImportMap (.NET 9 o posterior). El valor de integridad ImportMap se calcula para cada solicitud de aplicación porque el componente ImportMap representa contenido único cada vez que se genera la página para los recursos con huellas digitales.

La aplicación genera el mapa de importación representado desde el componente ImportMap en su origen, por lo que el atributo crossorigin no se incluye en la etiqueta ImportMap. Para obtener más información, consulte la Guía de CSP de MDN: Hashes y la Integridad de subrecursos (documentación de MDN).

@using System.Security.Cryptography
<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Security-Policy" content="
        base-uri 'self';
        default-src 'self';
        img-src data: https:;
        object-src 'none';
        script-src 'self' 'wasm-unsafe-eval' 'unsafe-hashes' '@integrity'
            'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0=';
        style-src https:;
        connect-src 'self' http: ws: wss:;
        upgrade-insecure-requests;" />
    ...
    <ImportMap integrity="@integrity" />
    ...
</head>
...
</html>

@code {
    private string? integrity;

    [CascadingParameter]
    public HttpContext? HttpContext { get; set; }

    protected override void OnInitialized()
    {
        var metadata = HttpContext?.GetEndpoint()?.Metadata
            .GetOrderedMetadata<ImportMapDefinition>();
        var utf8 = new System.Text.UTF8Encoding();
        var metadataBytes = utf8.GetBytes(
            metadata?.FirstOrDefault<ImportMapDefinition>()?.ToString()
                .ReplaceLineEndings("\n") ?? string.Empty);
        integrity = 
            $"sha256-{Convert.ToBase64String(SHA256.HashData(metadataBytes))}";
    }
}

Antes de .NET 6, use .Replace("\r\n", "\n") en lugar de llamar a ReplaceLineEndings en el código anterior.

Nota

Si se deben agregar atributos adicionales sobre el elemento ImportMap representado del componente <script>, puede pasar un diccionario con todos los atributos al componente ImportMap en la propiedad AdditionalAttributes property. El par de nombre y valor del atributo integrity se pasa en el diccionario junto con el resto de los atributos adicionales pasados.

Adopción de un nonce criptográfico

Un nonce criptográfico (número usado una vez) permite a los navegadores confirmar que los recursos capturados no se manipulan en tránsito. Un nonce criptográfico de un solo uso facilitado en el CSP debe coincidir con el valor nonce indicado en el recurso. La compatibilidad del navegador se puede examinar en ¿Se puede usar el valor nonce?.

En el ejemplo siguiente de un Blazor Web App (.NET 8 o posterior), se crea un nonce para el componente de ImportMap (.NET 9 o posterior) con un valor único cada vez que se carga la aplicación.

Para obtener más información, consulte Guía de CSP de MDN: Valores nonces y CSP: script-src: Script insertado no seguro (documentación de MDN).

@using System.Security.Cryptography
<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Security-Policy" content="
        base-uri 'self';
        default-src 'self';
        img-src data: https:;
        object-src 'none';
        script-src 'self' 'wasm-unsafe-eval' 'unsafe-hashes' 'nonce-@nonce' 
            'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0=';
        style-src https:;
        connect-src 'self' http: ws: wss:;
        upgrade-insecure-requests;" />
    ...
    <ImportMap nonce="@nonce" />
    ...
</head>
...
</html>

@code {
    private string? nonce;

    protected override void OnInitialized()
    {
        using (var rng = RandomNumberGenerator.Create())
        {
            var nonceBytes = new byte[32];
            rng.GetBytes(nonceBytes);
            nonce = Convert.ToBase64String(nonceBytes);
        }
    }
}

Nota

Si se deben agregar atributos adicionales sobre el elemento ImportMap representado del componente <script>, puede pasar un diccionario con todos los atributos al componente ImportMap en la propiedad AdditionalAttributes property. El par de nombre y valor del nonce se pasa en el diccionario junto con el resto de los atributos adicionales pasados.

Aplicación de un CSP en entornos que no son de Development

Cuando se aplica un CSP a un contenido Blazor de aplicación <head>, interfiere con las pruebas locales en el entorno de Development. Por ejemplo, Vínculo con exploradores y el script de actualización del explorador no se pueden cargar. En los ejemplos siguientes se muestra cómo aplicar la etiqueta <meta> de CSP en entornos no Development.

Nota

Los ejemplos de esta sección no muestran la etiqueta <meta> completa para los CSP. Las etiquetas completas <meta> se encuentran en las subsecciones de la sección Aplicar la directiva anteriormente en este artículo.

Hay tres enfoques generales disponibles:

  • Aplique el CSP a través del componenteApp, que aplica el CSP a todos los diseños de la aplicación.
  • Si necesita aplicar CSP a diferentes áreas de la aplicación, por ejemplo, un CSP personalizado solo para las páginas de administración, aplique los CSP por diseño mediante la <HeadContent> etiqueta. Para lograr una eficacia completa, todos los archivos de diseño de la aplicación deben adoptar el enfoque.
  • El servicio de hospedaje o el servidor pueden proporcionar un CSP a través de un encabezado Content-Security-Policy agregado a las respuestas salientes de una aplicación. Dado que este enfoque varía según el servicio de hospedaje o el servidor, no se trata en los ejemplos siguientes. Si desea adoptar este enfoque, consulte la documentación de su proveedor de servicios de hospedaje o servidor.

Métodos de Blazor Web App

En el componente App (Components/App.razor), inserte IHostEnvironment:

@inject IHostEnvironment Env

En el contenidoApp del componente <head>, aplique el CSP cuando no esté en el entorno de Development:

@if (!Env.IsDevelopment())
{
    <meta ...>
}

Como alternativa, aplique CSP para cada diseño en la carpeta Components/Layout, como se muestra en el ejemplo siguiente. Asegúrese de que cada diseño especifica un CSP.

@inject IHostEnvironment Env

@if (!Env.IsDevelopment())
{
    <HeadContent>
        <meta ...>
    </HeadContent>
}

Métodos de aplicación de Blazor WebAssembly

En el componente App (App.razor), inserte IWebAssemblyHostEnvironment:

@using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@inject IWebAssemblyHostEnvironment Env

En el contenidoApp del componente <head>, aplique el CSP cuando no esté en el entorno de Development:

@if (!Env.IsDevelopment())
{
    <HeadContent>
        <meta ...>
    </HeadContent>
}

Como alternativa, use el código anterior, pero aplique CSPs en función de cada diseño en la carpeta Layout. Asegúrese de que cada diseño especifica un CSP.

Limitaciones de la etiqueta meta

Una directiva de etiqueta <meta> no admite las siguientes directivas:

Para apoyar las directivas anteriores, use un encabezado denominado Content-Security-Policy. La cadena de directiva es el valor del encabezado.

Comprobación de una directiva y recepción de informes de infracciones

Las comprobaciones ayudan a confirmar que no se han bloqueado scripts de terceros por error al crear una directiva inicial.

Para comprobar una directiva durante un período de tiempo sin aplicar directivas, establezca el atributo <meta> de la etiqueta http-equiv o el nombre de encabezado de una directiva basada en encabezado en Content-Security-Policy-Report-Only. Los informes de errores se envían como documentos JSON a la dirección URL que se especifique. Para obtener más información, vea Documentación web de MDN: Content-Security-Policy-Report-Only.

Para obtener informes de infracciones mientras una directiva está activa, vea los siguientes artículos:

Aunque ya no se recomienda el uso de report-uri, ambas directivas deben usarse hasta que todos los exploradores principales admitan report-to. No use report-uri única y exclusivamente, ya que la compatibilidad con report-uri tiene visos de eliminarse de los exploradores en cualquier momento. Quite la compatibilidad con report-uri de sus directivas cuando report-to sea totalmente compatible. Para realizar un seguimiento del uso de report-to, vea ¿Puedo usar report-to?

Compruebe y actualice la directiva de una aplicación en cada versión.

Solucionar problemas

  • Aparecen errores en la consola de herramientas de desarrollo del explorador. Los exploradores proporcionan información sobre lo siguiente:
    • Elementos que no cumplen la directiva
    • Cómo modificar la directiva para permitir un elemento bloqueado
  • Una directiva es totalmente efectiva únicamente cuando el explorador del cliente admite todas las directivas incluidas. Para obtener una matriz de compatibilidad de exploradores actuales, vea ¿Puedo usar Content-Security-Policy?

Recursos adicionales