Skip to content

fix(security): harden web.config — CSP, HSTS, cookies, crypto (#131) - #442

Merged
jsboige merged 1 commit into
masterfrom
security/131-webconfig-hardening
Jun 15, 2026
Merged

fix(security): harden web.config — CSP, HSTS, cookies, crypto (#131)#442
jsboige merged 1 commit into
masterfrom
security/131-webconfig-hardening

Conversation

@jsboige

@jsboige jsboige commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

@

Security hardening — DNNPlatform/web.config (#131)

Prep work for #131 Phase D. Harden the web.config snapshot (keys-excluded, safe to commit). The real production web.config (with machineKey/connection strings) is on the VPS — jsboige applies changes manually.

Changes (+15/-6, 1 file)

HTTP response headers (system.webServer/httpProtocol):

  • Add X-Content-Type-Options: nosniff — prevent MIME sniffing
  • Add Content-Security-Policy — restrictive default (self + needed CDN exceptions for Stripe/JS/fonts)
  • Add Referrer-Policy: strict-origin-when-cross-origin
  • Add Permissions-Policy: camera=(), microphone=(), geolocation=()
  • Strict-Transport-Securitycommented out (activate only when prod is fully HTTPS)

Cryptography (machineKey):

  • decryption: 3DES → AES
  • validation: SHA1 → HMACSHA256

Cookies:

  • httpCookies requireSSL: false → true — cookies only over HTTPS
  • anonymousIdentification cookieRequireSSL: false → true
  • anonymousIdentification cookieProtection: None → All (encryption + validation)

Password policy (AspNetSqlMembershipProvider):

  • minRequiredPasswordLength: 7 → 12
  • minRequiredNonalphanumericCharacters: 0 → 1

Auth services:

  • BasicAuth/DigestAuth forceSSL: false → true

PR Status

HOLD — merge timing:

Testing

  • Static config change only — no automated tests applicable
  • Verify in staging: check response headers via curl -I, confirm cookies set with Secure flag
  • CSP may need relaxation if third-party resources are added (analytics, fonts, etc.)

Related

…assword policy (#131)

Security hardening changes (snapshot repo, keys excluded):

Headers (system.webServer/httpProtocol):
- Add X-Content-Type-Options: nosniff
- Add Content-Security-Policy (restrictive default)
- Add Referrer-Policy: strict-origin-when-cross-origin
- Add Permissions-Policy (camera/mic/geo disabled)
- HSTS: commented out (activate when prod is fully HTTPS)

Crypto (machineKey):
- decryption: 3DES → AES
- validation: SHA1 → HMACSHA256

Cookies:
- httpCookies requireSSL: false → true
- anonymousIdentification cookieRequireSSL: false → true
- anonymousIdentification cookieProtection: None → All

Password policy:
- minRequiredPasswordLength: 7 → 12
- minRequiredNonalphanumericCharacters: 0 → 1

Auth services:
- BasicAuth/DigestAuth forceSSL: false → true

Ref: #131 (security audit P1 recommendations)
Note: Real production web.config (with keys) on VPS — jsboige applies manually.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NanoClaw]

Review: web.config security hardening

Solid hardening pass. All changes move in the right direction and align with the #131 audit recommendations (P1 items 4, 8, 9). +15/-6 on a single config file, well-scoped.

Good

  • Crypto migration: 3DES to AES, SHA1 to HMACSHA256 — both correct. Placeholder keys (REPLACE) confirm this is a safe-to-commit template, not production config.
  • Cookie hardening: requireSSL=true + cookieProtection=All on both httpCookies and anonymousIdentification — proper defense-in-depth even though BasicAuth/DigestAuth are disabled (the forceSSL=true change on those is good hygiene).
  • New headers: X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy (camera/mic/geo blocked) — all standard and well-chosen.
  • HSTS commented out: Prudent. The remove+commented-add pattern is clean — uncomment when prod is confirmed HTTPS-only.
  • Password policy: 12 chars + 1 non-alphanumeric — reasonable modern minimum. Existing passwords unaffected (ASP.NET enforces on new/reset only).
  • Remove-before-add pattern: Consistent with existing headers (X-Powered-By, X-XSS-Protection, X-Frame-Options) — correctly overrides IIS defaults before setting explicit values.

Concerns (non-blocking)

1. Cookie requireSSL="true" timing — verify prod HTTPS status

This is the only change with real regression potential. If any production traffic still arrives over HTTP, setting requireSSL=true will silently drop session and anonymous identification cookies for those requests — users get logged out or can't maintain sessions. The HSTS header is correctly held back for this reason, but the cookie flag is already active. If the site is fully HTTPS (redirect HTTP to HTTPS at the load balancer/IIS level), this is fine. If not, these cookie changes should ride along with the HTTPS migration, not precede it.

2. CSP unsafe-inline + unsafe-eval weaken the policy significantly

These effectively neuter XSS protection from CSP — 'unsafe-eval' allows eval(), new Function(), etc. This is a known DNN limitation (the framework injects inline scripts and uses eval in postback/control lifecycle), so it's an acceptable trade-off for a DNN-based site. But it should be tracked as tech debt — if DNN ever moves away from inline script injection, these should be tightened (or use nonce/hash-based CSP).

3. CSP img-src ... https: is very permissive

Allows images from any HTTPS source, which is an exfiltration vector (attacker loads https://evil.com/track?data=stolen as an image src). For a DNN site with user-generated content this may be necessary, but consider restricting to known domains if practical.

4. HSTS activation needs a follow-up task

The comment says "activate ONLY when site is fully HTTPS" — make sure there's a tracked item to uncomment this after the HTTPS migration is confirmed, otherwise it gets forgotten.

Verdict

No blockers. The security posture is materially improved. The one actionable item is confirming production is HTTPS-only before merging (or accepting the cookie change as part of the HTTPS migration). The CSP limitations are a known DNN trade-off, not a deficiency in this PR.

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Hermes] Review web.config security hardening (#131)

Checklist: ✅ Security clean (changes are hardening, not leaks) ✅ Cross-repo: none ✅ Fix incident: #131

Analysis — 9 security improvements: CSP restrictive default, X-Content-Type-Options nosniff, HSTS (correctly commented pending full HTTPS), Referrer-Policy strict-origin, Permissions-Policy camera/mic/geo disabled, machineKey HMACSHA256/AES, cookies requireSSL, membership password 12+ chars + 1 non-alpha, auth handlers forceSSL.

Note: CSP allows unsafe-inline/unsafe-eval — needed for legacy DNN/Razor. Consider nonce-based CSP if templates migrate.

APPROVE: Comprehensive security hardening following best practices.

@jsboige
jsboige merged commit 092bb8f into master Jun 15, 2026
3 checks passed
@jsboige
jsboige deleted the security/131-webconfig-hardening branch June 15, 2026 01:03
jsboige added a commit that referenced this pull request Jun 15, 2026
Secondary task of ai-01 dispatch `slfy5i`. Documents the intermediate
security palier 9.11.1 -> 9.13.x that closes CVE-2025-64095 (CVSS 9.8,
unauthenticated file upload via HTML editor provider) WITHOUT the
gated 10.x jump (eshop/OpenStore, Stripe, jsboige go-live).

Honest scoping: 9.13.x does NOT patch CVE-2025-52488 (NTLM hash
exposure, requires 10.0.1) -- documented as residual risk, mitigated
by the #442 hardenings (AES/HMACSHA256 machineKey, requireSSL cookies,
CSP) already merged on master 092bb8f.

Verified current state by code: DotNetNuke.dll ProductVersion = 9.11.1
(web.config InstallVersion=09.06.02 is a legacy sticker, NOT runtime
truth); .NET target 4.8 (9.13.x stays on 4.8, no .NET 8+ jump); 2sxc
21.x + Argumentum Razor14 templates are the integration risk to verify.

Plan is sandbox-prep only -- no prod touch, no tag, release v0.9.0 gate
unaffected. Execution blocked until jsboige provisions sandbox copy +
disk headroom (C: ~9 GB free / 100%).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
jsboige added a commit that referenced this pull request Jul 22, 2026
…ecret leak (#842)

Defense-in-depth against accidental commit of real DNN credentials.

Context: DNNPlatform/web.config is git-tracked but carries PLACEHOLDERS on
master (Data Source=REPLACE, validationKey/decryptionKey='REPLACE', per #442).
At runtime DNN expands these to real SQL password + machineKey and rewrites the
file in-place, so it shows as modified ('M') — permanent risk of 'git add'-ing
the real secret.

This pre-commit hook (.githooks/pre-commit) rejects any staged web.config that
contains a REAL (non-placeholder) secret:
  - Password=<non-REPLACE value>
  - validationKey='<16+ hex>'
  - decryptionKey='<16+ hex>'
The master placeholder template passes.

Orthogonal to machineKey rotation (server-ops, jsboige-gated #415). Does NOT
modify the template itself (load-bearing per #442, no-ersatz-overwrite).

Per ai-01 GO (msg-...v9ktbh): open PR, coordinator review before merge.

Co-authored-by: Claude <noreply@anthropic.com>
jsboige added a commit that referenced this pull request Jul 23, 2026
…ok (#856)

Transforms scattered staged docs (#854 machineKey + #442 web.config hardening +
dnn10-migration-readiness + skin diagnostic #851) into ONE top-to-bottom
procedure jsboige executes on go-live day.

- Block-head: 4 blocking arbitrages checklist (machineKey rotation / skin
  tabid=138 Opt 1 vs 2 / #681 2sxc export / T&A #802).
- Body: canonical ordered sequence (A rotation server-side FIRST -> B1 scrub
  bleed-stop after rotation -> C verify #442 hardening already-merged -> D
  DNN10 readiness -> E 2sxc #681 -> F deploy #132 + ai-01 live verdict).
- Every step tagged [jsboige-DECISION] / [po-2023-EXEC] / [ai-01-VERDICT].
- Each step POINTS to its staged doc (does not duplicate content).
- #811 dependabot assessment folded in (transitive, reco merge, 0 prod path).
- SECRET-SAFE: references by location only (0 key/password/CS value).
  GitGuardian must pass.

Note (code=truth): #442 = MERGED (hardening on master, not HELD), #444/#132
= CLOSED - capstone reflects reality.

Dispatch ai-01 msg-20260723T024927-zwcvck (primaire). Staged / 0 exec gated.
Verdict go-live = ai-01.

Co-authored-by: Claude-Code <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants