diff --git a/ambuda/__init__.py b/ambuda/__init__.py index 7dc76c59..8172a2ed 100644 --- a/ambuda/__init__.py +++ b/ambuda/__init__.py @@ -12,6 +12,7 @@ from dotenv import load_dotenv from flask import Flask, session from flask_babel import Babel, pgettext +from flask_talisman import Talisman from sentry_sdk.integrations.flask import FlaskIntegration from sqlalchemy import exc @@ -93,6 +94,23 @@ def create_app(config_env: str): app = Flask(__name__) + csp = { + "default-src": ["'self'"], + "script-src": [ + "'self'", + "https://cdn.jsdelivr.net", + "https://www.google.com", + "https://www.gstatic.com", + "https://plausible.io", + "'unsafe-eval'", + ], + "frame-src": ["https://www.google.com"], + "img-src": ["'self'", "data:"], + "style-src": ["'self'", "'unsafe-inline'"], + } + + Talisman(app, content_security_policy=csp, force_https=config_env != config.TESTING) + # Config app.config.from_object(config_spec) diff --git a/ambuda/static/js/proofer.js b/ambuda/static/js/proofer.js index 663a15ac..007d6ad7 100644 --- a/ambuda/static/js/proofer.js +++ b/ambuda/static/js/proofer.js @@ -64,6 +64,8 @@ export default () => ({ this.loadSettings(); this.layoutClasses = this.getLayoutClasses(); + const IMAGE_URL = JSON.parse(document.getElementById('image_url').innerText); + // Set `imageZoom` only after the viewer is fully initialized. this.imageViewer = initializeImageViewer(IMAGE_URL); this.imageViewer.addHandler('open', () => { diff --git a/ambuda/templates/header-main-footer.html b/ambuda/templates/header-main-footer.html index ee0e5b4d..07689a93 100644 --- a/ambuda/templates/header-main-footer.html +++ b/ambuda/templates/header-main-footer.html @@ -7,7 +7,7 @@ {# Load scripts before Alpine so that our init hooks are properly set up. #} - + {% endblock %} diff --git a/ambuda/templates/proofing/create-project-post.html b/ambuda/templates/proofing/create-project-post.html index 0ba126ff..1987b7fe 100644 --- a/ambuda/templates/proofing/create-project-post.html +++ b/ambuda/templates/proofing/create-project-post.html @@ -23,7 +23,4 @@

Create new project

- - {% endblock %} diff --git a/ambuda/templates/proofing/pages/edit.html b/ambuda/templates/proofing/pages/edit.html index a40c3249..fc212520 100644 --- a/ambuda/templates/proofing/pages/edit.html +++ b/ambuda/templates/proofing/pages/edit.html @@ -82,7 +82,5 @@ {% set image_url = url_for("site.page_image", project_slug=project.slug, page_slug=cur.slug) %} - + {% endblock %} diff --git a/requirements.txt b/requirements.txt index d8d6f3f7..88a6ab42 100644 --- a/requirements.txt +++ b/requirements.txt @@ -35,6 +35,7 @@ Flask-Babel==2.0.0 Flask-Bcrypt==1.0.1 Flask-Login==0.6.1 Flask-Mail==0.9.1 +flask-talisman==1.0.0 Flask-WTF==1.0.1 fonttools==4.33.3 gevent==21.12.0 diff --git a/test/js/proofer.test.js b/test/js/proofer.test.js index 8d2b3dab..274844e2 100644 --- a/test/js/proofer.test.js +++ b/test/js/proofer.test.js @@ -5,12 +5,12 @@ const sampleHTML = `
+ `; // Can't modify existing `window.location` -- delete it so that we can mock it. // (See beforeEach and the tests below.) delete window.location; -window.IMAGE_URL = 'IMAGE_URL'; window.OpenSeadragon = (_) => ({ addHandler: jest.fn((_, callback) => callback()), viewport: {