Udostępnij za pośrednictwem


Wymuszanie zasad zabezpieczeń zawartości dla ASP.NET Core Blazor

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu .NET 9.

Ostrzeżenie

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z bieżącą wersją, zobacz artykuł w wersji .NET 9.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu dla platformy .NET 9.

W tym artykule wyjaśniono, jak używać Polityki bezpieczeństwa treści (CSP) z aplikacjami ASP.NET Core Blazor, aby pomóc chronić przed niektórymi typami złośliwych ataków, takimi jak Cross-Site Scripting (XSS) i ataków clickjacking. XSS to luka w zabezpieczeniach, w której cyberataka umieszcza co najmniej jeden złośliwy skrypt po stronie klienta w renderowanej zawartości aplikacji. W przypadku ataku clickjacking użytkownik zostaje zmanipulowany, aby wchodzić w interakcje ze stroną internetową wprowadzającą w błąd, która ma osadzoną w sobie Twoją aplikację.

Dostawca CSP pomaga chronić przed tego rodzaju atakami, informując przeglądarkę o prawidłowych źródłach.

  • Źródła załadowanych zawartości, w tym skrypty, arkusze stylów, obrazy i wtyczki.
  • Akcje wykonywane przez stronę, określając dozwolone docelowe adresy URL formularzy.
  • Gdy aplikacja może być osadzona w innej witrynie internetowej za pomocą tagów <frame>, <iframe>, <object>lub <embed>.

Zalecamy zapoznanie się z następującymi zasobami MDN podczas implementowania polityki bezpieczeństwa treści (CSP).

Aby zastosować CSP do aplikacji, deweloper określa kilka dyrektyw zabezpieczeń zawartości CSP w co najmniej jednym Content-Security-Policy nagłówku lub <meta> tagach. Aby uzyskać wskazówki dotyczące stosowania CSP do aplikacji w kodzie C# przy uruchomieniu, odnieś się do ASP.NET Core Blazor startup oraz sekcji dyrektywa frame-ancestors w dalszej części tego artykułu.

Zasady są oceniane przez przeglądarkę podczas ładowania strony. Przeglądarka sprawdza źródła strony i określa, czy spełniają one wymagania dyrektyw zabezpieczeń zawartości. Gdy dyrektywy zasad nie są spełnione dla zasobu, przeglądarka nie ładuje zasobu. Rozważmy na przykład zasady, które nie zezwalają na skrypty innych firm. Gdy strona zawiera <script> tag pochodzący od strony trzeciej w atrybucie src, przeglądarka uniemożliwia ładowanie skryptu.

Program CSP jest obsługiwany w większości nowoczesnych przeglądarek klasycznych i mobilnych, w tym Chrome, Edge, Firefox, Opera i Safari. Zaleca się użycie CSP dla aplikacji Blazor.

Ostrzeżenie

Implementowanie Polityki Bezpieczeństwa Treści (CSP) minimalizuje ryzyko niektórych typów zagrożeń bezpieczeństwa, lecz nie gwarantuje, że aplikacja jest całkowicie bezpieczna przed XSS i atakami typu clickjacking. Agenci użytkowników, zazwyczaj przeglądarki, mogą zezwalać użytkownikom na modyfikowanie lub pomijanie wymuszania zasad za pomocą preferencji użytkownika, zakładek, rozszerzeń przeglądarki, dodatków innych firm do agenta użytkownika i innych takich mechanizmów. Ponadto dostawcy CSP koncentrują się tylko na korygowaniu podzestawu ataków, a nie wszystkich ataków, które mogą naruszyć bezpieczeństwo, takie jak wstrzyknięcie kodu SQL, fałszerzowanie żądań między witrynami (CSRF), błędna konfiguracja zabezpieczeń i ataki typu "odmowa usługi" (DoS).

Dyrektywy polityki

