Skip to content

Commit 5aedaa1

Browse files
authored
Merge pull request #23 from damienbod/security-headers-update
Security headers update
2 parents 94d8815 + 09e4f92 commit 5aedaa1

38 files changed

+138
-188
lines changed

.github/workflows/dotnet.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ jobs:
1212
runs-on: ubuntu-latest
1313

1414
steps:
15-
- uses: actions/checkout@v2
15+
- uses: actions/checkout@v4
1616
- name: Setup .NET
17-
uses: actions/setup-dotnet@v1
17+
uses: actions/setup-dotnet@v4
1818
with:
1919
dotnet-version: '8.0'
2020
include-prerelease: True

AspNetCore.sln

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorHosted.Shared", "Blaz
1313
EndProject
1414
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_solutionItems", "_solutionItems", "{7F337AB1-98B9-4380-BFFF-3F6422EFDED0}"
1515
ProjectSection(SolutionItems) = preProject
16-
.github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
1716
.github\workflows\dotnet.yml = .github\workflows\dotnet.yml
1817
README.md = README.md
1918
EndProjectSection

AspNetCoreRazor/AspNetCoreRazor.csproj

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.1" NoWarn="NU1605" />
12-
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.1" NoWarn="NU1605" />
13-
<PackageReference Include="Microsoft.Identity.Web" Version="2.16.1" />
14-
<PackageReference Include="Microsoft.Identity.Web.UI" Version="2.16.1" />
15-
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders" Version="0.21.0" />
16-
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders.TagHelpers" Version="0.21.0" />
11+
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" NoWarn="NU1605" />
12+
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.8" NoWarn="NU1605" />
13+
<PackageReference Include="Microsoft.Identity.Web" Version="3.2.0" />
14+
<PackageReference Include="Microsoft.Identity.Web.UI" Version="3.2.0" />
15+
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders" Version="1.0.0-preview.1" />
16+
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders.TagHelpers" Version="1.0.0-preview.1" />
1717
</ItemGroup>
1818

1919
</Project>

AspNetCoreRazor/Pages/Index.cshtml.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using Microsoft.AspNetCore.Mvc;
2-
using Microsoft.AspNetCore.Mvc.RazorPages;
1+
using Microsoft.AspNetCore.Mvc.RazorPages;
32

