mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
Merge pull request #2283 from DuendeSoftware/mb/csp
Add tests for wrong CSP hash constants
This commit is contained in:
parent
fcfbc9645e
commit
24d6b9c492
4 changed files with 77 additions and 6 deletions
|
|
@ -235,7 +235,7 @@ public static class IdentityServerConstants
|
|||
/// <summary>
|
||||
/// The hash of the inline script used on the check session endpoint.
|
||||
/// </summary>
|
||||
public const string CheckSessionScript = "sha256-fa5rxHhZ799izGRP38+h4ud5QXNT0SFaFlh4eqDumBI=";
|
||||
public const string CheckSessionScript = "sha256-4Hj97GNFvt0k8A6DbSr2hoRb/RJmCCakAgE+4zuVeHs=";
|
||||
}
|
||||
|
||||
public static class ProtocolRoutePaths
|
||||
|
|
|
|||
|
|
@ -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 class AuthorizeResultTests
|
|||
html.ShouldContain("<input type='hidden' name='state' value='state' />");
|
||||
}
|
||||
|
||||
[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, "<script>(.*?)</script>", 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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 class CheckSessionResultTests
|
|||
html.ShouldContain("<script id='cookie-name' type='application/json'>foobar</script>");
|
||||
}
|
||||
|
||||
[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, "<script>(.*?)</script>", 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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 class EndSessionCallbackResultTests
|
|||
_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 class EndSessionCallbackResultTests
|
|||
html.ShouldContain("<iframe loading='eager' allow='' src='http://bar.com'></iframe>");
|
||||
}
|
||||
|
||||
[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, "<style>(.*?)</style>", 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 class EndSessionCallbackResultTests
|
|||
|
||||
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 class EndSessionCallbackResultTests
|
|||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue