Skip to content

Commit e189370

Browse files
apognuChibiBlasphem
authored andcommitted
Add CSP config for Firebase, Metabase and the API.
1 parent aa239a7 commit e189370

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

packages/app-builder/src/entry.server.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { PassThrough } from 'stream';
1313

1414
import { initServerServices } from './services/init.server';
1515
import { captureUnexpectedRemixError } from './services/monitoring';
16-
import { checkEnv, getServerEnv } from './utils/environment';
16+
import { checkEnv, getClientEnvVars, getServerEnv } from './utils/environment';
1717
import { NonceProvider } from './utils/nonce';
1818

1919
const ABORT_DELAY = 70000;
@@ -120,16 +120,29 @@ function handleBrowserRequest(
120120

121121
responseHeaders.set('Content-Type', 'text/html');
122122

123+
const clientEnv = getClientEnvVars();
124+
const firebaseUrl = clientEnv.FIREBASE_CONFIG.withEmulator
125+
? clientEnv.FIREBASE_CONFIG.authEmulatorUrl
126+
: 'https://identitytoolkit.googleapis.com';
127+
128+
const externalDomains = ['cdn.segment.com', 'api.segment.io', '*.sentry.io'];
129+
123130
const cspOrigins = [
131+
['base-uri', "'none'"],
124132
['default-src', "'self'"],
125133
['frame-ancestors', "'none'"],
126134
['object-src', "'none'"],
127-
['style-src', "'self' 'unsafe-inline'"],
128-
['script-src', `'self' 'nonce-${nonce}' 'unsafe-eval' https://cdn.segment.com`],
129-
['connect-src', "'self' localhost:9099"],
130-
['frame-src', `https://subdomain.metabaseapp.com`],
135+
['style-src', "'self' 'unsafe-inline'"], // unsafe-inline seems to trigger a lot of errors, even though it did not seem to break the UI.
136+
['script-src', `'nonce-${nonce}' 'unsafe-eval' 'strict-dynamic'`], // unsafe-eval seems to be required by lottie.js for home page animations.
137+
[
138+
'connect-src',
139+
`'self' ${clientEnv.MARBLE_API_URL} ${firebaseUrl} ${externalDomains.map((d) => `https://${d}`).join(' ')}`,
140+
],
141+
['img-src', "'self' data:"],
131142
];
132143

144+
if (clientEnv.METABASE_URL) cspOrigins.push(['frame-src', clientEnv.METABASE_URL]);
145+
133146
responseHeaders.set(
134147
'content-security-policy',
135148
cspOrigins.flatMap((rule) => rule.join(' ')).join('; '),

packages/app-builder/src/utils/environment.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ const PublicEnvVarsSchema = z.object({
2727
MARBLE_API_URL_SERVER: z.string(),
2828
MARBLE_APP_URL: z.string(),
2929

30+
METABASE_URL: z.string().optional(),
31+
3032
FIREBASE_AUTH_EMULATOR_HOST: z.string().optional(),
3133
FIREBASE_API_KEY: z.string(),
3234
FIREBASE_APP_ID: z.string().optional(),
@@ -87,6 +89,7 @@ interface ServerEnvVars {
8789
MARBLE_API_URL_SERVER: string;
8890
MARBLE_APP_URL: string;
8991
FIREBASE_CONFIG: FirebaseConfig;
92+
METABASE_URL?: string;
9093
SENTRY_DSN?: string;
9194
SENTRY_ENVIRONMENT?: string;
9295
SEGMENT_WRITE_KEY?: string;
@@ -117,6 +120,7 @@ interface ClientEnvVars {
117120
MARBLE_APP_URL: string;
118121
SENTRY_DSN?: string;
119122
SENTRY_ENVIRONMENT?: string;
123+
METABASE_URL?: string;
120124
}
121125
export function getClientEnvVars(): ClientEnvVars {
122126
return {
@@ -126,6 +130,7 @@ export function getClientEnvVars(): ClientEnvVars {
126130
MARBLE_APP_URL: getServerEnv('MARBLE_APP_URL'),
127131
SENTRY_DSN: getServerEnv('SENTRY_DSN'),
128132
SENTRY_ENVIRONMENT: getServerEnv('SENTRY_ENVIRONMENT'),
133+
METABASE_URL: getServerEnv('METABASE_URL'),
129134
};
130135
}
131136

0 commit comments

Comments
 (0)