fix: API Helmet — allow cross-origin for frontend consumption
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 11s
Deploy / Build API Image (push) Failing after 18s
Deploy / Build AI Services Image (push) Failing after 9s
E2E Tests / Playwright E2E (push) Failing after 11s
Deploy / Smoke Test Staging (push) Has been skipped
CI / E2E Tests (push) Has been skipped
Deploy / Build Web Image (push) Failing after 8s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped

crossOriginResourcePolicy: 'same-origin' blocks browser fetch from
platform.goodgo.vn to api.goodgo.vn. Changed to 'cross-origin'.
Also disabled crossOriginEmbedderPolicy which conflicts with CORS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ho Ngoc Hai
2026-04-14 23:53:50 +07:00
parent b9ad280192
commit a394bb3139

View File

@@ -61,13 +61,14 @@ async function bootstrap() {
// ── Security Headers (Helmet) ── // ── Security Headers (Helmet) ──
app.use( app.use(
helmet({ helmet({
// CSP relaxed for API — responses are consumed cross-origin by the web frontend
contentSecurityPolicy: { contentSecurityPolicy: {
directives: { directives: {
defaultSrc: ["'self'"], defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", 'https://cdn.jsdelivr.net'], scriptSrc: ["'self'", "'unsafe-inline'", 'https://cdn.jsdelivr.net'],
styleSrc: ["'self'", "'unsafe-inline'", 'https://cdn.jsdelivr.net'], styleSrc: ["'self'", "'unsafe-inline'", 'https://cdn.jsdelivr.net'],
imgSrc: ["'self'", 'data:', 'https:', 'blob:'], imgSrc: ["'self'", 'data:', 'https:', 'blob:'],
connectSrc: ["'self'", 'https://cdn.jsdelivr.net'], connectSrc: ["'self'", 'https://cdn.jsdelivr.net', 'https://api.goodgo.vn'],
fontSrc: ["'self'", 'data:'], fontSrc: ["'self'", 'data:'],
objectSrc: ["'none'"], objectSrc: ["'none'"],
frameSrc: ["'none'"], frameSrc: ["'none'"],
@@ -75,9 +76,10 @@ async function bootstrap() {
formAction: ["'self'"], formAction: ["'self'"],
}, },
}, },
crossOriginEmbedderPolicy: true, // Must allow cross-origin for API consumed by platform.goodgo.vn
crossOriginOpenerPolicy: true, crossOriginEmbedderPolicy: false,
crossOriginResourcePolicy: { policy: 'same-origin' }, crossOriginOpenerPolicy: false,
crossOriginResourcePolicy: { policy: 'cross-origin' },
frameguard: { action: 'deny' }, frameguard: { action: 'deny' },
hsts: { maxAge: 31536000, includeSubDomains: true, preload: true }, hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
referrerPolicy: { policy: 'strict-origin-when-cross-origin' }, referrerPolicy: { policy: 'strict-origin-when-cross-origin' },