diff --git a/awx/ui_next/public/index.html b/awx/ui_next/public/index.html
index 59a709abbf..280c34a94e 100644
--- a/awx/ui_next/public/index.html
+++ b/awx/ui_next/public/index.html
@@ -7,7 +7,7 @@
<% } %>
diff --git a/awx/ui_next/src/setupCSP.js b/awx/ui_next/src/setupCSP.js
index ee4e2465ac..77d40c5775 100644
--- a/awx/ui_next/src/setupCSP.js
+++ b/awx/ui_next/src/setupCSP.js
@@ -3,3 +3,28 @@
// Set a special variable to add `nonce` attributes to all styles/script tags
// See https://github.com/webpack/webpack/pull/3210
__webpack_nonce__ = window.NONCE_ID;
+
+// Send report when a CSP violation occurs
+// See: https://w3c.github.io/webappsec-csp/2/#violation-reports
+// See: https://developer.mozilla.org/en-US/docs/Web/API/SecurityPolicyViolationEvent
+document.addEventListener('securitypolicyviolation', e => {
+ const violation = {
+ 'csp-report': {
+ 'blocked-uri': e.blockedURI,
+ 'document-uri': e.documentURI,
+ 'effective-directive': e.effectiveDirective,
+ 'original-policy': e.originalPolicy,
+ referrer: e.referrer,
+ 'status-code': e.statusCode,
+ 'violated-directive': e.violatedDirective,
+ },
+ };
+ if (e.sourceFile) violation['csp-report']['source-file'] = e.sourceFile;
+ if (e.lineNumber) violation['csp-report']['line-number'] = e.lineNumber;
+ if (e.columnNumber) violation['csp-report']['column-number'] = e.columnNumber;
+
+ const xhr = new XMLHttpRequest();
+ xhr.open('POST', '/csp-violation/', true);
+ xhr.setRequestHeader('content-type', 'application/csp-report');
+ xhr.send(JSON.stringify(violation));
+});