Następujące dyrektywy i źródła są często używane w przypadku aplikacji Blazor. Dodaj dodatkowe dyrektywy i źródła zgodnie z potrzebami. Następujące dyrektywy są używane w Zastosuj zasady sekcji tego artykułu, gdzie podano przykładowe zasady zabezpieczeń dla aplikacji Blazor:

  • base-uri: ogranicza adresy URL tagu <base> strony. Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
  • default-src: wskazuje zapasowe ustawienie dla dyrektyw źródłowych, które nie są jawnie określone przez politykę. Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
  • img-src: wskazuje prawidłowe źródła obrazów.
    • Określ data: , aby zezwolić na ładowanie obrazów z data: adresów URL.
    • Określ https: , aby zezwolić na ładowanie obrazów z punktów końcowych HTTPS.
  • object-src: wskazuje prawidłowe źródła tagów <object>, <embed>i <applet>. Określ none aby uniemożliwić dostęp do wszystkich źródeł URL.
  • script-src: wskazuje prawidłowe źródła skryptów.
    • Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
    • W aplikacji po stronie Blazor klienta:
      • Określ wasm-unsafe-eval , aby umożliwić działanie środowiska uruchomieniowego Mono po stronie Blazor klienta.
      • Określ wszelkie dodatkowe hasze, aby zezwolić na ładowanie wymaganych skryptów niezależnych od frameworków. Na przykład określ unsafe-hashes za pomocą hashu sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0=, aby zezwolić na wbudowany skrypt JavaScript do przełączania nawigacji w składniku NavMenu.
    • W aplikacji po stronie Blazor serwera określ skróty, aby zezwolić na ładowanie wymaganych skryptów.
  • style-src: Określa prawidłowe źródła arkuszy stylów.
    • Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
    • Jeśli aplikacja używa stylów wbudowanych, określ unsafe-inline , aby zezwolić na używanie stylów wbudowanych.
  • connect-src: ogranicza adresy URL, które można załadować przy użyciu interfejsów skryptów. Źródła schematów http:, ws: (protokół WebSocket) i wss: (protokół WebSocket Secure) są określone.
  • upgrade-insecure-requests: wskazuje, że adresy URL zawartości ze źródeł niezabezpieczonych (HTTP) powinny być uzyskiwane bezpiecznie za pośrednictwem protokołu HTTPS.
  • base-uri: ogranicza adresy URL tagu <base> strony. Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
  • default-src: wskazuje zapasowe ustawienie dla dyrektyw źródłowych, które nie są jawnie określone przez politykę. Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
  • img-src: wskazuje prawidłowe źródła obrazów.
    • Określ data: , aby zezwolić na ładowanie obrazów z data: adresów URL.
    • Określ https: , aby zezwolić na ładowanie obrazów z punktów końcowych HTTPS.
  • object-src: wskazuje prawidłowe źródła tagów <object>, <embed>i <applet>. Określ none aby zapobiec wszystkim źródłom URL.
  • script-src: wskazuje prawidłowe źródła skryptów.
    • Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
    • W aplikacji po stronie Blazor klienta:
      • Określ unsafe-eval , aby umożliwić działanie środowiska uruchomieniowego Mono po stronie Blazor klienta.
      • Określ wszelkie dodatkowe hashe, aby umożliwić ładowanie niezbędnych skryptów niezależnych od frameworków.
    • W aplikacji po stronie Blazor serwera określ skróty, aby zezwolić na ładowanie wymaganych skryptów.
  • style-src: Określa prawidłowe źródła arkuszy stylów.
    • Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
    • Jeśli aplikacja używa stylów wbudowanych, określ unsafe-inline , aby zezwolić na używanie stylów wbudowanych.
  • connect-src: ogranicza adresy URL, które można załadować przy użyciu interfejsów skryptów. Źródła schematów http:, ws: (protokół WebSocket) i wss: (protokół WebSocket Secure) są określone.
  • upgrade-insecure-requests: wskazuje, że adresy URL zawartości ze źródeł niezabezpieczonych (HTTP) powinny być bezpiecznie uzyskiwane za pośrednictwem protokołu HTTPS.
  • base-uri: ogranicza adresy URL tagu <base> strony. Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
  • default-src: wskazuje zapasowe ustawienie dla dyrektyw źródłowych, które nie są jawnie określone przez politykę. Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
  • img-src: wskazuje prawidłowe źródła obrazów.
    • Określ data: , aby zezwolić na ładowanie obrazów z data: adresów URL.
    • Określ https: , aby zezwolić na ładowanie obrazów z punktów końcowych HTTPS.
  • object-src: wskazuje prawidłowe źródła tagów <object>, <embed>i <applet>. Aby zablokować wszystkie źródła adresów URL, określ none.
  • script-src: wskazuje prawidłowe źródła skryptów.
    • https://stackpath.bootstrapcdn.com/ Określ źródło hosta dla skryptów bootstrap.
    • Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
    • W aplikacji po stronie Blazor klienta:
      • Określ unsafe-eval , aby umożliwić działanie środowiska uruchomieniowego Mono po stronie Blazor klienta.
      • Podaj dodatkowe hashe, aby zezwolić na ładowanie wymaganych skryptów nie związane ze strukturą.
    • W aplikacji po stronie Blazor serwera określ skróty, aby zezwolić na ładowanie wymaganych skryptów.
  • style-src: Określa prawidłowe źródła arkuszy stylów.
    • https://stackpath.bootstrapcdn.com/ Określ źródło hosta dla arkuszy stylów Bootstrap.
    • Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
    • Określ unsafe-inline , aby zezwolić na używanie stylów wbudowanych.
  • connect-src: ogranicza adresy URL, które można załadować przy użyciu interfejsów skryptów. Schematy źródeł http:, ws: (Protokół WebSocket) i wss: (Protokół WebSocket Secure) są określone.
  • upgrade-insecure-requests: wskazuje, że adresy URL zawartości ze źródeł niezabezpieczonych (HTTP) powinny być bezpiecznie uzyskiwane za pośrednictwem protokołu HTTPS.
  • base-uri: ogranicza adresy URL tagu <base> strony. Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
  • default-src: wskazuje zapasowe ustawienie dla dyrektyw źródłowych, które nie są jawnie określone przez politykę. Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
  • img-src: wskazuje prawidłowe źródła obrazów.
    • Określ data: , aby zezwolić na ładowanie obrazów z data: adresów URL.
    • Określ https: , aby zezwolić na ładowanie obrazów z punktów końcowych HTTPS.
  • object-src: wskazuje prawidłowe źródła tagów <object>, <embed>i <applet>. Określ none, aby uniemożliwić wszystkie źródła adresów URL.
  • script-src: wskazuje prawidłowe źródła skryptów.
    • https://stackpath.bootstrapcdn.com/ Określ źródło hosta dla skryptów bootstrap.
    • Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
    • W aplikacji po stronie Blazor klienta:
      • Określ hasze, aby zezwolić na ładowanie wymaganych skryptów.
      • Określ unsafe-eval, aby użyć eval() oraz metod do tworzenia kodu na podstawie ciągów.
    • W aplikacji po stronie Blazor serwera określ skróty, aby zezwolić na ładowanie wymaganych skryptów.
  • style-src: Określa prawidłowe źródła arkuszy stylów.
    • https://stackpath.bootstrapcdn.com/ Określ źródło hosta dla arkuszy stylów Bootstrap.
    • Określ self , aby wskazać, że źródło aplikacji, w tym schemat i numer portu, jest prawidłowym źródłem.
    • Określ unsafe-inline , aby zezwolić na używanie stylów wbudowanych. Deklaracja śródliniowa jest wymagana dla interfejsu użytkownika w celu ponownego połączenia klienta i serwera po początkowym żądaniu. W przyszłej wersji style wbudowane mogą zostać usunięte, aby unsafe-inline nie było już wymagane.
  • connect-src: ogranicza adresy URL, które można załadować przy użyciu interfejsów skryptów. Źródła schematów http:, ws: (protokół WebSocket) i wss: (protokół WebSocket Secure) są określone.
  • upgrade-insecure-requests: wskazuje, że adresy URL zawartości ze źródeł niezabezpieczonych (HTTP) powinny być bezpiecznie uzyskiwane za pośrednictwem protokołu HTTPS.

