From dcb80ac25038ce810805c9e7436a9f2e43ba2a3a Mon Sep 17 00:00:00 2001 From: Ben Busby Date: Sun, 7 Mar 2021 14:04:05 -0500 Subject: [PATCH] Send CSP header in all responses Introduces a new content security policy header for responses to all requests to reduce the possibility of ip leaks to outside connections. By default blocks all inline scripts, and only allows content loaded from Whoogle. Refactors a few small inline scripting cases in the project to their own individual scripts. --- app/__init__.py | 7 +++++++ app/routes.py | 22 +++++++++++++++------- app/static/js/header.js | 11 +++++++++++ app/static/js/utils.js | 8 ++++---- app/templates/error.html | 2 +- app/templates/header.html | 12 +----------- app/templates/index.html | 6 ------ 7 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 app/static/js/header.js diff --git a/app/__init__.py b/app/__init__.py index 13350a1..d5da4f5 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -40,6 +40,13 @@ app.config['BANG_PATH'] = os.getenv( app.config['BANG_FILE'] = os.path.join( app.config['BANG_PATH'], 'bangs.json') +app.config['CSP'] = 'default-src \'none\';' \ + 'img-src \'self\';' \ + 'style-src \'self\' \'unsafe-inline\';' \ + 'script-src \'self\';' \ + 'media-src \'self\';' \ + 'connect-src \'self\';' \ + 'form-action \'self\';' if not os.path.exists(app.config['CONFIG_PATH']): os.makedirs(app.config['CONFIG_PATH']) diff --git a/app/routes.py b/app/routes.py index f822b5e..acb38a6 100644 --- a/app/routes.py +++ b/app/routes.py @@ -87,7 +87,7 @@ def before_request_func(): @app.after_request -def after_request_func(response): +def after_request_func(resp): if app.user_elements[session['uuid']] <= 0 and '/element' in request.url: # Regenerate element key if all elements have been served to user session['fernet_keys'][ @@ -108,7 +108,11 @@ def after_request_func(response): for key in session_list: session.pop(key) - return response + resp.headers['Content-Security-Policy'] = app.config['CSP'] + if os.environ.get('HTTPS_ONLY', False): + resp.headers['Content-Security-Policy'] += 'upgrade-insecure-requests' + + return resp @app.errorhandler(404) @@ -122,15 +126,17 @@ def unknown_page(e): def index(): # Reset keys session['fernet_keys'] = generate_user_keys(g.cookies_disabled) - error_message = session[ - 'error_message'] if 'error_message' in session else '' - session['error_message'] = '' + + # Redirect if an error was raised + if 'error_message' in session and session['error_message']: + error_message = session['error_message'] + session['error_message'] = '' + return render_template('error.html', error_message=error_message) return render_template('index.html', languages=app.config['LANGUAGES'], countries=app.config['COUNTRIES'], config=g.user_config, - error_message=error_message, tor_available=int(os.environ.get('TOR_AVAILABLE')), version_number=app.config['VERSION_NUMBER']) @@ -286,7 +292,9 @@ def url(): if len(q) > 0 and 'http' in q: return redirect(q) else: - return render_template('error.html', query=q) + return render_template( + 'error.html', + error_message='Unable to resolve query: ' + q) @app.route('/imgres') diff --git a/app/static/js/header.js b/app/static/js/header.js new file mode 100644 index 0000000..02d8581 --- /dev/null +++ b/app/static/js/header.js @@ -0,0 +1,11 @@ +document.addEventListener("DOMContentLoaded", () => { + const searchBar = document.getElementById("search-bar"); + + searchBar.addEventListener("keyup", function (event) { + if (event.keyCode !== 13) { + handleUserInput(searchBar); + } else { + document.getElementById("search-form").submit(); + } + }); +}); diff --git a/app/static/js/utils.js b/app/static/js/utils.js index 775e072..56e052f 100644 --- a/app/static/js/utils.js +++ b/app/static/js/utils.js @@ -28,7 +28,7 @@ const checkForTracking = () => { /^[0-9]{15}$/ ] } - } + }; // Creates a link to a UPS/USPS/FedEx tracking page const createTrackingLink = href => { @@ -37,7 +37,7 @@ const checkForTracking = () => { link.innerHTML = "View Tracking Info"; link.href = href; mainDiv.prepend(link); - } + }; // Compares the query against a set of regex patterns // for tracking numbers @@ -48,12 +48,12 @@ const checkForTracking = () => { return true; } }); - } + }; for (const key of Object.keys(matchTracking)) { compareQuery(matchTracking[key]); } -} +}; document.addEventListener("DOMContentLoaded", function() { checkForTracking(); diff --git a/app/templates/error.html b/app/templates/error.html index 9546e23..efa3f79 100644 --- a/app/templates/error.html +++ b/app/templates/error.html @@ -1,6 +1,6 @@

Error


- Error parsing "{{ query }}" + Error: "{{ error_message|safe }}"

Return Home diff --git a/app/templates/header.html b/app/templates/header.html index 7ae980f..5c8da25 100644 --- a/app/templates/header.html +++ b/app/templates/header.html @@ -48,14 +48,4 @@ {% endif %} - + diff --git a/app/templates/index.html b/app/templates/index.html index a308e0d..de306f9 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -36,12 +36,6 @@ Whoogle Search -