Skip to content

Commit 73d779a

Browse files
authored
fix(csp): added terms, privacy, & logo URLs to CSP (#1413)
1 parent 2578127 commit 73d779a

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

apps/sim/lib/security/csp.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@ import { env, getEnv } from '../env'
22

33
/**
44
* Content Security Policy (CSP) configuration builder
5-
* This creates a more maintainable and readable CSP configuration
65
*/
76

7+
function getHostnameFromUrl(url: string | undefined): string[] {
8+
if (!url) return []
9+
try {
10+
return [`https://${new URL(url).hostname}`]
11+
} catch {
12+
return []
13+
}
14+
}
15+
816
export interface CSPDirectives {
917
'default-src'?: string[]
1018
'script-src'?: string[]
@@ -43,7 +51,6 @@ export const buildTimeCSPDirectives: CSPDirectives = {
4351
'style-src': ["'self'", "'unsafe-inline'", 'https://fonts.googleapis.com'],
4452

4553
'img-src': [
46-
'https://agentics.epiqglobal.com',
4754
"'self'",
4855
'data:',
4956
'blob:',
@@ -66,6 +73,7 @@ export const buildTimeCSPDirectives: CSPDirectives = {
6673
: []),
6774
'https://*.amazonaws.com',
6875
'https://*.blob.core.windows.net',
76+
...getHostnameFromUrl(env.NEXT_PUBLIC_BRAND_LOGO_URL),
6977
],
7078

7179
'media-src': ["'self'", 'blob:'],
@@ -98,14 +106,12 @@ export const buildTimeCSPDirectives: CSPDirectives = {
98106
'https://*.vercel.app',
99107
'wss://*.vercel.app',
100108
'https://pro.ip-api.com',
109+
...getHostnameFromUrl(env.NEXT_PUBLIC_BRAND_LOGO_URL),
110+
...getHostnameFromUrl(env.NEXT_PUBLIC_PRIVACY_URL),
111+
...getHostnameFromUrl(env.NEXT_PUBLIC_TERMS_URL),
101112
],
102113

103-
// Google Picker and Drive integration
104-
'frame-src': [
105-
'https://drive.google.com',
106-
'https://docs.google.com', // Required for Google Picker
107-
'https://*.google.com',
108-
],
114+
'frame-src': ['https://drive.google.com', 'https://docs.google.com', 'https://*.google.com'],
109115

110116
'frame-ancestors': ["'self'"],
111117
'form-action': ["'self'"],
@@ -120,7 +126,6 @@ export function buildCSPString(directives: CSPDirectives): string {
120126
return Object.entries(directives)
121127
.map(([directive, sources]) => {
122128
if (!sources || sources.length === 0) return ''
123-
// Filter out empty strings
124129
const validSources = sources.filter((source: string) => source && source.trim() !== '')
125130
if (validSources.length === 0) return ''
126131
return `${directive} ${validSources.join(' ')}`
@@ -140,14 +145,23 @@ export function generateRuntimeCSP(): string {
140145
const appUrl = getEnv('NEXT_PUBLIC_APP_URL') || ''
141146
const ollamaUrl = getEnv('OLLAMA_URL') || 'http://localhost:11434'
142147

148+
const brandLogoDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_BRAND_LOGO_URL'))
149+
const privacyDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_PRIVACY_URL'))
150+
const termsDomains = getHostnameFromUrl(getEnv('NEXT_PUBLIC_TERMS_URL'))
151+
152+
const allDynamicDomains = [...brandLogoDomains, ...privacyDomains, ...termsDomains]
153+
const uniqueDynamicDomains = Array.from(new Set(allDynamicDomains))
154+
const dynamicDomainsStr = uniqueDynamicDomains.join(' ')
155+
const brandLogoDomain = brandLogoDomains[0] || ''
156+
143157
return `
144158
default-src 'self';
145159
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.google.com https://apis.google.com https://*.vercel-scripts.com https://*.vercel-insights.com https://vercel.live https://*.vercel.live https://vercel.com https://*.vercel.app https://vitals.vercel-insights.com https://b2bjsstore.s3.us-west-2.amazonaws.com;
146160
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
147-
img-src 'self' data: blob: https://*.googleusercontent.com https://*.google.com https://*.atlassian.com https://cdn.discordapp.com https://*.githubusercontent.com https://*.public.blob.vercel-storage.com;
161+
img-src 'self' data: blob: https://*.googleusercontent.com https://*.google.com https://*.atlassian.com https://cdn.discordapp.com https://*.githubusercontent.com https://*.public.blob.vercel-storage.com ${brandLogoDomain};
148162
media-src 'self' blob:;
149163
font-src 'self' https://fonts.gstatic.com;
150-
connect-src 'self' ${appUrl} ${ollamaUrl} ${socketUrl} ${socketWsUrl} https://*.up.railway.app wss://*.up.railway.app https://api.browser-use.com https://api.exa.ai https://api.firecrawl.dev https://*.googleapis.com https://*.amazonaws.com https://*.s3.amazonaws.com https://*.blob.core.windows.net https://*.vercel-insights.com https://vitals.vercel-insights.com https://*.atlassian.com https://*.supabase.co https://vercel.live https://*.vercel.live https://vercel.com https://*.vercel.app wss://*.vercel.app https://pro.ip-api.com;
164+
connect-src 'self' ${appUrl} ${ollamaUrl} ${socketUrl} ${socketWsUrl} https://*.up.railway.app wss://*.up.railway.app https://api.browser-use.com https://api.exa.ai https://api.firecrawl.dev https://*.googleapis.com https://*.amazonaws.com https://*.s3.amazonaws.com https://*.blob.core.windows.net https://*.vercel-insights.com https://vitals.vercel-insights.com https://*.atlassian.com https://*.supabase.co https://vercel.live https://*.vercel.live https://vercel.com https://*.vercel.app wss://*.vercel.app https://pro.ip-api.com ${dynamicDomainsStr};
151165
frame-src https://drive.google.com https://docs.google.com https://*.google.com;
152166
frame-ancestors 'self';
153167
form-action 'self';

0 commit comments

Comments
 (0)