Powyższe dyrektywy są obsługiwane przez wszystkie przeglądarki z wyjątkiem programu Microsoft Internet Explorer.

Aby uzyskać skróty SHA dla dodatkowych skryptów wbudowanych:

  • Zastosuj zasady CSP pokazane w sekcji Zastosuj zasady.
  • Uzyskaj dostęp do konsoli narzędzi deweloperskich przeglądarki podczas lokalnego uruchamiania aplikacji. Przeglądarka oblicza i wyświetla skróty dla zablokowanych skryptów, gdy jest obecny nagłówek CSP lub tag meta.
  • Skopiuj hasze dostarczone przez przeglądarkę do script-src źródeł. Użyj pojedynczych cudzysłowów wokół każdego skrótu.

Aby zapoznać się z macierzą obsługi Content Security Policy Level 2 w przeglądarkach, zobacz Can I use: Content Security Policy Level 2.

Stosowanie zasad

Możesz zastosować politykę CSP przez:

  • Nagłówek odpowiedzi wystawiony przez hosta (na przykład usługi IIS) lub wystawiony przez aplikację (zobacz nagłówki Control w kodzie języka C# podczas uruchamiania).
  • Tag <meta>. w tym artykule przedstawiono tylko podejście do tagów <meta>.

Aby użyć tagu <meta> do zastosowania polityki:

  • Ustaw wartość atrybutu http-equiv na Content-Security-Policy.
  • Umieść dyrektywy w wartości atrybutu content . Rozdziel dyrektywy średnikiem (;). Średnik kończący ostatnią dyrektywę ciągu zasad nie jest wymagany zgodnie ze specyfikacją Content Security Policy Level 3.
  • Umieść tag <meta> w zawartości <head> tuż wewnątrz tagu otwierającego <head>. Polityka jest oceniana i egzekwowana po przeanalizowaniu znaczników CSP, dlatego powinna znajdować się na górze znaczników <head>, aby upewnić się, że jest egzekwowana na wszystkich tagach <script> i <link>.

W poniższych sekcjach przedstawiono przykładowe zasady. Te przykłady są wersjonowane w tym artykule dla każdej wersji programu Blazor. Aby użyć wersji odpowiedniej dla wydania, wybierz wersję dokumentu z listy rozwijanej Wersja na tej stronie.

Dyrektywa frame-ancestors

Dyrektywa frame-ancestors określa prawidłowych rodziców, którzy mogą osadzić stronę z tagami <frame>, <iframe>, <object>lub <embed>. Nie można zastosować dyrektywy frame-ancestors za pomocą polityki CSP opartej na tagach <meta>. Dyrektywa musi być stosowana za pomocą nagłówka odpowiedzi. Nagłówek odpowiedzi CSP można dodać przez hosta serwera, a kod aplikacji w języku C# może dodawać lub aktualizować CSP za pomocą dyrektywy frame-ancestors.

Blazor Web Apps (.NET 8 lub nowszy) automatycznie dołącza nagłówek odpowiedzi, ustawiając wartość na 'self':

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

Aby zmienić wartość domyślną na bardziej restrykcyjną 'none' i uniemożliwić osadzanie aplikacji wszystkim użytkownikom nadrzędnym, ustaw opcję ContentSecurityFrameAncestorsPolicy w wywołaniu dla AddInteractiveServerRenderMode w pliku Program. Następujące działanie ma zastosowanie tylko wtedy, gdy jest włączona kompresja protokołu WebSocket (<xref:Microsoft.AspNetCore.Components.Server.ServerComponentsEndpointOptions.ConfigureWebSocketAcceptContext%2A> jest ustawiona, co jest ustawieniem domyślnym dla aplikacji Blazor).

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

W aplikacjach Blazor Server domyślna dyrektywa frame-ancestors nie jest dodawana do kolekcji nagłówków odpowiedzi. Nagłówek CSP można dodać ręcznie za pomocą oprogramowania pośredniczącego w potoku przetwarzania żądań:

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

Ostrzeżenie

Unikaj ustawiania wartości dyrektywy frame-ancestors na 'null', gdy kompresja protokołu WebSocket jest włączona (domyślnie kompresja jest włączona), ponieważ sprawia to, że aplikacja jest podatna na wstrzyknięcie złośliwego skryptu i ataki typu clickjacking.

Aby uzyskać więcej informacji, zobacz CSP: frame-ancestors (dokumentacja MDN).

Aplikacje po stronie Blazor serwera

Poniższy przykład stanowi punkt wyjścia do dalszego opracowywania. Na górze zawartości <head>zastosuj dyrektywy opisane w sekcji dyrektyw polityki oraz inne dyrektywy, które są wymagane przez specyfikację aplikacji.

W przypadku aplikacji Blazor Web Applub 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 Appzawiera wbudowany program obsługi zdarzeń języka JavaScript onclick w składniku NavMenu, który wymaga jednej z następujących zmian:

  • Dodaj skrót do dyrektywy script-src za pomocą słowa kluczowego unsafe-hashes:

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

    Aby uzyskać więcej informacji, zobacz CSP: script-src: Niebezpieczny skrypt wbudowany (dokumentacja MDN).

  • Przenieś wbudowany program obsługi zdarzeń języka JavaScript do pliku lub modułu JavaScript, który jest dozwolony do załadowania zgodnie z zasadami.

Blazor Web Appma również komponent ImportMap w treści <head>, który renderuje wbudowany tag mapy importu <script>. Aby zmodyfikować zasady zezwalające na ładowanie mapy importu, zobacz sekcję Rozwiązywanie naruszeń zasad CSP za pomocą integralności podźródłowej (SRI) lub kryptograficznego nonce.

W przypadku aplikacji 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">

W przypadku aplikacji 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">

W przypadku aplikacji 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">

Uwaga

Poprzedni skrót SHA256 służy do celów demonstracyjnych. Może być konieczne obliczenie nowego skrótu dla CSP.

Dodaj dodatkowe script-src i style-src hasze zgodnie z wymaganiami aplikacji. Podczas programowania użyj narzędzia online lub narzędzi deweloperskich przeglądarki, aby obliczyć skróty. Na przykład następujący błąd konsoli narzędzi przeglądarki zgłasza skrót dla wymaganego skryptu, który nie jest objęty zasadami:

Odmówił wykonania skryptu wbudowanego, ponieważ narusza on następującą dyrektywę Zasad zabezpieczeń zawartości: " ... ". Słowo kluczowe "unsafe-inline", skrót ('sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=') lub nonce ('nonce-...') jest wymagane do umożliwienia wykonywania kodu inline.

Określony skrypt skojarzony z błędem jest wyświetlany w konsoli obok błędu.

Aby uzyskać wskazówki dotyczące stosowania CSP do aplikacji w kodzie C# podczas uruchamiania, zobacz ASP.NET Core Blazor startup.

Aplikacje po stronie Blazor klienta

Poniższy przykład stanowi punkt wyjścia do dalszego opracowywania. <head> W zawartości zastosuj dyrektywy opisane w sekcji Dyrektywy zasad:

<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">

Uwaga

Skrót sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA= reprezentuje skrypt wbudowany używany w aplikacjach po stronie klienta. Może to zostać usunięte w przyszłości.

<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">

Dodaj dodatkowe script-src i style-src hasze zgodnie z potrzebami aplikacji. Podczas programowania użyj narzędzia online lub narzędzi deweloperskich przeglądarki, aby obliczyć skróty. Na przykład następujący błąd konsoli narzędzi przeglądarki zgłasza skrót dla wymaganego skryptu, który nie jest objęty zasadami:

Odmówił wykonania skryptu wbudowanego, ponieważ narusza on następującą dyrektywę Zasad zabezpieczeń zawartości: " ... ". Słowo kluczowe "unsafe-inline", skrót ('sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=') lub nonce ('nonce-...') jest wymagane do włączenia wykonywania inline.

Określony skrypt skojarzony z błędem jest wyświetlany w konsoli obok błędu.

Rozwiązywanie naruszeń zasad CSP z użyciem Subresource Integrity (SRI) lub kryptograficznego nonce’a.

Dwa podejścia do rozwiązywania naruszeń CSP, które zostały opisane w dwóch następnych sekcjach, to:

Wprowadź integralność podźródła (SRI)

Integralność podźródła (SRI) umożliwia przeglądarkom potwierdzenie, że pobrane zasoby nie są modyfikowane podczas przesyłania. Skrót kryptograficzny podany w zasobie musi być zgodny z wartością skrótu obliczoną przez przeglądarkę dla pobranego zasobu i skrótem wymienionym w programie CSP. Zgodność przeglądarki można ocenić pod adresem Czy mogę użyć? Integralność podźródła.

W poniższym przykładzie dla aplikacji Blazor Server integralność jest obliczana za pomocą narzędzia innej firmy i określana dla skryptu Blazor (blazor.server.js) oraz polityki CSP. Skrypt Blazor nie zmienia się dynamicznie w tym scenariuszu i ma stabilny skrót SHA, dzięki czemu można zakodować wartość atrybutu integrity.

Ostrożność

️ ⚠Ustaw atrybut crossorigin w podźródle załadowanym z innego źródła bez współużytkowania zasobów między źródłami (CORS). Jeśli źródło aplikacji różni się od miejsca ładowania podźródła, wymagany jest nagłówek Access-Control-Allow-Origin, który umożliwia udostępnianie zasobu żądającemu źródła lub atrybutu crossorigin należy zastosować do tagu podźródła w aplikacji. W przeciwnym razie przeglądarka przyjmuje zasady "fail-open" dla podźródła, co oznacza, że podźródło jest ładowane bez sprawdzania jego integralności.

Atrybut crossorigin nie jest dodawany do tagu Blazor<script> w poniższym przykładzie, ponieważ skrypt Blazor jest ładowany ze źródła aplikacji.

Aby uzyskać więcej informacji, zobacz udostępnianie zasobów między źródłami i integralność podzasobów (dokumentacja 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>

W poniższym przykładzie dla Blazor Web App (.NET 8 lub nowszej) integralność jest obliczana dla składnika ImportMap (.NET 9 lub nowszego). Wartość integralności ImportMap jest obliczana dla każdego żądania aplikacji, ponieważ składnik ImportMap renderuje unikatową zawartość za każdym razem, gdy strona jest generowana dla zasobów odcisków palców.

Renderowana mapa importu ze składnika ImportMap jest generowana przez aplikację u jej źródła, dlatego atrybut crossorigin nie jest uwzględniony w tagu ImportMap. Aby uzyskać więcej informacji, zobacz przewodnik MDN CSP: Hashy oraz Integralność podzasobów (dokumentacja 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))}";
    }
}

