diff --git a/awx/main/views.py b/awx/main/views.py index 6cf27c0476..13230d0846 100644 --- a/awx/main/views.py +++ b/awx/main/views.py @@ -1,14 +1,20 @@ # Copyright (c) 2015 Ansible, Inc. # All Rights Reserved. +import json + # Django +from django.http import HttpResponse from django.shortcuts import render from django.utils.html import format_html from django.utils.translation import ugettext_lazy as _ +from django.views.decorators.csrf import csrf_exempt # Django REST Framework from rest_framework import exceptions, permissions, views +import logging + def _force_raising_exception(view_obj, request, format=None): raise view_obj.exception_class() @@ -84,3 +90,10 @@ def handle_500(request): 'content': _('A server error has occurred.'), } return handle_error(request, 500, **kwargs) + + +@csrf_exempt +def handle_csp_violation(request): + logger = logging.getLogger('awx') + logger.error(json.loads(request.body)) + return HttpResponse(content=None) diff --git a/awx/urls.py b/awx/urls.py index b14a750554..d16ccdf67c 100644 --- a/awx/urls.py +++ b/awx/urls.py @@ -8,6 +8,7 @@ from awx.main.views import ( handle_403, handle_404, handle_500, + handle_csp_violation, ) @@ -20,6 +21,7 @@ urlpatterns = [ url(r'^(?:api/)?403.html$', handle_403), url(r'^(?:api/)?404.html$', handle_404), url(r'^(?:api/)?500.html$', handle_500), + url(r'^csp-violation/', handle_csp_violation), ] if settings.SETTINGS_MODULE == 'awx.settings.development': diff --git a/installer/roles/image_build/templates/nginx.conf.j2 b/installer/roles/image_build/templates/nginx.conf.j2 index a0f23698cb..f8dae89610 100644 --- a/installer/roles/image_build/templates/nginx.conf.j2 +++ b/installer/roles/image_build/templates/nginx.conf.j2 @@ -61,6 +61,8 @@ http { # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) add_header Strict-Transport-Security max-age=15768000; + add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' cdn.pendo.io; report-uri /csp-violation/"; + add_header X-Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' cdn.pendo.io; report-uri /csp-violation/"; # Protect against click-jacking https://www.owasp.org/index.php/Testing_for_Clickjacking_(OTG-CLIENT-009) add_header X-Frame-Options "DENY"; diff --git a/tools/docker-compose/nginx.vh.default.conf b/tools/docker-compose/nginx.vh.default.conf index 73a4d1cd8d..c677ab4e01 100644 --- a/tools/docker-compose/nginx.vh.default.conf +++ b/tools/docker-compose/nginx.vh.default.conf @@ -22,6 +22,8 @@ server { # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) add_header Strict-Transport-Security max-age=15768000; + add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' cdn.pendo.io; report-uri /csp-violation/"; + add_header X-Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' cdn.pendo.io; report-uri /csp-violation/"; location /static/ { root /awx_devel; @@ -82,6 +84,8 @@ server { # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) add_header Strict-Transport-Security max-age=15768000; + add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' cdn.pendo.io; report-uri /csp-violation/"; + add_header X-Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' cdn.pendo.io; report-uri /csp-violation/"; location /static/ { root /awx_devel;