DEV: Remove CSP report collection endpoint and setting (#37903)

This is no longer useful since we've implemented `strict-dynamic` in our
CSP.
This commit is contained in:
Penar Musaraj
2026-02-19 08:51:32 -05:00
committed by GitHub
parent e3abc79046
commit df08e1a479
7 changed files with 1 additions and 166 deletions
-49
View File
@@ -1,49 +0,0 @@
# frozen_string_literal: true
class CspReportsController < ApplicationController
skip_before_action :check_xhr, :preload_json, :verify_authenticity_token, only: [:create]
def create
raise Discourse::NotFound unless report_collection_enabled?
report = parse_report
if report.blank?
render_json_error("empty CSP report", status: 422)
else
Logster.add_to_env(request.env, "CSP Report", report)
Rails.logger.warn("CSP Violation: '#{report["blocked-uri"]}' \n\n#{report["script-sample"]}")
head :ok
end
rescue JSON::ParserError
render_json_error("invalid CSP report", status: 422)
end
private
def parse_report
obj = JSON.parse(request.body.read)
if Hash === obj
obj = obj["csp-report"]
if Hash === obj
obj.slice(
"blocked-uri",
"disposition",
"document-uri",
"effective-directive",
"original-policy",
"referrer",
"script-sample",
"status-code",
"violated-directive",
"line-number",
"source-file",
)
end
end
end
def report_collection_enabled?
SiteSetting.content_security_policy_collect_reports
end
end
-1
View File
@@ -1919,7 +1919,6 @@ en:
llms_txt: "Upload a text file to be served at /llms.txt for LLM crawlers. See <a href='https://llmstxt.org/' target='_blank'>llmstxt.org</a> for more information."
content_security_policy: "Enable Content-Security-Policy (CSP). CSP is an additional layer of security that helps to prevent certain types of attacks, including Cross Site Scripting (XSS) and data injection."
content_security_policy_report_only: "Enable Content-Security-Policy-Report-Only (CSP)"
content_security_policy_collect_reports: "Enable CSP violation report collection at /csp_reports"
content_security_policy_frame_ancestors: "Restrict who can embed this site in iframes via CSP. Control allowed hosts on <a href='%{base_path}/admin/customize/embedding'>Embedding</a>"
content_security_policy_script_src: "Additional allowlisted script sources. The current host and CDN are included by default. See <a href='https://meta.discourse.org/t/mitigate-xss-attacks-with-content-security-policy/104243' target='_blank'>Mitigate XSS Attacks with Content Security Policy.</a> (CSP). Other host sources are ignored as strict-dynamic is enabled."
invalidate_inactive_admin_email_after_days: "Admin accounts that have not visited the site in this number of days will need to re-validate their email address before logging in. Set to 0 to disable."
-2
View File
@@ -1878,8 +1878,6 @@ Discourse::Application.routes.draw do
post "/push_notifications/subscribe" => "push_notification#subscribe"
post "/push_notifications/unsubscribe" => "push_notification#unsubscribe"
resources :csp_reports, only: [:create]
get "/permalink-check", to: "permalinks#check"
post "/do-not-disturb" => "do_not_disturb#create"
-3
View File
@@ -2751,9 +2751,6 @@ security:
default: true
content_security_policy_report_only:
default: false
content_security_policy_collect_reports:
default: false
hidden: true
content_security_policy_frame_ancestors:
default: true
content_security_policy_script_src:
+1 -11
View File
@@ -14,9 +14,6 @@ class ContentSecurityPolicy
directives[:object_src] = [:none]
directives[:script_src] = script_src
directives[:worker_src] = []
directives[
:report_uri
] = report_uri if SiteSetting.content_security_policy_collect_reports
directives[:frame_ancestors] = frame_ancestors if restrict_embed?
directives[:manifest_src] = ["'self'"]
end
@@ -60,14 +57,7 @@ class ContentSecurityPolicy
end
def script_src
sources = ["'strict-dynamic'"]
sources << :report_sample if SiteSetting.content_security_policy_collect_reports
sources
end
def report_uri
"#{base_url}/csp_reports"
["'strict-dynamic'"]
end
def frame_ancestors
-18
View File
@@ -2,18 +2,6 @@
RSpec.describe ContentSecurityPolicy do
after { DiscoursePluginRegistry.reset! }
describe "report-uri" do
it "is enabled by SiteSetting" do
SiteSetting.content_security_policy_collect_reports = true
report_uri = parse(policy)["report-uri"].first
expect(report_uri).to eq("http://test.localhost/csp_reports")
SiteSetting.content_security_policy_collect_reports = false
report_uri = parse(policy)["report-uri"]
expect(report_uri).to eq(nil)
end
end
describe "base-uri" do
it "is set to self" do
base_uri = parse(policy)["base-uri"]
@@ -50,12 +38,6 @@ RSpec.describe ContentSecurityPolicy do
worker_src = parse(policy)["worker-src"]
expect(worker_src).to eq(nil)
end
it 'includes "report-sample" when report collection is enabled' do
SiteSetting.content_security_policy_collect_reports = true
script_srcs = parse(policy)["script-src"]
expect(script_srcs).to include("'report-sample'")
end
end
describe "manifest-src" do
@@ -1,82 +0,0 @@
# frozen_string_literal: true
RSpec.describe CspReportsController do
describe "#create" do
let(:fake_logger) { FakeLogger.new }
before do
SiteSetting.content_security_policy = true
SiteSetting.content_security_policy_collect_reports = true
Rails.logger.broadcast_to(fake_logger)
end
after { Rails.logger.stop_broadcasting_to(fake_logger) }
def send_report
post "/csp_reports",
params: {
"csp-report": {
"document-uri": "http://localhost:3000/",
referrer: "",
"violated-directive": "script-src",
"effective-directive": "script-src",
"original-policy":
"script-src 'unsafe-eval' www.google-analytics.com; report-uri /csp_reports",
disposition: "report",
"blocked-uri": "http://suspicio.us/assets.js",
"line-number": 25,
"source-file": "http://localhost:3000/",
"status-code": 200,
"script-sample": "console.log('unsafe')",
},
}.to_json,
headers: {
"Content-Type": "application/csp-report",
}
end
it "returns an error for invalid reports" do
SiteSetting.content_security_policy_collect_reports = true
post "/csp_reports",
params: "[ not-json",
headers: {
"Content-Type": "application/csp-report",
}
expect(response.status).to eq(422)
post "/csp_reports",
params: ["yes json"].to_json,
headers: {
"Content-Type": "application/csp-report",
}
expect(response.status).to eq(422)
end
it "is enabled by SiteSetting" do
SiteSetting.content_security_policy = false
SiteSetting.content_security_policy_report_only = false
SiteSetting.content_security_policy_collect_reports = true
send_report
expect(response.status).to eq(200)
SiteSetting.content_security_policy = true
send_report
expect(response.status).to eq(200)
SiteSetting.content_security_policy_collect_reports = false
send_report
expect(response.status).to eq(404)
end
it "logs the violation report" do
send_report
expect(fake_logger.warnings).to include(
"CSP Violation: 'http://suspicio.us/assets.js' \n\nconsole.log('unsafe')",
)
end
end
end