diff --git a/identity-server/src/IdentityServer/IdentityServerConstants.cs b/identity-server/src/IdentityServer/IdentityServerConstants.cs
index 7a6a32859..947c01fc5 100644
--- a/identity-server/src/IdentityServer/IdentityServerConstants.cs
+++ b/identity-server/src/IdentityServer/IdentityServerConstants.cs
@@ -235,7 +235,7 @@ public static class ContentSecurityPolicyHashes
///
/// The hash of the inline script used on the check session endpoint.
///
- public const string CheckSessionScript = "sha256-fa5rxHhZ799izGRP38+h4ud5QXNT0SFaFlh4eqDumBI=";
+ public const string CheckSessionScript = "sha256-4Hj97GNFvt0k8A6DbSr2hoRb/RJmCCakAgE+4zuVeHs=";
}
public static class ProtocolRoutePaths
diff --git a/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/AuthorizeResultTests.cs b/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/AuthorizeResultTests.cs
index 3573dec02..14abd0e3a 100644
--- a/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/AuthorizeResultTests.cs
+++ b/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/AuthorizeResultTests.cs
@@ -2,6 +2,7 @@
// See LICENSE in the project root for license information.
+using System.Text.RegularExpressions;
using Duende.IdentityModel;
using Duende.IdentityServer;
using Duende.IdentityServer.Configuration;
@@ -226,6 +227,32 @@ public async Task form_post_mode_should_pass_results_in_body()
html.ShouldContain("");
}
+ [Fact]
+ public async Task csp_hash_should_match_inline_script()
+ {
+ _response.Request = new ValidatedAuthorizeRequest
+ {
+ ClientId = "client",
+ ResponseMode = OidcConstants.ResponseModes.FormPost,
+ RedirectUri = "http://client/callback",
+ State = "state"
+ };
+
+ await _subject.WriteHttpResponse(new AuthorizeResult(_response), _context);
+
+ _context.Response.StatusCode.ShouldBe(200);
+ _context.Response.ContentType.ShouldStartWith("text/html");
+ _context.Response.Body.Seek(0, SeekOrigin.Begin);
+ using var rdr = new StreamReader(_context.Response.Body);
+ var html = await rdr.ReadToEndAsync();
+
+ var match = Regex.Match(html, "", RegexOptions.Singleline | RegexOptions.IgnoreCase);
+ match.Success.ShouldBeTrue();
+
+ var scriptSha256 = "sha256-" + match.Groups[1].Value.ToSha256();
+ IdentityServerConstants.ContentSecurityPolicyHashes.AuthorizeScript.ShouldContain(scriptSha256);
+ }
+
[Fact]
public async Task form_post_mode_should_add_unsafe_inline_for_csp_level_1()
{
diff --git a/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/CheckSessionResultTests.cs b/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/CheckSessionResultTests.cs
index 0d17795b6..975e6a707 100644
--- a/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/CheckSessionResultTests.cs
+++ b/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/CheckSessionResultTests.cs
@@ -2,6 +2,8 @@
// See LICENSE in the project root for license information.
+using System.Text.RegularExpressions;
+using Duende.IdentityModel;
using Duende.IdentityServer;
using Duende.IdentityServer.Configuration;
using Duende.IdentityServer.Endpoints.Results;
@@ -46,6 +48,24 @@ public async Task should_pass_results_in_body()
html.ShouldContain("");
}
+ [Fact]
+ public async Task csp_hash_should_match_inline_script()
+ {
+ await _subject.WriteHttpResponse(new CheckSessionResult(), _context);
+
+ _context.Response.StatusCode.ShouldBe(200);
+ _context.Response.ContentType.ShouldStartWith("text/html");
+ _context.Response.Body.Seek(0, SeekOrigin.Begin);
+ using var rdr = new StreamReader(_context.Response.Body);
+ var html = await rdr.ReadToEndAsync();
+
+ var match = Regex.Match(html, "", RegexOptions.Singleline | RegexOptions.IgnoreCase);
+ match.Success.ShouldBeTrue();
+
+ var scriptSha256 = "sha256-" + match.Groups[1].Value.ToSha256();
+ IdentityServerConstants.ContentSecurityPolicyHashes.CheckSessionScript.ShouldContain(scriptSha256);
+ }
+
[Fact]
public async Task form_post_mode_should_add_unsafe_inline_for_csp_level_1()
{
diff --git a/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/EndSessionCallbackResultTests.cs b/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/EndSessionCallbackResultTests.cs
index 74eb6204f..20dbad1e5 100644
--- a/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/EndSessionCallbackResultTests.cs
+++ b/identity-server/test/IdentityServer.UnitTests/Endpoints/Results/EndSessionCallbackResultTests.cs
@@ -2,6 +2,9 @@
// See LICENSE in the project root for license information.
+using System.Text.RegularExpressions;
+using Duende.IdentityModel;
+using Duende.IdentityServer;
using Duende.IdentityServer.Configuration;
using Duende.IdentityServer.Endpoints.Results;
using Duende.IdentityServer.Models;
@@ -52,10 +55,10 @@ public async Task success_should_render_html_and_iframes()
_context.Response.Headers.CacheControl.First().ShouldContain("no-cache");
_context.Response.Headers.CacheControl.First().ShouldContain("max-age=0");
_context.Response.Headers.ContentSecurityPolicy.First().ShouldContain("default-src 'none';");
- _context.Response.Headers.ContentSecurityPolicy.First().ShouldContain("style-src 'sha256-e6FQZewefmod2S/5T11pTXjzE2vn3/8GRwWOs917YE4=';");
+ _context.Response.Headers.ContentSecurityPolicy.First().ShouldContain($"style-src '{IdentityServerConstants.ContentSecurityPolicyHashes.EndSessionStyle}';");
_context.Response.Headers.ContentSecurityPolicy.First().ShouldContain("frame-src http://foo.com http://bar.com");
_context.Response.Headers["X-Content-Security-Policy"].First().ShouldContain("default-src 'none';");
- _context.Response.Headers["X-Content-Security-Policy"].First().ShouldContain("style-src 'sha256-e6FQZewefmod2S/5T11pTXjzE2vn3/8GRwWOs917YE4=';");
+ _context.Response.Headers["X-Content-Security-Policy"].First().ShouldContain($"style-src '{IdentityServerConstants.ContentSecurityPolicyHashes.EndSessionStyle}';");
_context.Response.Headers["X-Content-Security-Policy"].First().ShouldContain("frame-src http://foo.com http://bar.com");
_context.Response.Body.Seek(0, SeekOrigin.Begin);
using var rdr = new StreamReader(_context.Response.Body);
@@ -64,6 +67,27 @@ public async Task success_should_render_html_and_iframes()
html.ShouldContain("");
}
+ [Fact]
+ public async Task csp_hash_should_match_inline_style()
+ {
+ _result.IsError = false;
+ _result.FrontChannelLogoutUrls = new string[] { "http://foo.com", "http://bar.com" };
+
+ await _subject.WriteHttpResponse(new EndSessionCallbackResult(_result), _context);
+
+ _context.Response.StatusCode.ShouldBe(200);
+ _context.Response.ContentType.ShouldStartWith("text/html");
+ _context.Response.Body.Seek(0, SeekOrigin.Begin);
+ using var rdr = new StreamReader(_context.Response.Body);
+ var html = await rdr.ReadToEndAsync();
+
+ var match = Regex.Match(html, "", RegexOptions.Singleline | RegexOptions.IgnoreCase);
+ match.Success.ShouldBeTrue();
+
+ var styleSha256 = "sha256-" + match.Groups[1].Value.ToSha256();
+ IdentityServerConstants.ContentSecurityPolicyHashes.EndSessionStyle.ShouldContain(styleSha256);
+ }
+
[Fact]
public async Task fsuccess_should_add_unsafe_inline_for_csp_level_1()
{
@@ -73,8 +97,8 @@ public async Task fsuccess_should_add_unsafe_inline_for_csp_level_1()
await _subject.WriteHttpResponse(new EndSessionCallbackResult(_result), _context);
- _context.Response.Headers.ContentSecurityPolicy.First().ShouldContain("style-src 'unsafe-inline' 'sha256-e6FQZewefmod2S/5T11pTXjzE2vn3/8GRwWOs917YE4='");
- _context.Response.Headers["X-Content-Security-Policy"].First().ShouldContain("style-src 'unsafe-inline' 'sha256-e6FQZewefmod2S/5T11pTXjzE2vn3/8GRwWOs917YE4='");
+ _context.Response.Headers.ContentSecurityPolicy.First().ShouldContain($"style-src 'unsafe-inline' '{IdentityServerConstants.ContentSecurityPolicyHashes.EndSessionStyle}'");
+ _context.Response.Headers["X-Content-Security-Policy"].First().ShouldContain($"style-src 'unsafe-inline' '{IdentityServerConstants.ContentSecurityPolicyHashes.EndSessionStyle}'");
}
[Fact]
@@ -86,7 +110,7 @@ public async Task form_post_mode_should_not_add_deprecated_header_when_it_is_dis
await _subject.WriteHttpResponse(new EndSessionCallbackResult(_result), _context);
- _context.Response.Headers.ContentSecurityPolicy.First().ShouldContain("style-src 'sha256-e6FQZewefmod2S/5T11pTXjzE2vn3/8GRwWOs917YE4='");
+ _context.Response.Headers.ContentSecurityPolicy.First().ShouldContain($"style-src '{IdentityServerConstants.ContentSecurityPolicyHashes.EndSessionStyle}'");
_context.Response.Headers["X-Content-Security-Policy"].ShouldBeEmpty();
}
}