43
namespace AspNetCoreRazor.Pages
54
{

AspNetCoreRazor/Pages/Privacy.cshtml.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using Microsoft.AspNetCore.Mvc;
2-
using Microsoft.AspNetCore.Mvc.RazorPages;
1+
using Microsoft.AspNetCore.Mvc.RazorPages;
32

43
namespace AspNetCoreRazor.Pages
54
{

AspNetCoreRazor/Pages/Shared/_Layout.cshtml

+6-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
<meta charset="utf-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>@ViewData["Title"] - AspNetCoreRazor</title>
7-
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
8-
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
9-
<link rel="stylesheet" href="~/AspNetCoreRazor.styles.css" asp-append-version="true" />
7+
<link asp-add-nonce rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
8+
<link asp-add-nonce rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
9+
<link asp-add-nonce rel="stylesheet" href="~/AspNetCoreRazor.styles.css" asp-append-version="true" />
1010
</head>
1111
<body>
1212
<header>
@@ -43,10 +43,9 @@
4343
</div>
4444
</footer>
4545

46-
@{var nonce = Context.GetNonce();}
47-
<script src="~/lib/jquery/dist/jquery.min.js" nonce="@nonce"></script>
48-
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js" nonce="@nonce"></script>
49-
<script src="~/js/site.js" asp-append-version="true" nonce="@nonce"></script>
46+
<script src="~/lib/jquery/dist/jquery.min.js" asp-add-nonce></script>
47+
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js" asp-add-nonce></script>
48+
<script src="~/js/site.js" asp-append-version="true" asp-add-nonce></script>
5049

5150
@await RenderSectionAsync("Scripts", required: false)
5251
</body>
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
@{var nonce = this.Context.GetNonce();}
2-
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js" nonce="@nonce"></script>
3-
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" nonce="@nonce"></script>
1+
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js" asp-add-nonce></script>
2+
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" asp-add-nonce></script>

AspNetCoreRazor/Pages/_ViewImports.cshtml

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
@using NetEscapades.AspNetCore.SecurityHeaders
33
@namespace AspNetCoreRazor.Pages
44
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
5+
@addTagHelper *, NetEscapades.AspNetCore.SecurityHeaders.TagHelpers

AspNetCoreRazor/Program.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
33
using Microsoft.Identity.Web;
44
using Microsoft.Identity.Web.UI;
5+
using NetEscapades.AspNetCore.SecurityHeaders.Infrastructure;
56

67
var builder = WebApplication.CreateBuilder(args);
78

@@ -14,6 +15,12 @@
1415
var configuration = builder.Configuration;
1516
var env = builder.Environment;
1617

18+
services.AddSecurityHeaderPolicies()
19+
.SetPolicySelector((PolicySelectorContext ctx) =>
20+
{
21+
return SecurityHeadersDefinitions.GetHeaderPolicyCollection(env.IsDevelopment());
22+
});
23+
1724
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
1825
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
1926

@@ -33,8 +40,7 @@
3340
app.UseHsts();
3441
}
3542

36-
app.UseSecurityHeaders(SecurityHeadersDefinitions
37-
.GetHeaderPolicyCollection(env.IsDevelopment()));
43+
app.UseSecurityHeaders();
3844

3945
app.UseHttpsRedirection();
4046
app.UseStaticFiles();
+9-24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using Microsoft.AspNetCore.Builder;
2-
3-
namespace AspNetCoreRazor;
1+
namespace AspNetCoreRazor;
42

53
public static class SecurityHeadersDefinitions
64
{
@@ -20,39 +18,26 @@ public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev)
2018
builder.AddImgSrc().Self().From("data:");
2119
builder.AddFormAction().Self();
2220
builder.AddFontSrc().Self();
23-
builder.AddStyleSrc().Self(); // .UnsafeInline();
2421
builder.AddBaseUri().Self();
25-
builder.AddScriptSrc().UnsafeInline().WithNonce();
2622
builder.AddFrameAncestors().None();
23+
24+
builder.AddStyleSrc().WithNonce().UnsafeInline();
25+
26+
builder.AddScriptSrc()
27+
.WithNonce()
28+
.WithHash256("j7OoGArf6XW6YY4cAyS3riSSvrJRqpSi1fOF9vQ5SrI=")
29+
.UnsafeInline();
2730
//builder.AddCustomDirective("require-trusted-types-for", "'script'");
2831
})
2932
.RemoveServerHeader()
30-
.AddPermissionsPolicy(builder =>
31-
{
32-
builder.AddAccelerometer().None();
33-
builder.AddAutoplay().None();
34-
builder.AddCamera().None();
35-
builder.AddEncryptedMedia().None();
36-
builder.AddFullscreen().All();
37-
builder.AddGeolocation().None();
38-
builder.AddGyroscope().None();
39-
builder.AddMagnetometer().None();
40-
builder.AddMicrophone().None();
41-
builder.AddMidi().None();
42-
builder.AddPayment().None();
43-
builder.AddPictureInPicture().None();
44-
builder.AddSyncXHR().None();
45-
builder.AddUsb().None();
46-
});
33+
.AddPermissionsPolicyWithDefaultSecureDirectives();
4734

4835
if (!isDev)
4936
{
5037
// maxage = one year in seconds
5138
policy.AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365);
5239
}
5340

54-
policy.ApplyDocumentHeadersToAllResponses();
55-
5641
return policy;
5742
}
5843
}

AspNetCoreRazorMultiClients/AspNetCoreRazorMultiClients.csproj

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.1" NoWarn="NU1605" />
12-
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.1" NoWarn="NU1605" />
13-
<PackageReference Include="Microsoft.Identity.Web" Version="2.16.1" />
14-
<PackageReference Include="Microsoft.Identity.Web.UI" Version="2.16.1" />
15-
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders" Version="0.21.0" />
16-
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders.TagHelpers" Version="0.21.0" />
11+
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" NoWarn="NU1605" />
12+
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.8" NoWarn="NU1605" />
13+
<PackageReference Include="Microsoft.Identity.Web" Version="3.2.0" />
14+
<PackageReference Include="Microsoft.Identity.Web.UI" Version="3.2.0" />
15+
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders" Version="1.0.0-preview.1" />
16+
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders.TagHelpers" Version="1.0.0-preview.1" />
1717
</ItemGroup>
1818

