Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn moreThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
This isn't the latest version of this article. For the current release, see the .NET 9 version of this article.
Warning
This version of ASP.NET Core is no longer supported. For more information, see the .NET and .NET Core Support Policy. For the current release, see the .NET 9 version of this article.
Important
This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
For the current release, see the .NET 9 version of this article.
This article explains how to use a Content Security Policy (CSP) with ASP.NET Core Blazor apps to help protect against Cross-Site Scripting (XSS) attacks.
Cross-Site Scripting (XSS) is a security vulnerability where a cyberattacker places one or more malicious client-side scripts into an app's rendered content. A CSP helps protect against XSS attacks by informing the browser of valid:
To apply a CSP to an app, the developer specifies several CSP content security directives in one or more Content-Security-Policy
headers or <meta>
tags. For guidance on applying a CSP to an app in C# code at startup, see ASP.NET Core Blazor startup.
Policies are evaluated by the browser while a page is loading. The browser inspects the page's sources and determines if they meet the requirements of the content security directives. When policy directives aren't met for a resource, the browser doesn't load the resource. For example, consider a policy that doesn't allow third-party scripts. When a page contains a <script>
tag with a third-party origin in the src
attribute, the browser prevents the script from loading.
CSP is supported in most modern desktop and mobile browsers, including Chrome, Edge, Firefox, Opera, and Safari. CSP is recommended for Blazor apps.
Minimally, specify the following directives and sources for Blazor apps. Add additional directives and sources as needed. The following directives are used in the Apply the policy section of this article, where example security policies for Blazor apps are provided:
base-uri
: Restricts the URLs for a page's <base>
tag. Specify self
to indicate that the app's origin, including the scheme and port number, is a valid source.default-src
: Indicates a fallback for source directives that aren't explicitly specified by the policy. Specify self
to indicate that the app's origin, including the scheme and port number, is a valid source.img-src
: Indicates valid sources for images.
data:
to permit loading images from data:
URLs.https:
to permit loading images from HTTPS endpoints.object-src
: Indicates valid sources for the <object>
, <embed>
, and <applet>
tags. Specify none
to prevent all URL sources.script-src
: Indicates valid sources for scripts.
self
to indicate that the app's origin, including the scheme and port number, is a valid source.wasm-unsafe-eval
to permit the client-side Blazor Mono runtime to function.style-src
: Indicates valid sources for stylesheets.
self
to indicate that the app's origin, including the scheme and port number, is a valid source.unsafe-inline
to allow the use of your inline styles.base-uri
: Restricts the URLs for a page's <base>
tag. Specify self
to indicate that the app's origin, including the scheme and port number, is a valid source.default-src
: Indicates a fallback for source directives that aren't explicitly specified by the policy. Specify self
to indicate that the app's origin, including the scheme and port number, is a valid source.img-src
: Indicates valid sources for images.
data:
to permit loading images from data:
URLs.https:
to permit loading images from HTTPS endpoints.object-src
: Indicates valid sources for the <object>
, <embed>
, and <applet>
tags. Specify none
to prevent all URL sources.script-src
: Indicates valid sources for scripts.
self
to indicate that the app's origin, including the scheme and port number, is a valid source.unsafe-eval
to permit the client-side Blazor Mono runtime to function.style-src
: Indicates valid sources for stylesheets.
self
to indicate that the app's origin, including the scheme and port number, is a valid source.unsafe-inline
to allow the use of your inline styles.upgrade-insecure-requests
: Indicates that content URLs from insecure (HTTP) sources should be acquired securely over HTTPS.base-uri
: Restricts the URLs for a page's <base>
tag. Specify self
to indicate that the app's origin, including the scheme and port number, is a valid source.default-src
: Indicates a fallback for source directives that aren't explicitly specified by the policy. Specify self
to indicate that the app's origin, including the scheme and port number, is a valid source.img-src
: Indicates valid sources for images.
data:
to permit loading images from data:
URLs.https:
to permit loading images from HTTPS endpoints.object-src
: Indicates valid sources for the <object>
, <embed>
, and <applet>
tags. Specify none
to prevent all URL sources.script-src
: Indicates valid sources for scripts.
https://stackpath.bootstrapcdn.com/
host source for Bootstrap scripts.self
to indicate that the app's origin, including the scheme and port number, is a valid source.unsafe-eval
to permit the client-side Blazor Mono runtime to function.style-src
: Indicates valid sources for stylesheets.
https://stackpath.bootstrapcdn.com/
host source for Bootstrap stylesheets.self
to indicate that the app's origin, including the scheme and port number, is a valid source.unsafe-inline
to allow the use of inline styles.upgrade-insecure-requests
: Indicates that content URLs from insecure (HTTP) sources should be acquired securely over HTTPS.base-uri
: Restricts the URLs for a page's <base>
tag. Specify self
to indicate that the app's origin, including the scheme and port number, is a valid source.default-src
: Indicates a fallback for source directives that aren't explicitly specified by the policy. Specify self
to indicate that the app's origin, including the scheme and port number, is a valid source.img-src
: Indicates valid sources for images.
data:
to permit loading images from data:
URLs.https:
to permit loading images from HTTPS endpoints.object-src
: Indicates valid sources for the <object>
, <embed>
, and <applet>
tags. Specify none
to prevent all URL sources.script-src
: Indicates valid sources for scripts.
https://stackpath.bootstrapcdn.com/
host source for Bootstrap scripts.self
to indicate that the app's origin, including the scheme and port number, is a valid source.unsafe-eval
to use eval()
and methods for creating code from strings.style-src
: Indicates valid sources for stylesheets.
https://stackpath.bootstrapcdn.com/
host source for Bootstrap stylesheets.self
to indicate that the app's origin, including the scheme and port number, is a valid source.unsafe-inline
to allow the use of inline styles. The inline declaration is required for the UI for reconnecting the client and server after the initial request. In a future release, inline styling might be removed so that unsafe-inline
is no longer required.upgrade-insecure-requests
: Indicates that content URLs from insecure (HTTP) sources should be acquired securely over HTTPS.The preceding directives are supported by all browsers except Microsoft Internet Explorer.
To obtain SHA hashes for additional inline scripts:
meta
tag is present.script-src
sources. Use single quotes around each hash.For a Content Security Policy Level 2 browser support matrix, see Can I use: Content Security Policy Level 2.
Use a <meta>
tag to apply the policy:
http-equiv
attribute to Content-Security-Policy
.content
attribute value. Separate directives with a semicolon (;
).meta
tag in the <head>
content.The following sections show example policies. These examples are versioned with this article for each release of Blazor. To use a version appropriate for your release, select the document version with the Version dropdown selector on this webpage.
In the <head>
content, apply the directives described in the Policy directives section:
<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';
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 https://stackpath.bootstrapcdn.com/
'self';
style-src https://stackpath.bootstrapcdn.com/
'self'
'unsafe-inline';
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 https://stackpath.bootstrapcdn.com/
'self'
'sha256-34WLX60Tw3aG6hylk0plKbZZFXCuepeQ6Hu7OqRf8PI=';
style-src https://stackpath.bootstrapcdn.com/
'self'
'unsafe-inline';
upgrade-insecure-requests;">
Add additional script-src
and style-src
hashes as required by the app. During development, use an online tool or browser developer tools to have the hashes calculated for you. For example, the following browser tools console error reports the hash for a required script not covered by the policy:
Refused to execute inline script because it violates the following Content Security Policy directive: " ... ". Either the 'unsafe-inline' keyword, a hash ('sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA='), or a nonce ('nonce-...') is required to enable inline execution.
The particular script associated with the error is displayed in the console next to the error.
For guidance on applying a CSP to an app in C# code at startup, see ASP.NET Core Blazor startup.
In the <head>
content, apply the directives described in the Policy directives section:
<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';
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';
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'
'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA='
'unsafe-eval';
style-src 'self';
upgrade-insecure-requests;">
Note
The sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=
hash represents the inline script that's used for client-side Blazor apps. This may be removed in the future.
<meta http-equiv="Content-Security-Policy"
content="base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src https://stackpath.bootstrapcdn.com/
'self'
'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA='
'unsafe-eval';
style-src https://stackpath.bootstrapcdn.com/
'self'
'unsafe-inline';
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 https://stackpath.bootstrapcdn.com/
'self'
'sha256-v8ZC9OgMhcnEQ/Me77/R9TlJfzOBqrMTW8e1KuqLaqc='
'sha256-If//FtbPc03afjLezvWHnC3Nbu4fDM04IIzkPaf3pH0='
'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA='
'unsafe-eval';
style-src https://stackpath.bootstrapcdn.com/
'self'
'unsafe-inline';
upgrade-insecure-requests;">
Add additional script-src
and style-src
hashes as required by the app. During development, use an online tool or browser developer tools to have the hashes calculated for you. For example, the following browser tools console error reports the hash for a required script not covered by the policy:
Refused to execute inline script because it violates the following Content Security Policy directive: " ... ". Either the 'unsafe-inline' keyword, a hash ('sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA='), or a nonce ('nonce-...') is required to enable inline execution.
The particular script associated with the error is displayed in the console next to the error.
When a CSP is applied to a Blazor app's <head>
content, it interferes with local testing in the Development
environment. For example, Browser Link and the browser refresh script fail to load. The following examples demonstrate how to apply the CSP's <meta>
tag in non-Development
environments.
Note
The examples in this section don't show the full <meta>
tag for the CSPs. The complete <meta>
tags are found in the subsections of the Apply the policy section earlier in this article.
Three general approaches are available:
App
component, which applies the CSP to all layouts of the app.<HeadContent>
tag. For complete effectiveness, every app layout file must adopt the approach.Content-Security-Policy
header added an app's outgoing responses. Because this approach varies by hosting service or server, it isn't addressed in the following examples. If you wish to adopt this approach, consult the documentation for your hosting service provider or server.In the App
component (Components/App.razor
), inject IHostEnvironment:
@inject IHostEnvironment Env
In the App
component's <head>
content, apply the CSP when not in the Development
environment:
@if (!Env.IsDevelopment())
{
<meta ...>
}
Alternatively, apply CSPs on a per-layout basis in the Components/Layout
folder, as the following example demonstrates. Make sure that every layout specifies a CSP.
@inject IHostEnvironment Env
@if (!Env.IsDevelopment())
{
<HeadContent>
<meta ...>
</HeadContent>
}
In the App
component (App.razor
), inject IWebAssemblyHostEnvironment:
@using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@inject IWebAssemblyHostEnvironment Env
In the App
component's <head>
content, apply the CSP when not in the Development
environment:
@if (!Env.IsDevelopment())
{
<HeadContent>
<meta ...>
</HeadContent>
}
Alternatively, use the preceding code but apply CSPs on a per-layout basis in the Layout
folder. Make sure that every layout specifies a CSP.
A <meta>
tag policy doesn't support the following directives:
To support the preceding directives, use a header named Content-Security-Policy
. The directive string is the header's value.
Testing helps confirm that third-party scripts aren't inadvertently blocked when building an initial policy.
To test a policy over a period of time without enforcing the policy directives, set the <meta>
tag's http-equiv
attribute or header name of a header-based policy to Content-Security-Policy-Report-Only
. Failure reports are sent as JSON documents to a specified URL. For more information, see MDN web docs: Content-Security-Policy-Report-Only.
For reporting on violations while a policy is active, see the following articles:
Although report-uri
is no longer recommended for use, both directives should be used until report-to
is supported by all of the major browsers. Don't exclusively use report-uri
because support for report-uri
is subject to being dropped at any time from browsers. Remove support for report-uri
in your policies when report-to
is fully supported. To track adoption of report-to
, see Can I use: report-to.
Test and update an app's policy every release.
ASP.NET Core feedback
ASP.NET Core is an open source project. Select a link to provide feedback:
Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn moreTraining
Module
Guide to Secure .NET Development with OWASP Top 10 - Training
Evaluate security risks that come with insecure application development patterns and practices