Przed .NET 6 użyj .Replace("\r\n", "\n") zamiast wywoływać ReplaceLineEndings w poprzednim kodzie.

Uwaga

Jeśli do renderowanego elementu <script> komponentu ImportMap należy dodać dodatkowe atrybuty, można przekazać słownik wszystkich atrybutów do komponentu ImportMap do właściwości AdditionalAttributes. Para integrity nazwa-wartość atrybutu jest przekazywana w słowniku z pozostałymi przekazanymi atrybutami.

Przyjęcie kryptograficznego nonce

Kryptograficzny nonce (numerużywany raz) umożliwia przeglądarkom potwierdzenie, że pobrane zasoby nie są modyfikowane podczas przesyłania. Kryptograficzny nonce używany jednorazowo, podany w CSP, musi być zgodny z wartością wskazaną w zasobie. Zgodność przeglądarki można ocenić pod adresem Czy mogę użyć? Nonce.

W poniższym przykładzie dla Blazor Web App (.NET 8 lub nowszej) jest tworzony nonce dla składnika ImportMap (.NET 9 lub nowszego) z unikatową wartością za każdym razem, gdy aplikacja jest ładowana.

Aby uzyskać więcej informacji, zobacz przewodnik CSP MDN: Nonces i CSP: script-src: Niebezpieczny skrypt wbudowany (dokumentacja 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);
        }
    }
}

