NetEscapades.AspNetCore.SecurityHeaders
NetEscapades.AspNetCore.SecurityHeaders copied to clipboard
Set a different X-Frame-Options and CSP for specific page
How can we allow only certain page to be placed in iframe? The rest of the pages will have X-Frame-Options deny and CSP that blocks iframe
I'm afraid that's currently not possible. It's an interesting feature idea though.
I think one possible workaround for the CSP side would be to use a frame-src with a nonce
I think my use case can be accomplished by having HeaderPolicyCollection as a request scoped object, then inject IHttpContextAccessor in IConfigureOptions<HeaderPolicyCollection>, and returning different policies depending on the URL.
I shall do a pull request to register IOptions<HeaderPolicyCollection> and inject it in the middleware. The pattern will thus be like the CorsMiddleware, with AddSecurityHeaders in ConfigureServices and UseSecurityHeaders in Configure.
To register IOptions<HeaderPolicyCollection> as scoped, I call services.AddScoped<IOptions<HeaderPolicyCollection>, OptionsManager<HeaderPolicyCollection>>(); in my code.
I actually initially modelled the library after the CorsMiddleware but specifically removed the requirement to do AddSecurityHeaders in ConfigureServices after feedback.
I'm not against adding features, but I'd really like to keep the required setup as it is where possible 🙂
Since ASP.NET Core 2.0, the Add/Use pattern is adopted. It enables IConfigureOptions to configure different settings for each request, instead of forking the middleware pipeline.
I think following CorsMiddleware still makes sense. It allows for both configuring via UseCors and via AddCors. Thus existing code should still work
For those who want this feature. I just removed the header after it was added. It a bit quick and dirty:
var policyCollection = new HeaderPolicyCollection()
.AddDefaultSecurityHeaders();
// immediately remove X-Frame-Options that is added from UseSecurityHeaders
app.Use(async (context, next) =>
{
// OnStarting delegates run in reverse order so we configure Before UseSecurityHeaders()
context.Response.OnStarting(OnResponseStartingRemoveXFrameOptions, context);
await next();
});
Task OnResponseStartingRemoveXFrameOptions(object state)
{
if (state is HttpContext context) {
if (context.Request.Path == "/blah") // your predicate here
{
context.Response.Headers.Remove("X-Frame-Options");
}
}
return Task.CompletedTask;
}
app.UseSecurityHeaders(policyCollection);