summaryrefslogtreecommitdiff
path: root/lib/gitlab/content_security_policy/config_loader.rb
blob: b2f3345d33a65b2f6d39241dcb4e8f22bf8fcf72 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
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
# frozen_string_literal: true

module Gitlab
  module ContentSecurityPolicy
    class ConfigLoader
      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 script_src style_src worker_src).freeze

      def self.default_settings_hash
        {
          'enabled' => false,
          'report_only' => false,
          'directives' => DIRECTIVES.each_with_object({}) { |directive, hash| hash[directive] = nil }
        }
      end

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

      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

      private

      def arguments_for(directive)
        arguments = @csp_directives[directive.to_s]

        return unless arguments.present? && arguments.is_a?(String)

        arguments.strip.split(' ').map(&:strip)
      end
    end
  end
end