jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

Web Security for Frontend Devs · Part 8 — Secure Headers & HTTPS/TLS

HTTPS/TLS, HSTS, mixed content, the production security-header stack (CSP, COOP/COEP, Permissions-Policy, SRI), static-host `_headers` examples, and audit tooling — with exercises.

Part 8 of 10 in the Web Security for Frontend Devs series {Phần 8/10 trong series Web Security for Frontend Devs}. Previous {Trước}: Part 7 — Clickjacking & Framing · Next {Tiếp}: Part 9 — Secrets, Data Leakage & Supply-Chain.

This is Part 8 of a 10-part series on the web-security essentials every frontend developer should know — and actively prevent {Đây là Phần 8 của series 10 bài về những kiến thức bảo mật web mà mọi frontend dev nên biết — và chủ động phòng tránh}. Each part explains a real threat, shows vulnerable code, then the fix, and ends with exercises {Mỗi phần giải thích một mối đe dọa thật, cho xem code lỗ hổng, rồi cách sửa, và kết thúc bằng bài tập}.

Part 7 — Clickjacking & Framing locked down who may embed your UI with frame-ancestors and X-Frame-Options {Phần 7 khóa ai được nhúng UI bằng frame-ancestorsX-Frame-Options}. This part is the transport and header baseline: HTTPS everywhere, HSTS, the rest of the security header suite, and Subresource Integrity (SRI) so a compromised CDN cannot silently swap your scripts {Phần này là nền transport và header: HTTPS mọi nơi, HSTS, phần còn của bộ header bảo mật, và SRI để CDN bị xâm không đổi script lặng lẽ}. Most of these are HTTP response headers set at your host, CDN, or reverse proxy — not something you bolt on only in React {Phần lớn là header phản hồi HTTP set tại host, CDN, hoặc reverse proxy — không chỉ gắn trong React}.


HTTPS and TLS: the floor, not a feature {HTTPS và TLS: sàn, không phải tính năng}

TLS (what people still call “SSL”) gives you three properties on the wire between browser and server {TLS (người ta vẫn gọi “SSL”) cho ba tính chất trên đường truyền giữa trình duyệt và server}:

  1. Confidentiality — ciphertext on the network; passive observers cannot read bodies or cookies {Bảo mật nội dung — ciphertext trên mạng; kẻ nghe lén không đọc được body hay cookie}.
  2. Integrity — tampering is detected; an on-path attacker cannot silently replace your JS with malware {Toàn vẹn — sửa đổi bị phát hiện; attacker trên đường không thay JS của bạn bằng malware lặng lẽ}.
  3. Authentication — the certificate proves you reached the real host (modulo mis-issued certs and user mistakes) {Xác thực — chứng chỉ chứng minh bạn tới đúng host thật (trừ cert sai cấp và lỗi người dùng)}.

Without HTTPS, anyone on the same Wi‑Fi, ISP path, or compromised router can read and modify traffic — including injecting <script> into your HTML as it flies by {Không HTTPS, ai đó trên cùng Wi‑Fi, đường ISP, hay router bị xâm có thể đọc và sửa traffic — kể cả chèn <script> vào HTML trên đường}. Plain HTTP is obsolete for any site that handles logins, payments, PII, or admin tools; treat http:// as a redirect target only, never as the canonical app URL {HTTP thuần đã lỗi thời cho site có đăng nhập, thanh toán, PII, hay admin; coi http:// chỉ là đích redirect, không phải URL app chính thức}.

Browser TLS 🔒 response headers · Strict-Transport-Security· Content-Security-Policy· X-Content-Type-Options· Referrer-Policy· X-Frame-Options Server HTTPS everywhere + headers set the browser's security defaults
TLS encrypts the channel; response headers (HSTS, CSP, X-Content-Type-Options, …) set the browser's security defaults for every navigation

Frontend work still matters {Frontend vẫn quan trọng}: use relative URLs or https:// in markup, enable automatic HTTPS on your static host, and never ship http:// asset links on production pages {dùng URL tương đối hoặc https:// trong markup, bật HTTPS tự động trên static host, không ship link asset http:// trên production}.


HSTS: force HTTPS after the first visit {HSTS: ép HTTPS sau lần ghé đầu}

