SafeWebCore 1.8.1
dotnet add package SafeWebCore --version 1.8.1
NuGet\Install-Package SafeWebCore -Version 1.8.1
<PackageReference Include="SafeWebCore" Version="1.8.1" />
<PackageVersion Include="SafeWebCore" Version="1.8.1" />
<PackageReference Include="SafeWebCore" />
paket add SafeWebCore --version 1.8.1
#r "nuget: SafeWebCore, 1.8.1"
#:package SafeWebCore@1.8.1
#addin nuget:?package=SafeWebCore&version=1.8.1
#tool nuget:?package=SafeWebCore&version=1.8.1
๐ก๏ธ 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.
Current version: 1.8.1
New in 1.8.1 (maintenance patch โ no public API, default, preset or behavior change):
- Internal deduplication โ the pen-test signal scoring, the authorization-check notification flow and the path-policy resolution were byte-identical copies in the two fraud detectors and in the middleware/diagnostics pair; they now live once in the internal
PenTestSignalAnalyzerandPathPolicyResolverhelpers, so a rule can only change in one place. - Allocation cleanup โ the path-policy lookup walks the list by index instead of allocating an enumerator per request, and the repeated CSP source literals in
SecurePresets,CspOptionsandCrossOriginPolicyBuildernow name one private constant per file. Every emitted header value and policy-resolution outcome is identical. - Dependency maintenance โ development-only packages (test SDK, xunit, coverlet,
PublicApiAnalyzers) refreshed to their latest stable releases. - Docs โ a new SonarCloud triage page records how the analysis is scoped and the ten findings that are deliberately accepted.
SafeWebCore.FraudDetectionmoves to1.1.1,SafeWebCore.JwtBearerto1.0.1(itsMicrosoft.AspNetCore.Authentication.JwtBearerfloor is now 10.0.12), and the two preview packages to1.0.0-preview.2.
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 recognized features denied (scanner-safe, modern Chromium tokens only) |
Cross-Origin-Embedder-Policy |
require-corp |
Cross-Origin-Opener-Policy |
same-origin |
Cross-Origin-Resource-Policy |
same-origin |
Server |
(removed) |
X-Powered-By |
(removed) |
Features
- ๐ Strict A+ preset โ one-line setup with the strictest security headers
- ๐ Browser-safe Permissions-Policy โ preset emits only scanner-recognised tokens; invalid directives (e.g. identity-credentials-get, otp-credentials, publickey-credentials-create, window-management) and stale tokens removed to pass securityheaders.com checks without warnings
- ๐ ๏ธ 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:
- Current Roadmap โ active planning for v1.4 โ v1.6
- v1.2 Roadmap (archived / completed)
- v1.2 Implementation Plan (archived / completed)
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 (1)
Showing the top 1 NuGet packages that depend on SafeWebCore:
| Package | Downloads |
|---|---|
|
SafeWebCore.Testing
Testing helpers for SafeWebCore. Includes header assertions, CSP/nonce assertions, and bootstrap helpers for integration tests. |
GitHub repositories
This package is not used by any popular GitHub repositories.
## v1.8.1 โ Internal cleanup, no behavior change
Maintenance patch on the 1.8.0 line. **100% backwards compatible** โ the public API surface, defaults, presets and configuration paths are untouched.
**Changes:**
- Internal deduplication: the pen-test signal scoring, the authorization-check notification flow and the path-policy resolution existed as byte-identical copies in `GeoCulturalConsistencyDetector` / `WesternImpersonationDetector` and in `NetSecureHeadersMiddleware` / `NetSecureHeadersDiagnosticsService`. They now live once, in the internal `PenTestSignalAnalyzer` and `PathPolicyResolver` helpers that both call sites use, so a score, a throttle rule or a policy-resolution rule can only change in one place
- Internal code-quality cleanup with no behavior change: the repeated CSP source literals in `SecurePresets`, `CspOptions` and `CrossOriginPolicyBuilder` now name one private constant per file, and the path-policy lookup walks the list by index instead of allocating an enumerator per request. Every emitted header value, directive and policy-resolution outcome is identical
- Docs: a new SonarCloud triage page records how the analysis is scoped and the ten findings that are deliberately accepted
- Development-only dependencies refreshed to their latest stable releases
See CHANGELOG.md and docs/ for full details.