Uwaga

Jeśli na renderowanym elemencie <script> składnika ImportMap należy umieścić dodatkowe atrybuty, można przekazać słownik wszystkich atrybutów do składnika ImportMap w jego właściwości AdditionalAttributes. Para klucz-wartość nonce jest przekazywana w słowniku z pozostałymi dodatkowymi przekazanymi atrybutami.

Stosować CSP w środowiskach innych niż Development

Gdy polityka CSP jest zastosowana do zawartości aplikacji <head>, utrudnia lokalne testowanie w środowisku Development. Na przykład Browser Link i skrypt odświeżania przeglądarki nie ładują się. W poniższych przykładach pokazano, jak zastosować tag CSP <meta> w środowiskach innych niż Development.

Uwaga

Przykłady w tej sekcji nie pokazują pełnego <meta> tagu dla CSP. Pełne <meta> tagi znajdują się w podsekcjach sekcji Zastosuj zasady we wcześniejszej części tego artykułu.

Dostępne są trzy ogólne podejścia:

  • Zastosuj CSP za pośrednictwem App składnika, który stosowany jest do wszystkich układów aplikacji.
  • Jeśli musisz zastosować zasady CSP do różnych obszarów aplikacji, np. niestandardowe zasady CSP tylko dla stron administracyjnych, zastosuj je dla poszczególnych układów przy użyciu tagu <HeadContent>. Aby zapewnić pełną skuteczność, każdy plik układu aplikacji musi przyjąć podejście.
  • Usługa hostingu lub serwer może dostarczyć dostawcę usług kryptograficznych za pośrednictwem Content-Security-Policy nagłówka dodanego odpowiedzi wychodzących aplikacji. Ponieważ takie podejście różni się w zależności od usługi hostingu lub serwera, nie jest ono rozwiązane w poniższych przykładach. Jeśli chcesz zastosować to podejście, zapoznaj się z dokumentacją dostawcy usług hostingu lub serwera.

