Skip to content

Commit 2691126

Browse files
authored
Settings: bring CSP settings from -ops (#12199)
Closes readthedocs/readthedocs-ops#1502
1 parent f2e997c commit 2691126

File tree

1 file changed

+102
-9
lines changed

1 file changed

+102
-9
lines changed

readthedocs/settings/base.py

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,6 @@ def SHOW_DEBUG_TOOLBAR(self):
127127
SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin"
128128
X_FRAME_OPTIONS = "DENY"
129129

130-
# Content Security Policy
131-
# https://django-csp.readthedocs.io/
132-
CSP_DEFAULT_SRC = None # This could be improved
133-
CSP_FRAME_ANCESTORS = ("'none'",)
134-
CSP_OBJECT_SRC = ("'none'",)
135-
CSP_REPORT_URI = None
136-
CSP_REPORT_ONLY = False
137-
CSP_EXCLUDE_URL_PREFIXES = ("/admin/",)
138-
RTD_CSP_UPDATE_HEADERS = {}
139130

140131
# Read the Docs
141132
READ_THE_DOCS_EXTENSIONS = ext
@@ -403,6 +394,108 @@ def MIDDLEWARE(self):
403394
]
404395
PYTHON_MEDIA = False
405396

397+
# Content Security Policy
398+
# https://django-csp.readthedocs.io/
399+
CSP_FRAME_ANCESTORS = ("'none'",)
400+
CSP_REPORT_URI = None
401+
CSP_REPORT_ONLY = False
402+
403+
# Default to disallow everything, and then allow specific sources on each directive.
404+
CSP_DEFAULT_SRC = ["'none'"]
405+
CSP_IMG_SRC = [
406+
"'self'",
407+
# Some of our styles include images as data URLs.
408+
"data:",
409+
# We load avatars from GitHub, GitLab, and Bitbucket,
410+
# and other services. They don't use a single specific domain,
411+
# so we just allow any https domain here.
412+
"https:",
413+
]
414+
CSP_BASE_URI = ["'self'"]
415+
CSP_FRAME_SRC = [
416+
# Stripe (used for Gold subscriptions)
417+
"https://js.stripe.com/",
418+
]
419+
RTD_CSP_UPDATE_HEADERS = {}
420+
421+
@property
422+
def CSP_CONNECT_SRC(self):
423+
CSP_CONNECT_SRC = [
424+
"'self'",
425+
# Allow sentry to report errors.
426+
"https://*.ingest.us.sentry.io",
427+
# Allow fontawesome to load.
428+
"https://ka-p.fontawesome.com",
429+
"https://kit.fontawesome.com",
430+
# Plausible analytics
431+
"https://plausible.io/api/event",
432+
]
433+
CSP_CONNECT_SRC.append(f"ws://{self.PRODUCTION_DOMAIN}:10001/ws")
434+
return CSP_CONNECT_SRC
435+
436+
@property
437+
def CSP_SCRIPT_SRC(self):
438+
CSP_SCRIPT_SRC = [
439+
"'self'",
440+
# Some of our JS deps are using eval.
441+
"'unsafe-eval'",
442+
# Allow fontawesome to load.
443+
"https://kit.fontawesome.com",
444+
# Stripe (used for Gold subscriptions)
445+
"https://js.stripe.com/",
446+
]
447+
CSP_SCRIPT_SRC.append(self.STATIC_URL)
448+
if self.RTD_EXT_THEME_DEV_SERVER:
449+
CSP_SCRIPT_SRC.append(self.RTD_EXT_THEME_DEV_SERVER)
450+
return CSP_SCRIPT_SRC
451+
452+
@property
453+
def CSP_FONT_SRC(self):
454+
CSP_FONT_SRC = [
455+
"'self'",
456+
# Allow fontawesome to load.
457+
"data:",
458+
"https://ka-p.fontawesome.com",
459+
]
460+
CSP_FONT_SRC.append(self.STATIC_URL)
461+
if self.RTD_EXT_THEME_DEV_SERVER:
462+
CSP_FONT_SRC.append(self.RTD_EXT_THEME_DEV_SERVER)
463+
return CSP_FONT_SRC
464+
465+
@property
466+
def CSP_STYLE_SRC(self):
467+
CSP_STYLE_SRC = [
468+
"'self'",
469+
# We have lots of inline styles!
470+
# TODO: we should remove this.
471+
"'unsafe-inline'",
472+
]
473+
CSP_STYLE_SRC.append(self.STATIC_URL)
474+
if self.RTD_EXT_THEME_DEV_SERVER:
475+
CSP_STYLE_SRC.append(self.RTD_EXT_THEME_DEV_SERVER)
476+
return CSP_STYLE_SRC
477+
478+
@property
479+
def CSP_FORM_ACTION(self):
480+
CSP_FORM_ACTION = [
481+
"'self'",
482+
# Chrome and Safari block form submissions if it redirects to a different domain.
483+
# We redirect to external domains for some forms, like login.
484+
"https://github.com",
485+
"https://gitlab.com",
486+
"https://bitbucket.org",
487+
"https://id.atlassian.com",
488+
"https://accounts.google.com",
489+
# We also redirect to Stripe on subscription forms.
490+
"https://billing.stripe.com",
491+
"https://checkout.stripe.com",
492+
]
493+
# Allow our support form to submit to external domains.
494+
if self.SUPPORT_FORM_ENDPOINT:
495+
CSP_FORM_ACTION.append(self.SUPPORT_FORM_ENDPOINT)
496+
return CSP_FORM_ACTION
497+
498+
406499
# Django Storage subclass used to write build artifacts to cloud or local storage
407500
# https://docs.readthedocs.io/page/development/settings.html#rtd-build-media-storage
408501
RTD_BUILD_MEDIA_STORAGE = "readthedocs.builds.storage.BuildMediaFileSystemStorage"

0 commit comments

Comments
 (0)