The first request to your site might still be http:// if the user typed the hostname, followed a bookmark, or hit a downgrade link {Lần request đầu tới site vẫn có thể là http:// nếu user gõ hostname, bookmark cũ, hay link downgrade}. HTTP Strict Transport Security (HSTS) tells the browser: for this host (and optionally subdomains), only use HTTPS for the next max-age seconds {HSTS bảo trình duyệt: với host này (và tùy chọn subdomain), chỉ dùng HTTPS trong max-age giây tới}.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
PieceRole {Vai trò}
max-ageHow long the browser remembers “HTTPS only” (often 1 year = 31536000) {Thời gian trình duyệt nhớ “chỉ HTTPS”}
includeSubDomainsApplies to api.example.com, cdn.example.com, etc. {Áp cho subdomain}
preloadEligible for browser preload lists baked into Chrome/Firefox/Safari — first visit never hits HTTP {Đủ điều kiện preload list trong trình duyệt — lần đầu không qua HTTP}

SSL stripping is the attack HSTS defeats: a network attacker intercepts your first http:// visit and proxies HTTP while speaking HTTPS upstream {SSL stripping là tấn công HSTS chặn: attacker chặn lần http:// đầu và proxy HTTP trong khi nói HTTPS phía trên}. With HSTS, compliant browsers upgrade or block before your login form loads over cleartext {Có HSTS, trình duyệt tuân thủ nâng cấp hoặc chặn trước khi form đăng nhập tải qua cleartext}.

Preload caveat {Lưu ý preload}: submitting to hstspreload.org is hard to undo — you must run HTTPS correctly on all listed hosts for months before removal propagates {gửi hstspreload.org khó hoàn tác — phải chạy HTTPS đúng trên mọi host trong danh sách hàng tháng trước khi gỡ lan rộng}. Only add preload when every subdomain is ready and you control TLS end-to-end {Chỉ thêm preload khi mọi subdomain sẵn sàng và bạn kiểm soát TLS end-to-end}.


Mixed content: HTTPS page, HTTP subresources {Mixed content: trang HTTPS, tài nguyên HTTP}

A page loaded over https:// must not pull active content over http:// {Trang tải qua https:// không được kéo nội dung active qua http://}. Browsers classify mixed content as blockable (scripts, stylesheets, iframes, XHR) or upgradeable/display (images, audio in modern modes) {Trình duyệt phân chặn được (script, stylesheet, iframe, XHR) hay nâng cấp/hiển thị (image, audio ở chế độ hiện đại)}.

Vulnerable pattern {Mẫu lỗ hổng} — hardcoded cleartext CDN:

<script src="http://cdn.example.com/lib.js"></script>
<link rel="stylesheet" href="http://cdn.example.com/app.css" />

Fix {Sửa}: protocol-relative is still wrong on HTTPS sites; use HTTPS or root-relative paths {URL theo protocol vẫn sai trên HTTPS; dùng HTTPS hoặc path tương đối gốc}:

<script src="https://cdn.example.com/lib.js"></script>
<link rel="stylesheet" href="/assets/app.css" />

Ship upgrade-insecure-requests inside CSP (see Part 3 — CSP) so legacy http:// links auto-upgrade where possible {Gửi upgrade-insecure-requests trong CSP (xem Phần 3) để link http:// cũ tự nâng cấp khi có thể}:

Content-Security-Policy: upgrade-insecure-requests; default-src 'self'

Audit with DevTools Issues panel and your CI HTML checker — mixed content failures often show up only in staging when someone copies an old embed URL {Audit bằng panel Issues DevTools và HTML checker CI — lỗi mixed content hay chỉ lộ ở staging khi ai đó copy URL embed cũ}.


The security header suite {Bộ header bảo mật}

These headers do not replace Part 3 CSP, Part 7 framing, or server-side validation — they stack independent browser-enforced defaults {Các header này không thay CSP Phần 3, framing Phần 7, hay validate server — chúng xếp chồng default trình duyệt độc lập}.

Content-Security-Policy (brief) {CSP (tóm tắt)}

