Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
What Changed in Frontend Security from Angular 11 to 22 and in Browsers
From Angular 11 to 22 most security features arrived in patches rather than new majors, so auditing an old project means checking the exact version, not the major. In this post we verify the version of each feature from Trusted Types to autoCsp and SSR allowedHosts from package tarballs, show in headless Chrome that 22.0.8 does not send the XSRF header, collect the browser changes and produce a runnable audit script.
Hardening the npm Supply Chain: Lifecycle Scripts, Release Cooldowns, Provenance and Trusted Publishing
Hardening the npm supply chain rests on three pillars: limiting install scripts with an allow list, letting new versions wait a few days, and removing publish tokens with trusted publishing. In this post we try npm 11 and 12's allowScripts policy, pnpm's allowBuilds and minimumReleaseAge, npm's min-release-age, npm audit signatures output and OIDC-based trusted publishing with real installs against a local registry.
Angular SSR Security: allowedHosts, Host Header Validation, TransferState and Secrets Leaking into Bundles
In Angular SSR the server resolves relative HttpClient URLs against the incoming request's Host header, so fill allowedHosts with explicit names, trust proxy headers only behind a trusted proxy and do not derive the API address from Host. On a local SSR server we show SSRF, the 2026 advisories, fields leaking into TransferState, a nonce-based CSP under SSR and secrets ending up in bundles and source maps, all with real output.
Third-Party Scripts, iframes and postMessage: sandbox, frame-ancestors, Permissions-Policy and Safe Messaging
Third-party code added with a script tag runs in your origin with your authority; move it into a sandboxed iframe on its own origin, close your page to framing with the frame-ancestors header, switch off unused APIs with Permissions-Policy and validate origin, source window and schema in postMessage. We show each step with real output from headless Chrome and Vitest in a local three-origin lab.
Where Should Tokens Live? The Threat Model of localStorage, Memory, Cookies, Service Workers and the BFF
No browser storage location can stop XSS from sending requests as the user; the difference is whether the token can be read and carried away, which is why RFC 10017 recommends a BFF that never hands tokens to the browser. In this post we test localStorage, memory and HttpOnly cookie models with simulated XSS in an Angular 22 and ASP.NET Core 10 lab, weigh Web/Service Worker and refresh token risks, and pin down Bookstore's BFF decision with tests.
Taking Trusted Types to Production: Angular Policies, Third-Party Libraries and Baseline 2026
Trusted Types makes DOM sinks accept only typed objects produced by an allowed policy instead of plain strings; even writing the result of DomSanitizer.sanitize to innerHTML is a violation. In this post we verify Angular's policy names in node_modules, build an inventory with Report-Only, resolve DOMPurify, loader and third-party script violations, show the danger of the default policy and summarize support, which became Baseline 2026 with Firefox 148.
Applying a Strict CSP to Angular: Nonces, strict-dynamic, autoCsp and a Gradual Rollout with Report-Only
Allowlist-based CSPs can usually be bypassed; the right path for Angular is a strict policy built on a nonce or hash plus 'strict-dynamic'. In this post we show, with headless Chrome output, the hash-based policy autoCsp generates for static hosting, per-request nonces with ngCspNonce served from ASP.NET Core, the base-uri 'none' trap, getting along with third-party scripts and moving to enforcement with Report-Only without breaking anything.
A DOM XSS Sink Inventory for Angular: ElementRef, Renderer2, Dynamic URLs, HTML-Producing Libraries and a Code Review Checklist
Angular only sanitizes its own template bindings; ElementRef.nativeElement, Renderer2.setProperty/setAttribute, insertAdjacentHTML, dynamic script and iframe sources and HTML-producing libraries are unprotected. In this post we show these sinks in headless Chrome, fix them with the template and DomSanitizer, compare marked, DOMPurify and setHTML, and build a grep and ESLint based code review checklist.
The Browser Security Model: Same-Origin Policy, Origin vs Site, SameSite Cookies and Fetch Metadata
The Same-Origin Policy does not stop a cross-origin request, it only stops the response from being read; SameSite decides which cookies go with the request, and the server can reject it by looking at the Sec-Fetch-* headers. In this post we log the real behaviour of origin vs site, CORS, Strict/Lax/None cookies and Fetch Metadata headers from headless Chrome against an ASP.NET Core 10 lab, and build a Fetch Metadata policy with tests.