Class: Gitlab::ContentSecurityPolicy::ConfigLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/content_security_policy/config_loader.rb

Constant Summary collapse

DIRECTIVES =
%w(base_uri child_src connect_src default_src font_src
form_action frame_ancestors frame_src img_src manifest_src
media_src object_src report_uri script_src style_src worker_src).freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(csp_directives) ⇒ ConfigLoader

Returns a new instance of ConfigLoader.


63
64
65
# File 'lib/gitlab/content_security_policy/config_loader.rb', line 63

def initialize(csp_directives)
  @csp_directives = HashWithIndifferentAccess.new(csp_directives)
end

Class Method Details

.default_directivesObject


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/gitlab/content_security_policy/config_loader.rb', line 14

def self.default_directives
  directives = {
    'default_src' => "'self'",
    'base_uri' => "'self'",
    'connect_src' => ContentSecurityPolicy::Directives.connect_src,
    'font_src' => "'self'",
    'form_action' => "'self' https: http:",
    'frame_ancestors' => "'self'",
    'frame_src' => ContentSecurityPolicy::Directives.frame_src,
    'img_src' => "'self' data: blob: http: https:",
    'manifest_src' => "'self'",
    'media_src' => "'self' data:",
    'script_src' => ContentSecurityPolicy::Directives.script_src,
    'style_src' => "'self' 'unsafe-inline'",
    'worker_src' => "#{Gitlab::Utils.append_path(Gitlab.config.gitlab.url, 'assets/')} blob: data:",
    'object_src' => "'none'",
    'report_uri' => nil
  }

  # connect_src with 'self' includes https/wss variations of the origin,
  # however, safari hasn't covered this yet and we need to explicitly add
  # support for websocket origins until Safari catches up with the specs
  if Rails.env.development?
    allow_webpack_dev_server(directives)
    allow_letter_opener(directives)
    allow_snowplow_micro(directives) if Gitlab::Tracking.snowplow_micro_enabled?
  end

  allow_websocket_connections(directives)
  allow_cdn(directives, Settings.gitlab.cdn_host) if Settings.gitlab.cdn_host.present?
  allow_sentry(directives) if Gitlab.config.sentry&.enabled && Gitlab.config.sentry&.clientside_dsn
  allow_framed_gitlab_paths(directives)
  allow_customersdot(directives) if ENV['CUSTOMER_PORTAL_URL'].present?

  # The follow section contains workarounds to patch Safari's lack of support for CSP Level 3
  # See https://gitlab.com/gitlab-org/gitlab/-/issues/343579
  # frame-src was deprecated in CSP level 2 in favor of child-src
  # CSP level 3 "undeprecated" frame-src and browsers fall back on child-src if it's missing
  # However Safari seems to read child-src first so we'll just keep both equal
  append_to_directive(directives, 'child_src', directives['frame_src'])

  # Safari also doesn't support worker-src and only checks child-src
  # So for compatibility until it catches up to other browsers we need to
  # append worker-src's content to child-src
  append_to_directive(directives, 'child_src', directives['worker_src'])

  directives
end

.default_enabledObject


10
11
12
# File 'lib/gitlab/content_security_policy/config_loader.rb', line 10

def self.default_enabled
  Rails.env.development? || Rails.env.test?
end

Instance Method Details

#load(policy) ⇒ Object


67
68
69
70
71
72
73
74
75
# File 'lib/gitlab/content_security_policy/config_loader.rb', line 67

def load(policy)
  DIRECTIVES.each do |directive|
    arguments = arguments_for(directive)

    next unless arguments.present?

    policy.public_send(directive, *arguments) # rubocop:disable GitlabSecurity/PublicSend
  end
end