mirror of
https://github.com/discourse/discourse.git
synced 2026-08-05 18:57:20 -05:00
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:
@@ -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
|
||||
@@ -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."
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user