Class: BetterContentSecurityPolicy::ContentSecurityPolicy
- Inherits:
-
Object
- Object
- BetterContentSecurityPolicy::ContentSecurityPolicy
- Defined in:
- lib/better_content_security_policy/content_security_policy.rb
Overview
DSL for building a Content Security Policy. An instance of this class will be available in your controllers and views. You can call a method multiple times to add additional rules to the policy.
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 prefetch-src require-trusted-types-for script-src script-src-attr script-src-elem style-src style-src-attr style-src-elem trusted-types worker-src ].freeze
- SCHEME_SOURCES =
%w[ blob data filesystem http https mediastream ws wss ].freeze
- QUOTED_SOURCES =
%w[ none self unsafe-eval unsafe-hashes unsafe-inline allow-duplicates report-sample script strict-dynamic ].freeze
Instance Attribute Summary collapse
-
#directives ⇒ Object
Returns the value of attribute directives.
-
#report_only ⇒ Object
Returns the value of attribute report_only.
-
#report_uri ⇒ Object
Returns the value of attribute report_uri.
Instance Method Summary collapse
-
#csp_source(dsl_source) ⇒ Object
Converts sources from our Ruby DSL (camelcase) into proper Content-Security-Policy sources.
- #header_name ⇒ Object
-
#initialize ⇒ ContentSecurityPolicy
constructor
A new instance of ContentSecurityPolicy.
-
#method_missing(directive_sym, *args) ⇒ Object
Handles directive methods, such as #script_src and #style_src.
- #report_only? ⇒ Boolean
- #respond_to_missing?(directive, include_all = false) ⇒ Boolean
- #to_h ⇒ Object
- #to_s ⇒ Object
- #valid_directive?(directive) ⇒ Boolean
Constructor Details
#initialize ⇒ ContentSecurityPolicy
Returns a new instance of ContentSecurityPolicy.
58 59 60 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 58 def initialize @directives = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(directive_sym, *args) ⇒ Object
Handles directive methods, such as #script_src and #style_src. Can be called multiple times to add additional sources.
72 73 74 75 76 77 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 72 def method_missing(directive_sym, *args) directive = directive_sym.to_s.downcase @directives[directive] ||= [] @directives[directive] += args.flatten.compact.map(&:to_s) @directives[directive] end |
Instance Attribute Details
#directives ⇒ Object
Returns the value of attribute directives.
56 57 58 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 56 def directives @directives end |
#report_only ⇒ Object
Returns the value of attribute report_only.
56 57 58 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 56 def report_only @report_only end |
#report_uri ⇒ Object
Returns the value of attribute report_uri.
56 57 58 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 56 def report_uri @report_uri end |
Instance Method Details
#csp_source(dsl_source) ⇒ Object
Converts sources from our Ruby DSL (camelcase) into proper Content-Security-Policy sources. (kebab-case, trailing colon, wrapped in single quotes, etc.) A few examples: data => data: http => http: self => ‘self’ unsafe_eval => ‘unsafe-eval’ example.com => example.com
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 90 def csp_source(dsl_source) return "#{dsl_source}:" if SCHEME_SOURCES.include?(dsl_source) kebab_source = kebab_case(dsl_source) return "'#{kebab_source}'" if QUOTED_SOURCES.include?(kebab_source) return "'#{dsl_source}'" if dsl_source.start_with?("nonce-") || dsl_source.start_with?("sha256-") dsl_source end |
#header_name ⇒ Object
113 114 115 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 113 def header_name report_only? ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy" end |
#report_only? ⇒ Boolean
62 63 64 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 62 def report_only? @report_only end |
#respond_to_missing?(directive, include_all = false) ⇒ Boolean
79 80 81 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 79 def respond_to_missing?(directive, include_all = false) valid_directive?(directive) || super end |
#to_h ⇒ Object
117 118 119 120 121 122 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 117 def to_h header_value = to_s return {} if header_value.blank? { header_name => header_value } end |
#to_s ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 101 def to_s directive_strings = @directives.uniq.sort.map do |directive, dsl_sources| [ kebab_case(directive), dsl_sources.map { |source| csp_source(source) }.join(" ") ].join(" ") end directive_strings << "report-uri #{report_uri}" if report_uri.present? directive_strings << "" directive_strings.join("; ").strip end |
#valid_directive?(directive) ⇒ Boolean
66 67 68 |
# File 'lib/better_content_security_policy/content_security_policy.rb', line 66 def valid_directive?(directive) DIRECTIVES.include?(kebab_case(directive)) end |