mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
155 lines
6.0 KiB
Ruby
155 lines
6.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#-- copyright
|
|
# OpenProject is an open source project management software.
|
|
# Copyright (C) the OpenProject GmbH
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License version 3.
|
|
#
|
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
|
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
# Copyright (C) 2010-2013 the ChiliProject Team
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# See COPYRIGHT and LICENSE files for more details.
|
|
#++
|
|
|
|
# Be sure to restart your server when you modify this file.
|
|
|
|
# Define an application-wide content security policy.
|
|
# 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|
|
|
# Valid for assets
|
|
assets_src = ["'self'"]
|
|
asset_host = OpenProject::Configuration.rails_asset_host
|
|
assets_src << asset_host if asset_host.present?
|
|
|
|
# Valid for iframes
|
|
frame_src = []
|
|
frame_src << OpenProject::Configuration[:security_badge_url] if OpenProject::Configuration[:security_badge_displayed]
|
|
|
|
# Default src
|
|
default_src = %w('self') # rubocop:disable Lint/PercentStringArray
|
|
|
|
# Attachment uploaders
|
|
default_src += OpenProject::Configuration.remote_storage_hosts
|
|
|
|
# Chargebee self-service
|
|
chargebee_src = ["https://*.chargebee.com"]
|
|
|
|
assets_src += chargebee_src
|
|
frame_src += chargebee_src
|
|
default_src += chargebee_src
|
|
|
|
# Allow requests to CLI in dev mode
|
|
connect_src = default_src + [OpenProject::Configuration.enterprise_trial_creation_host]
|
|
|
|
# Allow connections to asset host for source maps
|
|
connect_src << asset_host if asset_host.present?
|
|
|
|
# Rules for media (e.g. video sources)
|
|
media_src = default_src
|
|
media_src << asset_host if asset_host.present?
|
|
# Getting started video
|
|
onboarding = Addressable::URI.parse(OpenProject::Static::Links.url_for(:onboarding_video_url))
|
|
media_src << "#{onboarding.scheme}://#{onboarding.host}"
|
|
enterprise_video = Addressable::URI.parse(OpenProject::Static::Links.url_for(:enterprise_welcome_video))
|
|
media_src << "#{enterprise_video.scheme}://#{enterprise_video.host}"
|
|
media_src.uniq!
|
|
|
|
if OpenProject::Configuration.appsignal_frontend_key
|
|
connect_src += ["https://appsignal-endpoint.net"]
|
|
end
|
|
|
|
# Add proxy configuration for Angular CLI to csp
|
|
if FrontendAssetHelper.assets_proxied?
|
|
proxied = ["ws://#{Setting.host_name}", "http://#{Setting.host_name}",
|
|
FrontendAssetHelper.cli_proxy.sub("http", "ws"), FrontendAssetHelper.cli_proxy]
|
|
connect_src += proxied
|
|
assets_src += proxied
|
|
media_src += proxied
|
|
end
|
|
|
|
# Allow to extend the script-src in specific situations
|
|
script_src = assets_src + %w(js.chargebee.com)
|
|
|
|
# Allow unsafe-eval for rack-mini-profiler
|
|
if Rails.env.development? && ENV.fetch("OPENPROJECT_RACK_PROFILER_ENABLED", false)
|
|
script_src += %w('unsafe-eval') # rubocop:disable Lint/PercentStringArray
|
|
end
|
|
|
|
# Allow ANDI bookmarklet to run in development mode
|
|
# https://www.ssa.gov/accessibility/andi/help/install.html
|
|
if Rails.env.development?
|
|
script_src += ["https://www.ssa.gov"]
|
|
assets_src += ["https://www.ssa.gov"]
|
|
end
|
|
|
|
form_action = default_src
|
|
|
|
# Allow test s3 bucket for direct uploads in tests
|
|
if Rails.env.test?
|
|
connect_src += ["test-bucket.s3.amazonaws.com"]
|
|
form_action += ["test-bucket.s3.amazonaws.com"]
|
|
end
|
|
|
|
# Allow connections to S3 for BIM
|
|
if OpenProject::Configuration.fog_directory.present?
|
|
connect_src += [OpenProject::Configuration.fog_s3_upload_host]
|
|
form_action += [OpenProject::Configuration.fog_s3_upload_host]
|
|
end
|
|
|
|
# Configure CSP directives
|
|
policy.default_src(*default_src)
|
|
policy.base_uri("'self'")
|
|
policy.font_src(*assets_src, "data:")
|
|
policy.form_action(*form_action)
|
|
policy.frame_src(*frame_src, "'self'")
|
|
policy.frame_ancestors("'self'")
|
|
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'")
|
|
policy.object_src(OpenProject::Configuration[:security_badge_url])
|
|
policy.connect_src(*connect_src)
|
|
policy.media_src(*media_src)
|
|
end
|
|
|
|
# Generate session nonces for permitted importmap, inline scripts, and inline styles.
|
|
# This handles Turbo integration natively
|
|
config.content_security_policy_nonce_generator = lambda do |request|
|
|
# Use Turbo nonce if available (for Turbo navigation)
|
|
if request.env["HTTP_TURBO_REFERRER"].present? && request.env["HTTP_X_TURBO_NONCE"].present?
|
|
request.env["HTTP_X_TURBO_NONCE"]
|
|
else
|
|
# Generate a new nonce based on session
|
|
SecureRandom.base64(16)
|
|
end
|
|
end
|
|
|
|
config.content_security_policy_nonce_directives = %w(script-src)
|
|
end
|
|
end
|
|
# rubocop:enable Lint/PercentStringArray
|