mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Allow overriding the default wide img-src content security policy
https://community.openproject.org/projects/openproject/work_packages/74648/activity
This commit is contained in:
@@ -957,6 +957,13 @@ module Settings
|
||||
writable: false,
|
||||
description: "Host the frontend uses to download files, which has to be added to the CSP."
|
||||
},
|
||||
# Content Security Policy
|
||||
csp_img_src: {
|
||||
format: :array,
|
||||
default: %w(* data: blob:),
|
||||
writable: false,
|
||||
description: "Allowed sources for the CSP img-src directive."
|
||||
},
|
||||
report_incoming_email_errors: {
|
||||
description: "Respond to incoming mails with error details",
|
||||
default: true
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
# See the Securing Rails Applications Guide for more information:
|
||||
# https://guides.rubyonrails.org/security.html#content-security-policy-header
|
||||
|
||||
# rubocop:disable Lint/PercentStringArray
|
||||
Rails.application.config.after_initialize do
|
||||
Rails.application.configure do
|
||||
config.content_security_policy do |policy|
|
||||
@@ -125,7 +126,9 @@ Rails.application.config.after_initialize do
|
||||
policy.form_action(*form_action)
|
||||
policy.frame_src(*frame_src, "'self'")
|
||||
policy.frame_ancestors("'self'")
|
||||
policy.img_src("*", "data:", "blob:")
|
||||
img_src = %w('self') + Array(OpenProject::Configuration.csp_img_src)
|
||||
img_src << asset_host if asset_host.present?
|
||||
policy.img_src(*img_src.compact.uniq)
|
||||
policy.script_src(*script_src)
|
||||
policy.script_src_attr("'none'")
|
||||
policy.style_src(*assets_src, "'unsafe-inline'")
|
||||
@@ -149,3 +152,4 @@ Rails.application.config.after_initialize do
|
||||
config.content_security_policy_nonce_directives = %w(script-src)
|
||||
end
|
||||
end
|
||||
# rubocop:enable Lint/PercentStringArray
|
||||
|
||||
@@ -715,6 +715,26 @@ To disable rendering the badge, uncheck the setting at Administration > Syste
|
||||
OPENPROJECT_SECURITY__BADGE__DISPLAYED="false"
|
||||
```
|
||||
|
||||
### Content Security Policy image sources
|
||||
|
||||
Configure the allowed sources for the `img-src` CSP directive.
|
||||
|
||||
*default: `["*", "data:", "blob:"]`*
|
||||
|
||||
OpenProject always adds `'self'` and `rails_asset_host` (if configured) to `img-src` automatically, so same-origin and asset-hosted images remain allowed even if not listed in this setting.
|
||||
|
||||
Example to only allow secure remote images (plus data/blob):
|
||||
|
||||
```yaml
|
||||
OPENPROJECT_CSP__IMG__SRC="https: data: blob:"
|
||||
```
|
||||
|
||||
Example to restrict to specific hosts:
|
||||
|
||||
```yaml
|
||||
OPENPROJECT_CSP__IMG__SRC="https://cdn.example.com https://images.example.com data: blob:"
|
||||
```
|
||||
|
||||
### Cache configuration options
|
||||
|
||||
|
||||
|
||||
@@ -180,6 +180,7 @@ OPENPROJECT_COST__REPORTING__CACHE__FILTER__CLASSES (default=true)
|
||||
OPENPROJECT_COSTS__CURRENCY (default="EUR") Currency
|
||||
OPENPROJECT_COSTS__CURRENCY__FORMAT (default="%n %u") Format of currency
|
||||
OPENPROJECT_CROSS__PROJECT__WORK__PACKAGE__RELATIONS (default=true) Allow cross-project work package relations
|
||||
OPENPROJECT_CSP__IMG__SRC (default=["*", "data:", "blob:"]) Allowed sources for the CSP img-src directive.
|
||||
OPENPROJECT_DATABASE__CIPHER__KEY (default=nil) Encryption key for repository credentials
|
||||
OPENPROJECT_DATE__FORMAT (default=nil) Date
|
||||
OPENPROJECT_DAYS__PER__MONTH (default=20) This will define what is considered a “month” when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months.
|
||||
|
||||
@@ -74,5 +74,19 @@ RSpec.describe "" do
|
||||
csp = parse_csp(last_response.headers["Content-Security-Policy"])
|
||||
expect(csp["font-src"].count("'self'")).to eq(1)
|
||||
end
|
||||
|
||||
it "includes 'self' in img-src CSP directive" do
|
||||
get "/"
|
||||
|
||||
csp = parse_csp(last_response.headers["Content-Security-Policy"])
|
||||
expect(csp["img-src"]).to include("'self'")
|
||||
end
|
||||
|
||||
it "does not duplicate 'self' in img-src CSP directive" do
|
||||
get "/"
|
||||
|
||||
csp = parse_csp(last_response.headers["Content-Security-Policy"])
|
||||
expect(csp["img-src"].count("'self'")).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user