SafeWebCore 1.3.0
dotnet add package SafeWebCore --version 1.3.0
NuGet\Install-Package SafeWebCore -Version 1.3.0
<PackageReference Include="SafeWebCore" Version="1.3.0" />
<PackageVersion Include="SafeWebCore" Version="1.3.0" />
<PackageReference Include="SafeWebCore" />
paket add SafeWebCore --version 1.3.0
#r "nuget: SafeWebCore, 1.3.0"
#:package SafeWebCore@1.3.0
#addin nuget:?package=SafeWebCore&version=1.3.0
#tool nuget:?package=SafeWebCore&version=1.3.0
๐ก๏ธ SafeWebCore
A lightweight, high-performance .NET 10 middleware library that adds security headers to your ASP.NET Core applications. Targets an A+ rating on securityheaders.com out of the box.
Backward Compatibility Goal
SafeWebCore keeps a strict 100% backward compatibility contract. New capabilities are additive and opt-in, so existing configurations keep their current behavior.
Two Ways to Use SafeWebCore
Option 1 โ Strict A+ Preset (fastest)
One line for the strictest A+ configuration. Defined in ServiceCollectionExtensions.AddNetSecureHeadersStrictAPlus().
using SafeWebCore.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddNetSecureHeadersStrictAPlus();
var app = builder.Build();
app.UseNetSecureHeaders();
app.Run();
Customize the preset โ CSP directives are space-separated, add multiple origins in one string:
builder.Services.AddNetSecureHeadersStrictAPlus(opts =>
{
// Single origin
opts.Csp = opts.Csp with { ImgSrc = "'self' https://cdn.example.com" };
// Multiple origins โ just separate with spaces
opts.Csp = opts.Csp with { ImgSrc = "'self' https://cdn1.example.com https://cdn2.example.com data:" };
// Multiple directives at once
opts.Csp = opts.Csp with
{
ConnectSrc = "'self' https://api.example.com wss://ws.example.com",
FontSrc = "'self' https://fonts.gstatic.com https://cdn.example.com"
};
// Non-CSP headers
opts.ReferrerPolicyValue = "strict-origin-when-cross-origin";
});
Option 2 โ Fully Custom Configuration
Full control over every header via ServiceCollectionExtensions.AddNetSecureHeaders():
using SafeWebCore.Builder;
using SafeWebCore.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddNetSecureHeaders(opts =>
{
// Transport security
opts.EnableHsts = true;
opts.HstsValue = "max-age=31536000; includeSubDomains";
// Framing
opts.EnableXFrameOptions = true;
opts.XFrameOptionsValue = "SAMEORIGIN";
// MIME sniffing
opts.EnableXContentTypeOptions = true;
opts.XContentTypeOptionsValue = "nosniff";
// Referrer
opts.EnableReferrerPolicy = true;
opts.ReferrerPolicyValue = "strict-origin-when-cross-origin";
// Permissions
opts.EnablePermissionsPolicy = true;
opts.PermissionsPolicyValue = "camera=(), microphone=(), geolocation=()";
// Cross-Origin isolation
opts.EnableCoep = true;
opts.CoepValue = "require-corp";
opts.EnableCoop = true;
opts.CoopValue = "same-origin";
opts.EnableCorp = true;
opts.CorpValue = "same-origin";
// Server header
opts.RemoveServerHeader = true;
// CSP โ use the fluent builder
opts.Csp = new CspBuilder()
.DefaultSrc("'none'")
.ScriptSrc("'nonce-{nonce}' 'strict-dynamic' https:")
.StyleSrc("'nonce-{nonce}'")
.ImgSrc("'self' https: data:")
.FontSrc("'self' https://fonts.gstatic.com")
.ConnectSrc("'self' wss://realtime.example.com")
.FrameAncestors("'none'")
.BaseUri("'none'")
.FormAction("'self'")
.UpgradeInsecureRequests()
.Build();
});
var app = builder.Build();
app.UseNetSecureHeaders();
app.Run();
Both methods are defined in SafeWebCore.Extensions.ServiceCollectionExtensions.
Strict A+ Headers
| Header | Strict A+ Value |
|---|---|
Strict-Transport-Security |
max-age=63072000; includeSubDomains; preload |
Content-Security-Policy |
Nonce-based, strict-dynamic, Trusted Types |
X-Frame-Options |
DENY |
X-Content-Type-Options |
nosniff |
Referrer-Policy |
no-referrer |
Permissions-Policy |
All 28 browser features denied (modern, Chromium-recognised tokens) |
Cross-Origin-Embedder-Policy |
require-corp |
Cross-Origin-Opener-Policy |
same-origin |
Cross-Origin-Resource-Policy |
same-origin |
Server |
(removed) |
Features
- ๐ Strict A+ preset โ one-line setup with the strictest security headers
- ๐ Browser-safe Permissions-Policy โ preset emits only tokens recognised by current Chromium builds; stale tokens (
ambient-light-sensor,battery,navigation-override, etc.) removed in v1.3.0 to eliminate console noise - ๐ ๏ธ Fully custom โ configure every header and CSP directive individually
- ๐งฉ Nonce-based CSP โ per-request cryptographic nonces for scripts and styles
- ๐งท Razor nonce TagHelpers โ auto-add nonce to
<script>and<style>in Razor views - ๐ฃ๏ธ Path-based policies โ assign different security profiles per route prefix (longest-prefix wins)
- ๐งช Startup validation โ fail fast on invalid combinations and duplicate path policies
- ๐ CSP Report-Only mode โ safely test policy changes before hard enforcement
- ๐งฑ Typed policy builders โ strongly typed builders for
Referrer-Policy,Permissions-Policy, and COEP/COOP/CORP - ๐งญ First-class upcoming header support โ configure non-standard or emerging headers through
AdditionalHeaders(opt-in) - ๐ก First-class Reporting API endpoint support โ emit
Reporting-Endpointsfrom typedReportingEndpointsoptions (opt-in) - ๐ Full CSP Level 3 (W3C Recommendation) โ all 22 directives, nonce/hash support,
strict-dynamic,report-to,worker-src,frame-src,manifest-src,script-src-elem/attr,style-src-elem/attr - ๐ฎ CSP Level 4 ready โ Trusted Types (
require-trusted-types-for,trusted-types),fenced-frame-src(Privacy Sandbox) - ๐ฏ Fluent CSP Builder โ type-safe, chainable API with full XML documentation
- โก Zero-allocation nonce generation โ
stackalloc+RandomNumberGenerator, plusTryWriteNonce(Span<char>)for fully heap-free scenarios (v1.1.0) - ๐
HttpContext.GetCspNonce()โ discoverable extension method to retrieve the per-request nonce (v1.1.0) - ๐ Pre-built CSP template โ CSP header string computed once at startup, not per-request (v1.1.0)
- ๐ Extensible โ custom
IHeaderPolicyimplementations - ๐ CSP violation reporting โ built-in
/csp-reportendpoint using Reporting API v1
First-class Upcoming Headers (Opt-in)
Use AdditionalHeaders when you want to emit upcoming or non-standard headers without writing a custom policy type:
builder.Services.AddNetSecureHeaders(opts =>
{
opts.AdditionalHeaders.Add(new()
{
Name = "Document-Policy",
Value = "force-load-at-top"
});
});
First-class Reporting Endpoints (Opt-in)
Use ReportingEndpoints to emit the Reporting-Endpoints response header and map endpoint groups used by CSP report-to:
builder.Services.AddNetSecureHeaders(opts =>
{
opts.Csp = opts.Csp with { ReportTo = "default" };
opts.ReportingEndpoints.Add(new()
{
Group = "default",
Url = "https://reports.example.com/csp"
});
});
Emitted header value:
Reporting-Endpoints: default="https://reports.example.com/csp"
Validate Your Headers
After deploying, test your security headers with:
- securityheaders.com โ Grades all response headers A+ through F. With the Strict A+ preset you should score A+ immediately.
- Google CSP Evaluator โ Paste your
Content-Security-Policyvalue to check for misconfigurations (missingobject-src,'unsafe-inline'without nonce, missing'strict-dynamic', etc.).
Documentation
Full documentation: github.com/MPCoreDeveloper/SafeWebCore/docs
Planning documents:
License
MIT โ see LICENSE
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
## v1.3.0 โ Permissions-Policy Browser Compatibility Cleanup
**Changed:**
- StrictAPlus preset: removed 8 stale Permissions-Policy tokens that Chromium logs as
"Unrecognized feature" (ambient-light-sensor, battery, cross-origin-isolated,
document-domain, execution-while-not-rendered, execution-while-out-of-viewport,
navigation-override, sync-xhr). These were removed from or were never part of the
Permissions Policy spec.
- StrictAPlus preset: added 7 modern Permissions-Policy tokens standardised in 2022โ2024
(clipboard-read, clipboard-write, identity-credentials-get, local-fonts,
otp-credentials, publickey-credentials-create, window-management).
**Result:** Preset now emits 28 recognised feature tokens, eliminating browser console
noise while keeping full deny-all coverage for all current standardised features.
## v1.2.0 โ Security Rollout and Developer Experience
**Major Features:**
- CSP Report-Only mode for safe policy rollout before enforcement
- Path-based policy selection (different headers per route prefix, longest-prefix matching)
- Startup validation with actionable errors for invalid configurations
- Razor TagHelpers for automatic nonce injection on <script> and <style>
- Typed builders for Referrer-Policy, Permissions-Policy, and Cross-Origin policies
- CSP violation reporting with ICspReportSink abstraction (custom handling, logging, telemetry)
- Endpoint metadata overrides ([SkipNetSecureHeaders], [CspMode]) for targeted exceptions
- Optional additional headers: Origin-Agent-Cluster, X-Robots-Tag, Clear-Site-Data
- Five app-profile presets: StrictAPlus, Api, Mvc, Blazor, SpaReverseProxy
**Performance Optimizations (v1.1.0+):**
- Pre-built CSP template (computed once at startup, not per-request)
- StringBuilder-based CSP header generation (eliminates ~20 intermediate string allocations)
- Zero-allocation nonce generation: TryWriteNonce(Span<char>) for heap-free scenarios
- NonceService.NonceLength constant (44) for buffer pre-allocation
**New APIs:**
- HttpContext.GetCspNonce() extension method for discoverable nonce access
- NonceService.TryWriteNonce(Span<char>, out int written) for zero-alloc scenarios
- CspBuilder.Build() returns immutable CspOptions record
- Improved CancellationToken propagation in CSP reporting pipeline
**Improvements:**
- Modernized C# patterns (primary constructors, collection expressions, file-scoped namespaces)
- Comprehensive documentation for all features and presets
- Full CSP Level 3 (W3C Recommendation) support
- CSP Level 4 ready (Trusted Types, fenced-frame-src)
**Breaking Changes:** None โ fully backward compatible with v1.0.0+
See docs/ for complete guides and examples/ for runnable sample projects.