Blazor Web App Podejścia

W składniku App (Components/App.razor) wstrzyknąć IHostEnvironment:

@inject IHostEnvironment Env

W zawartości składnika App, zastosuj CSP w <head>, gdy nie znajduje się w środowisku Development.

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

Alternatywnie zastosuj zasady CSP dla poszczególnych układów w folderze Components/Layout, jak pokazano w poniższym przykładzie. Upewnij się, że każde rozmieszczenie określa CSP.

@inject IHostEnvironment Env

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

Blazor WebAssembly podejścia aplikacji

Wstrzykuj w składnik ().

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

W treści składnika <head> zastosuj CSP, gdy nie jesteś w środowisku Development.

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

Alternatywnie użyj poprzedniego kodu, ale zastosuj CSP-y dla każdego układu w folderze Layout. Upewnij się, że każdy szablon określa politykę CSP.

Ograniczenia tagów metadanych

Zasady tagu <meta> nie obsługują następujących dyrektyw:

Aby wspierać powyższe dyrektywy, użyj nagłówka o nazwie Content-Security-Policy. Ciąg dyrektywy jest wartością nagłówka.

Testowanie zasad i odbieranie raportów o naruszeniach

Testowanie pomaga potwierdzić, że skrypty innych firm nie są przypadkowo blokowane podczas tworzenia zasad początkowych.

