From 3ff7ce78e782c7d28c8b5a1a3f40a1de897d89a1 Mon Sep 17 00:00:00 2001 From: Ted Johansson Date: Wed, 19 Jun 2024 11:11:35 +0800 Subject: [PATCH] FEATURE: Add hidden site setting to list 'unsafe-none' COOP referrers (#27510) Some tooling may rely on an unsafe-none cross origin opener policy to work. This change adds a hidden site setting that can be used to list referrers where we add this header instead of the default one configured in cross_origin_opener_policy_header. --- app/controllers/application_controller.rb | 9 +++++- config/site_settings.yml | 4 +++ spec/requests/application_controller_spec.rb | 29 ++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d44e28105ae..c5f613d9aa7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1008,7 +1008,14 @@ class ApplicationController < ActionController::Base end def set_cross_origin_opener_policy_header - response.headers["Cross-Origin-Opener-Policy"] = SiteSetting.cross_origin_opener_policy_header + response.headers["Cross-Origin-Opener-Policy"] = if SiteSetting + .cross_origin_opener_unsafe_none_referrers + .split("|") + .include?(request.referrer&.split("://")&.last) + "unsafe-none" + else + SiteSetting.cross_origin_opener_policy_header + end end protected diff --git a/config/site_settings.yml b/config/site_settings.yml index cd693788114..c77fb42eaaa 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -2052,6 +2052,10 @@ security: - "same-origin" - "same-origin-allow-popups" hidden: true + cross_origin_opener_unsafe_none_referrers: + default: "" + type: host_list + hidden: true onebox: post_onebox_maxlength: diff --git a/spec/requests/application_controller_spec.rb b/spec/requests/application_controller_spec.rb index 621db5936df..a1167032c11 100644 --- a/spec/requests/application_controller_spec.rb +++ b/spec/requests/application_controller_spec.rb @@ -547,6 +547,35 @@ RSpec.describe ApplicationController do expect(response.headers["Cross-Origin-Opener-Policy"]).to eq("unsafe-none") end end + + describe "when `cross_origin_unsafe_none_referrers` site setting has been set" do + before do + SiteSetting.cross_origin_opener_policy_header = "same-origin" + SiteSetting.cross_origin_opener_unsafe_none_referrers = + "meta.discourse.org|try.discourse.org" + end + + it "sets `Cross-Origin-Opener-Policy` to `unsafe-none` for a listed referrer" do + get "/latest", headers: { "HTTP_REFERER" => "meta.discourse.org" } + + expect(response.status).to eq(200) + expect(response.headers["Cross-Origin-Opener-Policy"]).to eq("unsafe-none") + end + + it "sets `Cross-Origin-Opener-Policy` to configured value for a non-listed referrer" do + get "/latest", headers: { "HTTP_REFERER" => "www.discourse.org" } + + expect(response.status).to eq(200) + expect(response.headers["Cross-Origin-Opener-Policy"]).to eq("same-origin") + end + + it "sets `Cross-Origin-Opener-Policy` to configured value when referrer is missing" do + get "/latest" + + expect(response.status).to eq(200) + expect(response.headers["Cross-Origin-Opener-Policy"]).to eq("same-origin") + end + end end describe "splash_screen" do