CSP is your in-browser firewall for scripts, styles, frames, and network destinations — covered in depth in Part 3 — Content Security Policy {CSP là tường lửa trong trình duyệt cho script, style, frame, và đích mạng — chi tiết ở Phần 3}. Minimum production habit: default-src 'self', tight script-src with nonces or hashes, object-src 'none', and frame-ancestors aligned with Part 7 {Thói quen production tối thiểu: default-src 'self', script-src chặt với nonce/hash, object-src 'none', và frame-ancestors khớp Phần 7}.

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-PLACEHOLDER'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'

X-Content-Type-Options: nosniff {X-Content-Type-Options}

Stops the browser from MIME-sniffing a response into executable context (e.g. treating text/plain upload as HTML) {Chặn trình duyệt đoán MIME response thành ngữ cảnh thực thi (vd upload text/plain thành HTML)}.

X-Content-Type-Options: nosniff

Pair with correct Content-Type on downloads and APIs; nosniff is cheap and universally supported {Kèm Content-Type đúng trên download và API; nosniff rẻ và hỗ trợ rộng}.

Referrer-Policy {Referrer-Policy}

Controls how much of the previous URL (path, query, tokens in query) leaks on navigation and subresource requests {Điều khiển mức URL trước (path, query, token trong query) rò rỉ khi điều hướng và request tài nguyên phụ}.

Referrer-Policy: strict-origin-when-cross-origin

Same-origin navigations send full URL; cross-origin HTTPS sends origin only; downgrade to HTTP sends no referrer {Điều hướng same-origin gửi URL đầy đủ; cross-origin HTTPS chỉ gửi origin; hạ xuống HTTP không gửi referrer}. Tighter options (no-referrer, same-origin) help on OAuth return URLs and password-reset pages with secrets in the query string {Tùy chọn chặt hơn (no-referrer, same-origin) hữu ích trên URL OAuth và reset mật khẩu có secret trong query}.

Framing: X-Frame-Options and frame-ancestors {Framing}

Part 7 is the source of truth for clickjacking; deploy both modern CSP and legacy XFO during migration {Phần 7 là nguồn chính cho clickjacking; triển khai cả CSP hiện đại và XFO legacy khi migrate}:

Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY

Embed-only routes get a narrow allowlist on that route only — not a site-wide SAMEORIGIN if admin must stay DENY {Route chỉ embed dùng allowlist hẹp trên route đó — không SAMEORIGIN toàn site nếu admin phải DENY}.

Permissions-Policy {Permissions-Policy}

Formerly Feature-Policy — disables powerful APIs by default (camera, microphone, geolocation, payment, usb, …) unless you explicitly allow them {Trước là Feature-Policy — tắt API mạnh mặc định (camera, mic, geolocation, payment, usb, …) trừ khi bạn cho phép rõ}:

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