Aby przetestować zasady w danym okresie bez stosowania dyrektyw polityki, ustaw atrybut tagu <meta> lub nazwę nagłówka polityki opartej na nagłówku na wartość Content-Security-Policy-Report-Only. Raporty o błędach są wysyłane jako dokumenty JSON do określonego adresu URL. Aby uzyskać więcej informacji, zobacz Dokumentacja internetowa MDN: Content-Security-Policy-Report-Only.

Aby uzyskać informacje na temat raportowania naruszeń, gdy zasady są aktywne, zobacz następujące artykuły:

Chociaż report-uri nie jest już zalecane do użycia, obie dyrektywy powinny być używane aż report-to będzie obsługiwane przez wszystkie główne przeglądarki. Nie używaj wyłącznie report-uri, ponieważ obsługa report-uri może być w każdej chwili wycofana z przeglądarek. Usuń obsługę report-uri w swoich zasadach, gdy report-to jest w pełni obsługiwane. Aby śledzić przyjęcie report-to, zobacz Czy mogę używać: report-to.

Testowanie i aktualizowanie zasad aplikacji w każdej wersji.

Rozwiązywanie problemów

  • Błędy są wyświetlane w konsoli narzędzi deweloperskich przeglądarki. Przeglądarki zawierają informacje o:
    • Elementy, które nie są zgodne z zasadami.
    • Jak zmodyfikować zasady, aby zezwolić na zablokowany element.
  • Zasady są całkowicie skuteczne tylko wtedy, gdy przeglądarka klienta obsługuje wszystkie dołączone dyrektywy. Aby zapoznać się z bieżącą macierzą obsługi przeglądarki, zobacz Czy mogę użyć: Content-Security-Policy.

Dodatkowe zasoby