diff --git a/packages/cloud/src/middleware/with-security-headers.ts b/packages/cloud/src/middleware/with-security-headers.ts index 3f531cc83..647638a54 100644 --- a/packages/cloud/src/middleware/with-security-headers.ts +++ b/packages/cloud/src/middleware/with-security-headers.ts @@ -1,6 +1,7 @@ import type { IncomingMessage, ServerResponse } from 'node:http'; import { promisify } from 'node:util'; +import { conditionalArray } from '@silverhand/essentials'; import type { NextFunction, HttpContext, RequestContext } from '@withtyped/server'; import helmet, { type HelmetOptions } from 'helmet'; @@ -34,7 +35,8 @@ export default function withSecurityHeaders const adminOrigins = adminUrlSet.origins; const cloudOrigins = cloudUrlSet.origins; const urlSetOrigins = urlSet.origins; - const developmentOrigins = isProduction ? [] : ['ws:']; + const developmentOrigins = conditionalArray(!isProduction && 'ws:'); + const appInsightsOrigins = ['https://*.applicationinsights.azure.com']; return async ( context: InputContext, @@ -96,6 +98,7 @@ export default function withSecurityHeaders ...cloudOrigins, ...urlSetOrigins, ...developmentOrigins, + ...appInsightsOrigins, ], frameSrc: ["'self'", ...urlSetOrigins], }, diff --git a/packages/core/src/middleware/koa-security-headers.ts b/packages/core/src/middleware/koa-security-headers.ts index 9d78be95b..fc972fa8a 100644 --- a/packages/core/src/middleware/koa-security-headers.ts +++ b/packages/core/src/middleware/koa-security-headers.ts @@ -2,6 +2,7 @@ import { type IncomingMessage, type ServerResponse } from 'node:http'; import { promisify } from 'node:util'; import { defaultTenantId } from '@logto/schemas'; +import { conditionalArray } from '@silverhand/essentials'; import helmet, { type HelmetOptions } from 'helmet'; import type { MiddlewareType } from 'koa'; @@ -33,12 +34,13 @@ export default function koaSecurityHeaders( const { isProduction, isCloud, isMultiTenancy, adminUrlSet, cloudUrlSet } = EnvSet.values; const adminOrigins = adminUrlSet.origins; - const cloudOrigins = isCloud ? cloudUrlSet.origins : []; + const cloudOrigins = conditionalArray(isCloud && cloudUrlSet.origins); const tenantEndpointOrigin = getTenantEndpoint( isMultiTenancy ? tenantId : defaultTenantId, EnvSet.values ).origin; - const developmentOrigins = isProduction ? [] : ['ws:']; + const developmentOrigins = conditionalArray(!isProduction && 'ws:'); + const appInsightsOrigins = ['https://*.applicationinsights.azure.com']; /** * Default Applied rules: @@ -80,7 +82,13 @@ export default function koaSecurityHeaders( 'upgrade-insecure-requests': null, imgSrc: ["'self'", 'data:', 'https:'], scriptSrc: ["'self'", "'unsafe-eval'", "'unsafe-inline'"], - connectSrc: ["'self'", ...adminOrigins, ...cloudOrigins, ...developmentOrigins], + connectSrc: [ + "'self'", + ...adminOrigins, + ...cloudOrigins, + ...developmentOrigins, + ...appInsightsOrigins, + ], // WARNING: high risk Need to allow self hosted terms of use page loaded in an iframe frameSrc: ["'self'", 'https:'], // Alow loaded by console preview iframe