Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,10 @@ services:
- "traefik.http.routers.web-frontend.rule=PathPrefix(`/`)"
- "traefik.http.routers.web-frontend.priority=1"
- "traefik.http.services.web-frontend.loadbalancer.server.port=80"
# Enable browser profiling for Datadog RUM
# See: https://docs.datadoghq.com/real_user_monitoring/correlate_with_other_telemetry/profiling/browser_profiling/
- "traefik.http.middlewares.document-policy.headers.customresponseheaders.Document-Policy=js-profiling"
- "traefik.http.routers.web-frontend.middlewares=document-policy"

sticker-award:
build:
Expand Down
81 changes: 80 additions & 1 deletion shared/infra/aws/lib/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
AllowedMethods,
CachePolicy,
Distribution,
HeadersFrameOption,
HeadersReferrerPolicy,
OriginAccessIdentity,
OriginProtocolPolicy,
OriginRequestPolicy,
Expand All @@ -43,6 +45,7 @@ import {
} from "aws-cdk-lib/aws-cloudfront-origins";
import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
import { Dns } from "./dns";
import { Duration } from "aws-cdk-lib";

export interface NetworkProps {
env: string;
Expand Down Expand Up @@ -161,7 +164,82 @@ export class Network extends Construct {
comment: `OAI for stickerlandia web frontend ${props.env}`,
});
webFrontendBucket.grantRead(originIdentity);


const corsWithTracingHeadersPolicy = new ResponseHeadersPolicy(
this,
"CorsWithTracingHeadersPolicy",
{
responseHeadersPolicyName: `Stickerlandia-CORS-Tracing-${props.env}`,
comment:
"CORS policy with W3C Trace Context and Datadog headers for RUM-APM correlation",
// Enable browser profiling for Datadog RUM
// See: https://docs.datadoghq.com/real_user_monitoring/correlate_with_other_telemetry/profiling/browser_profiling/
customHeadersBehavior: {
customHeaders: [
{
header: "Document-Policy",
value: "js-profiling",
override: true,
},
],
},
corsBehavior: {
accessControlAllowCredentials: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid wildcard origin when allowing credentials

This CORS policy enables accessControlAllowCredentials: true while also allowing origin *, which produces an invalid credentialed CORS response (Access-Control-Allow-Origin: * with credentials) and causes browsers to reject cross-origin requests that include cookies or auth credentials. In environments where the frontend is fetched cross-origin with credentials, those requests will fail despite this policy intending to improve telemetry/correlation behavior.

Useful? React with 👍 / 👎.

accessControlAllowHeaders: [
"Content-Type",
"Authorization",
"Accept",
// W3C Trace Context headers for distributed tracing
"traceparent",
"tracestate",
// Datadog-specific headers for RUM-APM correlation
"x-datadog-trace-id",
"x-datadog-parent-id",
"x-datadog-origin",
"x-datadog-sampling-priority",
],
accessControlAllowMethods: [
"GET",
"POST",
"PUT",
"DELETE",
"PATCH",
"OPTIONS",
],
accessControlAllowOrigins: [
`*`, // Allow all origins for development
],
accessControlExposeHeaders: [
// Allow browser to read trace headers from responses
"traceparent",
"tracestate",
"x-datadog-trace-id",
"x-datadog-parent-id",
],
accessControlMaxAge: Duration.hours(1),
originOverride: true,
},
securityHeadersBehavior: {
contentTypeOptions: { override: true },
frameOptions: {
frameOption: HeadersFrameOption.SAMEORIGIN,
override: true,
},
referrerPolicy: {
referrerPolicy:
HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN,
override: true,
},
strictTransportSecurity: {
accessControlMaxAge: Duration.days(365),
includeSubdomains: true,
override: true,
},
xssProtection: { protection: true, modeBlock: true, override: true },
},
},
);

this.distribution = new Distribution(this, `Stickerlandia-${props.env}`, {
certificate: props.dns.certificate,
domainNames: props.dns.getPrimaryDomainName(props.env)
Expand All @@ -188,6 +266,7 @@ export class Network extends Construct {
origin: S3BucketOrigin.withOriginAccessIdentity(webFrontendBucket, {
originAccessIdentity: originIdentity,
}),
responseHeadersPolicy: corsWithTracingHeadersPolicy,
},
});

Expand Down
Loading