-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnext.config.ts
More file actions
165 lines (153 loc) · 4.57 KB
/
next.config.ts
File metadata and controls
165 lines (153 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import { withSentryConfig } from "@sentry/nextjs";
import type { NextConfig } from "next";
/**
* Content Security Policy (CSP) Configuration
*
* This CSP is designed to be secure while allowing the application to function:
* - Google Tag Manager and Analytics for tracking (consent-gated)
* - Google Fonts for typography
* - KaTeX for math rendering (requires unsafe-inline for styles)
* - Framer Motion animations
*
* Note: 'unsafe-inline' for script-src is required for GTM's inline consent
* initialization script. This is a known tradeoff for GTM integration.
* Consider using nonce-based CSP in the future if stricter requirements arise.
*/
const ContentSecurityPolicy = `
default-src 'self';
script-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://www.google-analytics.com https://ssl.google-analytics.com https://*.sentry.io;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
img-src 'self' data: https: blob:;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self' https://www.googletagmanager.com https://www.google-analytics.com https://analytics.google.com https://region1.google-analytics.com https://*.ingest.sentry.io https://*.sentry.io;
frame-src 'self' https://www.googletagmanager.com;
frame-ancestors 'self' https://dineshd.dev https://*.dineshd.dev http://localhost:3000 http://localhost:3001;
base-uri 'self';
form-action 'self';
object-src 'none';
upgrade-insecure-requests;
`
.replace(/\s{2,}/g, " ")
.trim();
/**
* Permissions Policy (formerly Feature Policy)
*
* Restricts access to browser features to minimize attack surface.
* This application does not require camera, microphone, geolocation, etc.
*/
const PermissionsPolicy = [
"camera=()",
"microphone=()",
"geolocation=()",
"browsing-topics=()",
"interest-cohort=()",
"payment=()",
"usb=()",
"magnetometer=()",
"gyroscope=()",
"accelerometer=()",
].join(", ");
/**
* Security Headers Configuration
*
* Applied to all routes for defense-in-depth protection:
* - CSP: Prevents XSS and injection attacks
* - HSTS: Enforces HTTPS connections
* - X-Content-Type-Options: Prevents MIME type sniffing
* - CSP frame-ancestors: Prevents clickjacking (allows embedding from portfolio)
* - X-XSS-Protection: Legacy XSS filter (deprecated but still useful for older browsers)
* - Referrer-Policy: Controls referrer information sent with requests
* - Permissions-Policy: Restricts browser feature access
*/
const securityHeaders = [
{
key: "Content-Security-Policy",
value: ContentSecurityPolicy,
},
{
key: "Strict-Transport-Security",
value: "max-age=31536000; includeSubDomains; preload",
},
{
key: "X-Content-Type-Options",
value: "nosniff",
},
{
key: "X-XSS-Protection",
value: "1; mode=block",
},
{
key: "Referrer-Policy",
value: "strict-origin-when-cross-origin",
},
{
key: "Permissions-Policy",
value: PermissionsPolicy,
},
];
const nextConfig: NextConfig = {
/**
* Security Headers
*
* Applied globally to all routes. These headers provide defense-in-depth
* against common web vulnerabilities including XSS, clickjacking, and
* MIME type confusion attacks.
*/
async headers() {
return [
{
source: "/:path*",
headers: securityHeaders,
},
];
},
/**
* Powered By Header
*
* Disabled to prevent information disclosure about the framework version.
* This makes fingerprinting the application slightly harder.
*/
poweredByHeader: false,
/**
* Strict Mode
*
* Enables React Strict Mode for additional runtime checks during development.
* This helps identify potential problems early.
*/
reactStrictMode: true,
};
/**
* Sentry Configuration
*
* Wraps the Next.js config with Sentry for:
* - Automatic source map uploading
* - Error tracking integration
* - Performance monitoring
*/
export default withSentryConfig(nextConfig, {
// Sentry organization and project
org: "dinbuilds",
project: "yield",
// Suppress source map upload logs during build
silent: !process.env.CI,
// Upload source maps for better stack traces
// Requires SENTRY_AUTH_TOKEN environment variable
widenClientFileUpload: true,
// Configure source maps upload
sourcemaps: {
deleteSourcemapsAfterUpload: true,
},
// Tunnel Sentry events to avoid ad blockers (optional)
// tunnelRoute: "/monitoring",
// Webpack-specific Sentry options
webpack: {
// Automatically tree-shake Sentry logger statements
treeshake: {
removeDebugLogging: true,
},
// Enable React component annotations for better error context
reactComponentAnnotation: {
enabled: true,
},
},
});