Use () to disable for all origins; self or (https://trusted.example) to allow narrowly {Dùng () để tắt mọi origin; self hoặc (https://trusted.example) để cho phép hẹp}. This complements CSP: CSP says what may load; Permissions-Policy says what may run inside the page {Bổ sung CSP: CSP nói thứ gì được nạp; Permissions-Policy nói thứ gì được chạy trong trang}.

Cross-origin isolation: COOP, COEP, CORP {Cô lập cross-origin}

Spectre-class attacks read memory across origins in the same process {Tấn công kiểu Spectre đọc bộ nhớ cross-origin trong cùng process}. Browsers mitigate with cross-origin isolation — a separate process (or tight boundary) so sensitive data is not colocated with attacker-controlled content {Trình duyệt giảm nhẹ bằng cô lập cross-origin — process riêng (hoặc biên chặt) để dữ liệu nhạy cảm không nằm cạnh nội dung attacker kiểm soát}.

HeaderPurpose {Mục đích}
Cross-Origin-Opener-Policy: same-originNew browsing contexts cannot retain a joint reference to your window across origins {Context duyệt mới không giữ tham chiếu chung tới cửa sổ bạn cross-origin}
Cross-Origin-Embedder-Policy: require-corpCross-origin resources must opt in via CORP or CORS, or they fail to load {Tài nguyên cross-origin phải opt-in qua CORP hoặc CORS, không thì không nạp}
Cross-Origin-Resource-Policy: same-originYour assets declare who may embed/consume them in cross-origin contexts {Asset khai báo ai được nhúng/tiêu thụ trong ngữ cảnh cross-origin}

When COOP + COEP are configured correctly, window.crossOriginIsolated === true and APIs like SharedArrayBuffer and high-resolution timers become available again under controlled rules {Khi COOP + COEP đúng, window.crossOriginIsolated === true và API như SharedArrayBuffer cùng timer độ phân giải cao lại khả dụng theo quy tắc kiểm soát}. This is advanced; only adopt when you need those APIs or explicit isolation — misconfigured COEP breaks third-party widgets that do not send CORP {Nâng cao; chỉ áp khi cần API đó hoặc cô lập rõ — COEP cấu hình sai gãy widget bên thứ ba không gửi CORP}.

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin

Cache-Control on sensitive responses {Cache-Control trên phản hồi nhạy cảm}

Browsers and CDNs can store authenticated HTML or JSON in disk cache — a shared device risk {Trình duyệt và CDN có thể lưu HTML hoặc JSON đã xác thực trên cache đĩa — rủi ro thiết bị dùng chung}. For account pages, tokens, and health data:

Cache-Control: no-store
Pragma: no-cache

Static marketing assets still use long max-age + immutable; split policies by route {Asset marketing tĩnh vẫn max-age dài + immutable; tách policy theo route}.


Subresource Integrity (SRI) {SRI}

A script tag from a CDN runs with your origin’s full privileges (Part 1) {Thẻ script từ CDN chạy với toàn quyền origin bạn (Phần 1)}. If the CDN account or path is compromised, the attacker swaps the file — SRI makes the browser hash the bytes and refuse mismatches {CDN hoặc path bị xâm, attacker đổi file — SRI bắt trình duyệt băm byte và từ chối lệch}.

<script
  src="https://cdn.example.com/lib/v3.2.1/app.min.js"
  integrity="sha384-PLACEHOLDER_BASE64_DIGEST"
  crossorigin="anonymous"
></script>

Generate digests at build time (openssl dgst -sha384 -binary file.js | openssl base64 -A or your bundler plugin) {Sinh digest lúc build (openssl dgst -sha384 -binary file.js | openssl base64 -A hoặc plugin bundler)}. crossorigin="anonymous" is required for CORS-enabled CDN fetches used in the integrity check {crossorigin="anonymous" bắt buộc cho fetch CDN bật CORS dùng trong kiểm integrity}. SRI does not help inline scripts — pair with CSP script-src hashes/nonces (Part 3). Supply-chain depth continues in Part 9 — Secrets, Data Leakage & Supply-Chain {SRI không giúp script inline — kèm CSP hash/nonce (Phần 3). Chuỗi supply-chain tiếp ở Phần 9}.


Consolidated example: static host _headers {Ví dụ gộp: _headers static host}

Many static hosts (Netlify, Cloudflare Pages, etc.) map a _headers or headers config file to response headers — same idea as nginx add_header or CDN rules {Nhiều static host (Netlify, Cloudflare Pages, v.v.) map file _headers hoặc config headers sang header phản hồi — giống add_header nginx hoặc rule CDN}. Several headers cannot be set reliably via <meta http-equiv> (including HSTS and, in practice, framing and isolation headers) — configure them on the edge {Vài header không set ổn qua <meta http-equiv> (gồm HSTS và thực tế framing/isolation) — cấu hình ở edge}.

/*
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=()
  Cross-Origin-Opener-Policy: same-origin
  X-Frame-Options: DENY
  Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-PLACEHOLDER'; style-src 'self' 'nonce-PLACEHOLDER'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; upgrade-insecure-requests
  Cache-Control: public, max-age=0, must-revalidate

/account/*
  Cache-Control: no-store
  Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-PLACEHOLDER'; frame-ancestors 'none'

Tune CSP per environment; start Content-Security-Policy-Report-Only before enforcing (Part 3) {Chỉnh CSP theo môi trường; bắt đầu Content-Security-Policy-Report-Only trước khi enforce (Phần 3)}.


Reporting and audit tooling {Báo cáo và công cụ audit}

Scan externally after deploy:

  • securityheaders.com — letter grade on common headers {điểm chữ trên header phổ biến}.
  • Mozilla Observatory — broader HTTP/TLS and header guidance {hướng dẫn HTTP/TLS và header rộng hơn}.

CSP violation reporting — send reports to your collector while in report-only mode {Báo cáo vi phạm CSP — gửi tới collector khi ở chế độ report-only}:

Content-Security-Policy-Report-Only: script-src 'self'; report-uri https://reports.example.com/csp

Modern stacks prefer Reporting-Endpoints + report-to (successor to legacy Report-To); check your CDN’s support before relying on it in production {Stack hiện đại ưu tiên Reporting-Endpoints + report-to (kế thừa Report-To cũ); kiểm tra CDN hỗ trợ trước khi phụ thuộc production}. Wire alerts on spikes — a sudden script-src violation often means XSS attempt or a bad deploy {Cảnh báo khi spike — vi phạm script-src đột ngột thường là thử XSS hoặc deploy lỗi}.


Frontend checklist {Checklist frontend}

Before you call the security series “deployed” {Trước khi coi series bảo mật “đã deploy”}:

  • Canonical URLs are https://; HTTP redirects 301 to HTTPS; HSTS enabled with sane max-age {URL chính là https://; HTTP redirect 301 sang HTTPS; HSTS bật với max-age hợp lý}.
  • No production http:// script, stylesheet, or iframe sources; CSP includes upgrade-insecure-requests where legacy URLs exist {Không có script/stylesheet/iframe http:// production; CSP có upgrade-insecure-requests nếu còn URL cũ}.
  • Header stack deployed at CDN/server, not only in framework meta tags {Stack header ở CDN/server, không chỉ meta framework}.
  • Part 3 CSP enforced (or report-only with monitoring); Part 7 framing on sensitive routes {CSP Phần 3 enforce (hoặc report-only có monitor); framing Phần 7 trên route nhạy cảm}.
  • CDN scripts use SRI + crossorigin; lockfiles and dependency review land in Part 9 {Script CDN có SRI + crossorigin; lockfile và review dependency ở Phần 9}.
  • Account and API JSON responses send Cache-Control: no-store where appropriate {Phản hồi account và API JSON gửi Cache-Control: no-store khi cần}.
  • Quarterly scan on securityheaders.com / Observatory after infra changes {Quét định kỳ securityheaders.com / Observatory sau đổi infra}.

Bài tập / Exercises

1. In one sentence each, what do TLS confidentiality, integrity, and authentication protect against on an open Wi‑Fi network? {Mỗi thứ một câu: confidentiality, integrity, authentication của TLS chống gì trên Wi‑Fi công cộng?}

Solution {Lời giải}

Confidentiality — observers cannot read your session cookie or response bodies {Confidentiality — kẻ nghe lén không đọc cookie phiên hay body phản hồi}. Integrity — an attacker cannot swap your JS bundle for malware without the browser detecting the break {Integrity — attacker không đổi bundle JS thành malware mà trình duyệt không phát hiện}. Authentication — you are talking to the server that owns the certificate for that hostname, not a trivial local impersonator {Authentication — bạn nói chuyện với server sở hữu cert cho hostname đó, không phải kẻ giả danh local tầm thường}.

2. Your site adds Strict-Transport-Security: max-age=31536000; includeSubDomains; preload but http://legacy.example.com still serves an admin panel over HTTP. What breaks, and what is the fix order? {Site thêm HSTS như trên nhưng http://legacy.example.com vẫn phục vụ admin qua HTTP. Gì hỏng, thứ tự sửa?}

Solution {Lời giải}

Browsers with HSTS (especially preload) refuse or upgrade legacy.example.com — the admin panel becomes unreachable or behaves inconsistently {Trình duyệt có HSTS (nhất preload) từ chối hoặc nâng cấp legacy.example.com — admin không vào được hoặc lệch hành vi}. Fix order: (1) serve HTTPS on legacy with valid cert, (2) verify all subdomains over HTTPS, (3) deploy HSTS without preload until stable, (4) only then consider preload submission {Thứ tự sửa: (1) HTTPS trên legacy với cert hợp lệ, (2) xác minh mọi subdomain qua HTTPS, (3) deploy HSTS không preload đến khi ổn, (4) mới cân nhắc preload}.

3. Add SRI to the CDN script below and list one CSP directive that still blocks inline attack if the CDN is clean but an XSS injects <script>alert(1)</script> {Thêm SRI cho script CDN dưới và nêu một directive CSP vẫn chặn inline nếu CDN sạch nhưng XSS chèn <script>alert(1)</script>}.

<script src="https://cdn.example.com/analytics.js"></script>
Solution {Lời giải}
<script
  src="https://cdn.example.com/analytics.js"
  integrity="sha384-PLACEHOLDER_DIGEST_FROM_BUILD"
  crossorigin="anonymous"
></script>

CSP example: script-src 'self' 'nonce-PLACEHOLDER' (or strict hashes) — blocks inline alert even when the external file hash matches {Ví dụ CSP: script-src 'self' 'nonce-PLACEHOLDER' — chặn inline alert dù file ngoài khớp hash}.

Stretch {Nâng cao}: Explain why Cross-Origin-Embedder-Policy: require-corp can break a third-party payment iframe, and name two headers from this post that Part 7 already used for a different threat. {Giải thích vì sao COEP require-corp có thể gãy iframe thanh toán bên thứ ba, và nêu hai header bài này mà Phần 7 đã dùng cho mối đe dọa khác.}

Solution {Lời giải}

COEP require-corp requires every cross-origin subresource (including nested frames) to send Cross-Origin-Resource-Policy or proper CORS; many payment widgets are legacy cross-origin embeds without CORP, so they fail to load under require-corp {COEP require-corp bắt mọi tài nguyên cross-origin (kể cả frame lồng) gửi CORP hoặc CORS đúng; nhiều widget thanh toán là embed cũ không CORP nên không nạp}. Part 7 already deployed frame-ancestors / X-Frame-Options against clickjacking — same header family, different goal than COEP isolation {Phần 7 đã dùng frame-ancestors / X-Frame-Options chống clickjacking — cùng họ header, mục tiêu khác cô lập COEP}. Content-Security-Policy frame-ancestors also appears in both parts — framing vs script/load rules {Content-Security-Policy frame-ancestors cũng xuất hiện ở hai phần — framing so với quy tắc script/nạp}.


Key takeaways {Điểm chính}

  • HTTPS/TLS is mandatory: confidentiality, integrity, and authentication; cleartext HTTP enables wire-tap and injection {HTTPS/TLS bắt buộc: confidentiality, integrity, authentication; HTTP cleartext cho nghe lén và injection}.
  • HSTS closes the first-visit downgrade window; preload is powerful and slow to undo {HSTS đóng cửa sổ downgrade lần đầu; preload mạnh và chậm hoàn tác}.
  • Mixed content and hardcoded http:// assets break HTTPS pages — use relative/https:// URLs and upgrade-insecure-requests {Mixed content và asset http:// hardcode phá trang HTTPS — dùng URL tương đối/https://upgrade-insecure-requests}.
  • Stack nosniff, Referrer-Policy, Permissions-Policy, CSP (Part 3), framing (Part 7), and Cache-Control: no-store on sensitive data {Xếp nosniff, Referrer-Policy, Permissions-Policy, CSP (Phần 3), framing (Phần 7), Cache-Control: no-store trên dữ liệu nhạy cảm}.
  • COOP/COEP/CORP enable cross-origin isolation and crossOriginIsolated — adopt deliberately; can break third-party embeds {COOP/COEP/CORP bật cô lập cross-origin và crossOriginIsolated — áp có chủ đích; có thể gãy embed bên thứ ba}.
  • SRI pins CDN script bytes; pair with CSP and Part 9 supply-chain habits {SRI ghim byte script CDN; kèm CSP và thói quen supply-chain Phần 9}.
  • Configure headers on the server/CDN (_headers, nginx, etc.); audit with securityheaders.com, Observatory, and CSP reporting {Cấu hình header trên server/CDN (_headers, nginx, v.v.); audit bằng securityheaders.com, Observatory, và báo cáo CSP}.

Next up {Tiếp theo}

Part 9 — Secrets, Data Leakage & Supply-Chain: env vars in client bundles, localStorage leaks, npm typosquatting, lockfiles, and making SRI + CSP part of a repeatable release pipeline {Phần 9 — Secrets, Data Leakage & Supply-Chain: biến môi trường trong bundle client, rò localStorage, typosquat npm, lockfile, và biến SRI + CSP thành pipeline release lặp lại}. Continue to Part 9 — Secrets, Data Leakage & Supply-Chain.