1919
</Project>

AspNetCoreRazorMultiClients/CustomAccountController.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
using System.Threading.Tasks;
2-
using Microsoft.AspNetCore.Authentication;
1+
using Microsoft.AspNetCore.Authentication;
32
using Microsoft.AspNetCore.Authentication.Cookies;
43
using Microsoft.AspNetCore.Authorization;
54
using Microsoft.AspNetCore.Mvc;
6-
using Microsoft.Extensions.Configuration;
75

86
namespace AspNetCoreRazorMultiClients;
97

AspNetCoreRazorMultiClients/Pages/Index.cshtml.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using Microsoft.AspNetCore.Mvc;
2-
using Microsoft.AspNetCore.Mvc.RazorPages;
1+
using Microsoft.AspNetCore.Mvc.RazorPages;
32

43
namespace AspNetCoreRazorMultiClients.Pages
54
{

AspNetCoreRazorMultiClients/Pages/Privacy.cshtml.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using Microsoft.AspNetCore.Mvc;
2-
using Microsoft.AspNetCore.Mvc.RazorPages;
1+
using Microsoft.AspNetCore.Mvc.RazorPages;
32

43
namespace AspNetCoreRazorMultiClients.Pages
54
{

AspNetCoreRazorMultiClients/Pages/Shared/_Layout.cshtml

+6-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
<meta charset="utf-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>@ViewData["Title"] - AspNetCoreRazorMultiClients</title>
7-
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
8-
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
9-
<link rel="stylesheet" href="~/AspNetCoreRazorMultiClients.styles.css" asp-append-version="true" />
7+
<link asp-add-nonce rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
8+
<link asp-add-nonce rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
9+
<link asp-add-nonce rel="stylesheet" href="~/AspNetCoreRazorMultiClients.styles.css" asp-append-version="true" />
1010
</head>
1111
<body>
1212
<header>
@@ -43,10 +43,9 @@
4343
</div>
4444
</footer>
4545

46-
@{var nonce = Context.GetNonce();}
47-
<script src="~/lib/jquery/dist/jquery.min.js" nonce="@nonce"></script>
48-
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js" nonce="@nonce"></script>
49-
<script src="~/js/site.js" asp-append-version="true" nonce="@nonce"></script>
46+
<script src="~/lib/jquery/dist/jquery.min.js" asp-add-nonce></script>
47+
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js" asp-add-nonce></script>
48+
<script src="~/js/site.js" asp-append-version="true" asp-add-nonce></script>
5049

5150
@await RenderSectionAsync("Scripts", required: false)
5251
</body>
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
@{var nonce = this.Context.GetNonce();}
2-
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js" nonce="@nonce"></script>
3-
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" nonce="@nonce"></script>
1+
<script asp-add-nonce src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
2+
<script asp-add-nonce src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

AspNetCoreRazorMultiClients/Pages/_ViewImports.cshtml

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
@using NetEscapades.AspNetCore.SecurityHeaders
33
@namespace AspNetCoreRazorMultiClients.Pages
44
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
5+
@addTagHelper *, NetEscapades.AspNetCore.SecurityHeaders.TagHelpers

AspNetCoreRazorMultiClients/Program.cs

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
using AspNetCoreRazorMultiClients;
2+
using Microsoft.AspNetCore.Authentication;
23
using Microsoft.AspNetCore.Authentication.Cookies;
34
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
45
using Microsoft.Identity.Web;
56
using Microsoft.Identity.Web.UI;
6-
using Microsoft.AspNetCore.Authentication;
7+
using NetEscapades.AspNetCore.SecurityHeaders.Infrastructure;
78

89
var builder = WebApplication.CreateBuilder(args);
910

@@ -16,6 +17,12 @@
1617
var configuration = builder.Configuration;
1718
var env = builder.Environment;
1819

20+
services.AddSecurityHeaderPolicies()
21+
.SetPolicySelector((PolicySelectorContext ctx) =>
22+
{
23+
return SecurityHeadersDefinitions.GetHeaderPolicyCollection(env.IsDevelopment());
24+
});
25+
1926
// store the Microsoft Entra ID login
2027
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
2128
.AddCookie();
@@ -48,7 +55,7 @@ await context.HttpContext.SignInAsync(
4855
{
4956
await existingOnTokenValidatedHandler(context);
5057

51-
if(context.Principal != null)
58+
if (context.Principal != null)
5259
{
5360
await context.HttpContext.SignInAsync(
5461
CookieAuthenticationDefaults.AuthenticationScheme, context.Principal);
@@ -71,8 +78,7 @@ await context.HttpContext.SignInAsync(
7178
app.UseHsts();
7279
}
7380

74-
app.UseSecurityHeaders(SecurityHeadersDefinitions
75-
.GetHeaderPolicyCollection(env.IsDevelopment()));
81+
app.UseSecurityHeaders();
7682

7783
app.UseHttpsRedirection();
7884
app.UseStaticFiles();
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using Microsoft.AspNetCore.Builder;
2-
3-
namespace AspNetCoreRazorMultiClients;
1+
namespace AspNetCoreRazorMultiClients;
42

53
public static class SecurityHeadersDefinitions
64
{
@@ -19,40 +17,27 @@ public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev)
1917
builder.AddBlockAllMixedContent();
2018
builder.AddImgSrc().Self().From("data:");
2119
builder.AddFormAction().Self();
22-
builder.AddFontSrc().Self();
23-
builder.AddStyleSrc().Self(); // .UnsafeInline();
24-
builder.AddBaseUri().Self();
25-
builder.AddScriptSrc().UnsafeInline().WithNonce();
20+
builder.AddFontSrc().Self();
21+
builder.AddBaseUri().Self();
2622
builder.AddFrameAncestors().None();
23+
24+
builder.AddStyleSrc().WithNonce().UnsafeInline();
25+
26+
builder.AddScriptSrc()
27+
.WithNonce()
28+
.WithHash256("j7OoGArf6XW6YY4cAyS3riSSvrJRqpSi1fOF9vQ5SrI=")
29+
.UnsafeInline();
2730
// builder.AddCustomDirective("require-trusted-types-for", "'script'");
2831
})
2932
.RemoveServerHeader()
30-
.AddPermissionsPolicy(builder =>
31-
{
32-
builder.AddAccelerometer().None();
33-
builder.AddAutoplay().None();
34-
builder.AddCamera().None();
35-
builder.AddEncryptedMedia().None();
36-
builder.AddFullscreen().All();
37-
builder.AddGeolocation().None();
38-
builder.AddGyroscope().None();
39-
builder.AddMagnetometer().None();
40-
builder.AddMicrophone().None();
41-
builder.AddMidi().None();
42-
builder.AddPayment().None();
43-
builder.AddPictureInPicture().None();
44-
builder.AddSyncXHR().None();
45-
builder.AddUsb().None();
46-
});
33+
.AddPermissionsPolicyWithDefaultSecureDirectives();
4734

4835
if (!isDev)
4936
{
5037
// maxage = one year in seconds
5138
policy.AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365);
5239
}
5340

54-
policy.ApplyDocumentHeadersToAllResponses();
55-
5641
return policy;
5742
}
5843
}

BlazorBffAzureAD/Client/BlazorHosted.Client.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.1" />
12-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.1" PrivateAssets="all" />
11+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.8" />
12+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.8" PrivateAssets="all" />
1313
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
14-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.1" />
14+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.8" />
1515
</ItemGroup>
1616

1717
<ItemGroup>

BlazorBffAzureAD/Client/Services/AuthorizedHandler.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ protected override async Task<HttpResponseMessage> SendAsync(
1818
{
1919
var authState = await _authenticationStateProvider.GetAuthenticationStateAsync();
2020
HttpResponseMessage responseMessage;
21-
if (authState.User.Identity!= null && !authState.User.Identity.IsAuthenticated)
21+
if (authState.User.Identity != null && !authState.User.Identity.IsAuthenticated)
2222
{
2323
// if user is not authenticated, immediately set response status to 401 Unauthorized
2424
responseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized);

0 commit comments

Comments
 (0)