secure_headers 2.0.0.pre → 2.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of secure_headers might be problematic. Click here for more details.

data/README.md CHANGED
@@ -6,6 +6,8 @@ The gem will automatically apply several headers that are related to security.
6
6
  - X-Frame-Options (XFO) - Prevents your content from being framed and potentially clickjacked. [X-Frame-Options draft](https://tools.ietf.org/html/draft-ietf-websec-x-frame-options-02)
7
7
  - X-XSS-Protection - [Cross site scripting heuristic filter for IE/Chrome](http://msdn.microsoft.com/en-us/library/dd565647\(v=vs.85\).aspx)
8
8
  - X-Content-Type-Options - [Prevent content type sniffing](http://msdn.microsoft.com/en-us/library/ie/gg622941\(v=vs.85\).aspx)
9
+ - X-Download-Options - [Prevent file downloads opening](http://msdn.microsoft.com/en-us/library/ie/jj542450(v=vs.85).aspx)
10
+ - X-Permitted-Cross-Domain-Policies - [Restrict Adobe Flash Player's access to data](https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html)
9
11
 
10
12
  This gem has integration with Rails, but works for any Ruby code. See the sinatra example section.
11
13
 
@@ -48,6 +50,8 @@ The following methods are going to be called, unless they are provided in a `ski
48
50
  * `:set_x_frame_options_header`
49
51
  * `:set_x_xss_protection_header`
50
52
  * `:set_x_content_type_options_header`
53
+ * `:set_x_download_options_header`
54
+ * `:set_x_permitted_cross_domain_policies_header`
51
55
 
52
56
  ### Bonus Features
53
57
 
@@ -65,6 +69,8 @@ This gem makes a few assumptions about how you will use some features. For exam
65
69
  config.x_frame_options = 'DENY'
66
70
  config.x_content_type_options = "nosniff"
67
71
  config.x_xss_protection = {:value => 1, :mode => 'block'}
72
+ config.x_download_options = 'noopen'
73
+ config.x_permitted_cross_domain_policies = 'none'
68
74
  config.csp = {
69
75
  :default_src => "https: self",
70
76
  :frame_src => "https: http:.twimg.com http://itunes.apple.com",
@@ -106,6 +112,8 @@ This configuration will likely work for most applications without modification.
106
112
  :x_frame_options => {:value => 'SAMEORIGIN'}
107
113
  :x_xss_protection => {:value => 1, :mode => 'block'} # set the :mode option to false to use "warning only" mode
108
114
  :x_content_type_options => {:value => 'nosniff'}
115
+ :x_download_options => {:value => 'noopen'}
116
+ :x_permitted_cross_domain_policies => {:value => 'none'}
109
117
  ```
110
118
 
111
119
  ### Content Security Policy (CSP)
@@ -335,6 +343,8 @@ require 'secure_headers'
335
343
  config.x_frame_options = 'DENY'
336
344
  config.x_content_type_options = "nosniff"
337
345
  config.x_xss_protection = {:value => 1, :mode => false}
346
+ config.x_download_options = 'noopen'
347
+ config.x_permitted_cross_domain_policies = 'none'
338
348
  config.csp = {
339
349
  :default_src => "https: inline eval",
340
350
  :report_uri => '//example.com/uri-directive',
@@ -390,6 +400,8 @@ def before_load
390
400
  config.x_frame_options = 'DENY'
391
401
  config.x_content_type_options = "nosniff"
392
402
  config.x_xss_protection = {:value => '1', :mode => false}
403
+ config.x_download_options = 'noopen'
404
+ config.x_permitted_cross_domain_policies = 'none'
393
405
  config.csp = {
394
406
  :default_src => "https: inline eval",
395
407
  :report_uri => '//example.com/uri-directive',
@@ -3,6 +3,7 @@
3
3
  config.x_frame_options = 'SAMEORIGIN'
4
4
  config.x_content_type_options = "nosniff"
5
5
  config.x_xss_protection = {:value => 1, :mode => 'block'}
6
+ config.x_permitted_cross_domain_policies = 'none'
6
7
  csp = {
7
8
  :default_src => "self",
8
9
  :script_src => "self nonce",
@@ -67,6 +67,11 @@ describe OtherThingsController, :type => :controller do
67
67
  expect(@env['X-Content-Type-Options']).to eq("nosniff")
68
68
  end
69
69
 
70
+ it "sets the X-Permitted-Cross-Domain-Policies" do
71
+ get '/'
72
+ expect(@env['X-Permitted-Cross-Domain-Policies']).to eq("none")
73
+ end
74
+
70
75
  context "using IE" do
71
76
  it "sets the X-Content-Type-Options header" do
72
77
  @env['HTTP_USER_AGENT'] = "Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0"
@@ -38,6 +38,11 @@ describe ThingsController, :type => :controller do
38
38
  expect(response.headers['X-Content-Type-Options']).to eq("nosniff")
39
39
  end
40
40
 
41
+ it "sets the X-Permitted-Cross-Domain-Policies" do
42
+ get :index
43
+ expect(response.headers['X-Permitted-Cross-Domain-Policies']).to eq("none")
44
+ end
45
+
41
46
  context "using IE" do
42
47
  it "sets the X-Content-Type-Options header" do
43
48
  request.env['HTTP_USER_AGENT'] = "Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0"
@@ -34,6 +34,11 @@ describe OtherThingsController, :type => :controller do
34
34
  expect(response.headers['X-Content-Type-Options']).to eq(SecureHeaders::XContentTypeOptions::Constants::DEFAULT_VALUE)
35
35
  end
36
36
 
37
+ it "sets the X-Permitted-Cross-Domain-Policies" do
38
+ get :index
39
+ expect(response.headers['X-Permitted-Cross-Domain-Policies']).to eq("none")
40
+ end
41
+
37
42
  context "using IE" do
38
43
  it "sets the X-Content-Type-Options header" do
39
44
  request.env['HTTP_USER_AGENT'] = "Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0"
@@ -38,6 +38,11 @@ describe ThingsController, :type => :controller do
38
38
  expect(response.headers['X-Content-Type-Options']).to eq(SecureHeaders::XContentTypeOptions::Constants::DEFAULT_VALUE)
39
39
  end
40
40
 
41
+ it "sets the X-Permitted-Cross-Domain-Policies" do
42
+ get :index
43
+ expect(response.headers['X-Permitted-Cross-Domain-Policies']).to eq("none")
44
+ end
45
+
41
46
  context "using IE" do
42
47
  it "sets the X-Content-Type-Options header" do
43
48
  request.env['HTTP_USER_AGENT'] = "Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0"
@@ -0,0 +1,40 @@
1
+ module SecureHeaders
2
+ class XPCDPBuildError < StandardError; end
3
+ class XPermittedCrossDomainPolicies < Header
4
+ module Constants
5
+ XPCDP_HEADER_NAME = "X-Permitted-Cross-Domain-Policies"
6
+ DEFAULT_VALUE = 'none'
7
+ VALID_POLICIES = %w(all none master-only by-content-type by-ftp-filename)
8
+ end
9
+ include Constants
10
+
11
+ def initialize(config = nil)
12
+ @config = config
13
+ validate_config unless @config.nil?
14
+ end
15
+
16
+ def name
17
+ XPCDP_HEADER_NAME
18
+ end
19
+
20
+ def value
21
+ case @config
22
+ when NilClass
23
+ DEFAULT_VALUE
24
+ when String
25
+ @config
26
+ else
27
+ @config[:value]
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def validate_config
34
+ value = @config.is_a?(Hash) ? @config[:value] : @config
35
+ unless VALID_POLICIES.include?(value.downcase)
36
+ raise XPCDPBuildError.new("Value can only be one of #{VALID_POLICIES.join(', ')}")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,3 +1,3 @@
1
1
  module SecureHeaders
2
- VERSION = "2.0.0.pre"
2
+ VERSION = "2.0.0.pre2"
3
3
  end
@@ -5,7 +5,8 @@ module SecureHeaders
5
5
  module Configuration
6
6
  class << self
7
7
  attr_accessor :hsts, :x_frame_options, :x_content_type_options,
8
- :x_xss_protection, :csp, :x_download_options, :script_hashes
8
+ :x_xss_protection, :csp, :x_download_options, :script_hashes,
9
+ :x_permitted_cross_domain_policies
9
10
 
10
11
  def configure &block
11
12
  instance_eval &block
@@ -46,6 +47,7 @@ module SecureHeaders
46
47
  before_filter :set_x_xss_protection_header
47
48
  before_filter :set_x_content_type_options_header
48
49
  before_filter :set_x_download_options_header
50
+ before_filter :set_x_permitted_cross_domain_policies_header
49
51
  end
50
52
 
51
53
  # we can't use ||= because I'm overloading false => disable, nil => default
@@ -63,6 +65,7 @@ module SecureHeaders
63
65
  set_x_xss_protection_header(options[:x_xss_protection])
64
66
  set_x_content_type_options_header(options[:x_content_type_options])
65
67
  set_x_download_options_header(options[:x_download_options])
68
+ set_x_permitted_cross_domain_policies_header(options[:x_permitted_cross_domain_policies])
66
69
  end
67
70
 
68
71
  # set_csp_header - uses the request accessor and SecureHeader::Configuration settings
@@ -137,6 +140,10 @@ module SecureHeaders
137
140
  set_a_header(:x_download_options, XDownloadOptions, options)
138
141
  end
139
142
 
143
+ def set_x_permitted_cross_domain_policies_header(options=self.class.secure_headers_options[:x_permitted_cross_domain_policies])
144
+ set_a_header(:x_permitted_cross_domain_policies, XPermittedCrossDomainPolicies, options)
145
+ end
146
+
140
147
  private
141
148
 
142
149
  def set_a_header(name, klass, options=nil)
@@ -167,6 +174,7 @@ require "secure_headers/headers/strict_transport_security"
167
174
  require "secure_headers/headers/x_xss_protection"
168
175
  require "secure_headers/headers/x_content_type_options"
169
176
  require "secure_headers/headers/x_download_options"
177
+ require "secure_headers/headers/x_permitted_cross_domain_policies"
170
178
  require "secure_headers/railtie"
171
179
  require "secure_headers/hash_helper"
172
180
  require "secure_headers/view_helper"
@@ -8,10 +8,10 @@ Gem::Specification.new do |gem|
8
8
  gem.version = SecureHeaders::VERSION
9
9
  gem.authors = ["Neil Matatall"]
10
10
  gem.email = ["neil.matatall@gmail.com"]
11
- gem.description = %q{Add easily configured browser headers to responses.}
12
- gem.summary = %q{Add easily configured browser headers to responses
13
- including content security policy, x-frame-options,
14
- strict-transport-security and more.}
11
+ gem.description = %q{Security related headers all in one gem.}
12
+ gem.summary = %q{Add easily configured security headers to responses
13
+ including content-security-policy, x-frame-options,
14
+ strict-transport-security, etc.}
15
15
  gem.homepage = "https://github.com/twitter/secureheaders"
16
16
  gem.license = "Apache Public License 2.0"
17
17
  gem.files = `git ls-files`.split($/)
@@ -24,7 +24,7 @@ module SecureHeaders
24
24
 
25
25
  it "doesn't accept anything besides noopen" do
26
26
  expect {
27
- XContentTypeOptions.new("open")
27
+ XDownloadOptions.new("open")
28
28
  }.to raise_error
29
29
  end
30
30
  end
@@ -0,0 +1,64 @@
1
+ module SecureHeaders
2
+ describe XPermittedCrossDomainPolicies do
3
+ specify { expect(XPermittedCrossDomainPolicies.new.name).to eq(XPermittedCrossDomainPolicies::Constants::XPCDP_HEADER_NAME)}
4
+ specify { expect(XPermittedCrossDomainPolicies.new.value).to eq("none")}
5
+ specify { expect(XPermittedCrossDomainPolicies.new('master-only').value).to eq('master-only')}
6
+ specify { expect(XPermittedCrossDomainPolicies.new(:value => 'master-only').value).to eq('master-only') }
7
+
8
+ context "valid configuration values" do
9
+ it "accepts 'all'" do
10
+ expect {
11
+ XPermittedCrossDomainPolicies.new("all")
12
+ }.not_to raise_error
13
+
14
+ expect {
15
+ XPermittedCrossDomainPolicies.new(:value => "all")
16
+ }.not_to raise_error
17
+ end
18
+
19
+ it "accepts 'by-ftp-filename'" do
20
+ expect {
21
+ XPermittedCrossDomainPolicies.new("by-ftp-filename")
22
+ }.not_to raise_error
23
+
24
+ expect {
25
+ XPermittedCrossDomainPolicies.new(:value => "by-ftp-filename")
26
+ }.not_to raise_error
27
+ end
28
+
29
+ it "accepts 'by-content-type'" do
30
+ expect {
31
+ XPermittedCrossDomainPolicies.new("by-content-type")
32
+ }.not_to raise_error
33
+
34
+ expect {
35
+ XPermittedCrossDomainPolicies.new(:value => "by-content-type")
36
+ }.not_to raise_error
37
+ end
38
+ it "accepts 'master-only'" do
39
+ expect {
40
+ XPermittedCrossDomainPolicies.new("master-only")
41
+ }.not_to raise_error
42
+
43
+ expect {
44
+ XPermittedCrossDomainPolicies.new(:value => "master-only")
45
+ }.not_to raise_error
46
+ end
47
+
48
+ it "accepts nil" do
49
+ expect {
50
+ XPermittedCrossDomainPolicies.new
51
+ }.not_to raise_error
52
+ end
53
+ end
54
+
55
+ context 'invlaid configuration values' do
56
+
57
+ it "doesn't accept invalid values" do
58
+ expect {
59
+ XPermittedCrossDomainPolicies.new("open")
60
+ }.to raise_error
61
+ end
62
+ end
63
+ end
64
+ end
@@ -18,7 +18,7 @@ describe SecureHeaders do
18
18
  allow(subject).to receive(:request).and_return(request)
19
19
  end
20
20
 
21
- ALL_HEADERS = Hash[[:hsts, :csp, :x_frame_options, :x_content_type_options, :x_xss_protection].map{|header| [header, false]}]
21
+ ALL_HEADERS = Hash[[:hsts, :csp, :x_frame_options, :x_content_type_options, :x_xss_protection, :x_permitted_cross_domain_policies].map{|header| [header, false]}]
22
22
 
23
23
  def stub_user_agent val
24
24
  allow(request).to receive_message_chain(:env, :[]).and_return(val)
@@ -36,6 +36,7 @@ describe SecureHeaders do
36
36
  config.x_xss_protection = nil
37
37
  config.csp = nil
38
38
  config.x_download_options = nil
39
+ config.x_permitted_cross_domain_policies = nil
39
40
  end
40
41
  end
41
42
 
@@ -46,6 +47,7 @@ describe SecureHeaders do
46
47
  subject.set_x_content_type_options_header
47
48
  subject.set_x_xss_protection_header
48
49
  subject.set_x_download_options_header
50
+ subject.set_x_permitted_cross_domain_policies_header
49
51
  end
50
52
 
51
53
  describe "#set_header" do
@@ -64,7 +66,7 @@ describe SecureHeaders do
64
66
  USER_AGENTS.each do |name, useragent|
65
67
  it "sets all default headers for #{name} (smoke test)" do
66
68
  stub_user_agent(useragent)
67
- number_of_headers = 6
69
+ number_of_headers = 7
68
70
  expect(subject).to receive(:set_header).exactly(number_of_headers).times # a request for a given header
69
71
  subject.set_csp_header
70
72
  subject.set_x_frame_options_header
@@ -72,6 +74,7 @@ describe SecureHeaders do
72
74
  subject.set_x_xss_protection_header
73
75
  subject.set_x_content_type_options_header
74
76
  subject.set_x_download_options_header
77
+ subject.set_x_permitted_cross_domain_policies_header
75
78
  end
76
79
  end
77
80
 
@@ -96,6 +99,11 @@ describe SecureHeaders do
96
99
  subject.set_x_frame_options_header(false)
97
100
  end
98
101
 
102
+ it "does not set the X-Permitted-Cross-Domain-Policies header if disabled" do
103
+ should_not_assign_header(XPCDP_HEADER_NAME)
104
+ subject.set_x_permitted_cross_domain_policies_header(false)
105
+ end
106
+
99
107
  it "does not set the HSTS header if disabled" do
100
108
  should_not_assign_header(HSTS_HEADER_NAME)
101
109
  subject.set_hsts_header(false)
@@ -133,6 +141,7 @@ describe SecureHeaders do
133
141
  config.x_xss_protection = false
134
142
  config.csp = false
135
143
  config.x_download_options = false
144
+ config.x_permitted_cross_domain_policies = false
136
145
  end
137
146
  expect(subject).not_to receive(:set_header)
138
147
  set_security_headers(subject)
@@ -249,4 +258,16 @@ describe SecureHeaders do
249
258
  end
250
259
  end
251
260
  end
261
+
262
+ describe "#set_x_permitted_cross_domain_policies_header" do
263
+ it "sets the X-Permitted-Cross-Domain-Policies header" do
264
+ should_assign_header(XPCDP_HEADER_NAME, SecureHeaders::XPermittedCrossDomainPolicies::Constants::DEFAULT_VALUE)
265
+ subject.set_x_permitted_cross_domain_policies_header
266
+ end
267
+
268
+ it "allows a custom X-Permitted-Cross-Domain-Policies header" do
269
+ should_assign_header(XPCDP_HEADER_NAME, "master-only")
270
+ subject.set_x_permitted_cross_domain_policies_header(:value => 'master-only')
271
+ end
272
+ end
252
273
  end
data/spec/spec_helper.rb CHANGED
@@ -13,6 +13,7 @@ include ::SecureHeaders::XFrameOptions::Constants
13
13
  include ::SecureHeaders::XXssProtection::Constants
14
14
  include ::SecureHeaders::XContentTypeOptions::Constants
15
15
  include ::SecureHeaders::XDownloadOptions::Constants
16
+ include ::SecureHeaders::XPermittedCrossDomainPolicies::Constants
16
17
 
17
18
  USER_AGENTS = {
18
19
  :firefox => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1',
metadata CHANGED
@@ -1,40 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secure_headers
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre
4
+ version: 2.0.0.pre2
5
+ prerelease: 6
5
6
  platform: ruby
6
7
  authors:
7
8
  - Neil Matatall
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2014-11-14 00:00:00.000000000 Z
12
+ date: 2014-12-06 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rake
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - ">="
19
+ - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: '0'
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - ">="
27
+ - - ! '>='
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0'
27
- description: Add easily configured browser headers to responses.
30
+ description: Security related headers all in one gem.
28
31
  email:
29
32
  - neil.matatall@gmail.com
30
33
  executables: []
31
34
  extensions: []
32
35
  extra_rdoc_files: []
33
36
  files:
34
- - ".gitignore"
35
- - ".ruby-gemset"
36
- - ".ruby-version"
37
- - ".travis.yml"
37
+ - .gitignore
38
+ - .ruby-gemset
39
+ - .ruby-version
40
+ - .travis.yml
38
41
  - Gemfile
39
42
  - Guardfile
40
43
  - LICENSE
@@ -103,6 +106,7 @@ files:
103
106
  - lib/secure_headers/headers/x_content_type_options.rb
104
107
  - lib/secure_headers/headers/x_download_options.rb
105
108
  - lib/secure_headers/headers/x_frame_options.rb
109
+ - lib/secure_headers/headers/x_permitted_cross_domain_policies.rb
106
110
  - lib/secure_headers/headers/x_xss_protection.rb
107
111
  - lib/secure_headers/padrino.rb
108
112
  - lib/secure_headers/railtie.rb
@@ -116,6 +120,7 @@ files:
116
120
  - spec/lib/secure_headers/headers/x_content_type_options_spec.rb
117
121
  - spec/lib/secure_headers/headers/x_download_options_spec.rb
118
122
  - spec/lib/secure_headers/headers/x_frame_options_spec.rb
123
+ - spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb
119
124
  - spec/lib/secure_headers/headers/x_xss_protection_spec.rb
120
125
  - spec/lib/secure_headers_spec.rb
121
126
  - spec/spec_helper.rb
@@ -123,28 +128,29 @@ files:
123
128
  homepage: https://github.com/twitter/secureheaders
124
129
  licenses:
125
130
  - Apache Public License 2.0
126
- metadata: {}
127
131
  post_install_message:
128
132
  rdoc_options: []
129
133
  require_paths:
130
134
  - lib
131
135
  required_ruby_version: !ruby/object:Gem::Requirement
136
+ none: false
132
137
  requirements:
133
- - - ">="
138
+ - - ! '>='
134
139
  - !ruby/object:Gem::Version
135
140
  version: '0'
136
141
  required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
137
143
  requirements:
138
- - - ">"
144
+ - - ! '>'
139
145
  - !ruby/object:Gem::Version
140
146
  version: 1.3.1
141
147
  requirements: []
142
148
  rubyforge_project:
143
- rubygems_version: 2.2.2
149
+ rubygems_version: 1.8.23
144
150
  signing_key:
145
- specification_version: 4
146
- summary: Add easily configured browser headers to responses including content security
147
- policy, x-frame-options, strict-transport-security and more.
151
+ specification_version: 3
152
+ summary: Add easily configured security headers to responses including content-security-policy,
153
+ x-frame-options, strict-transport-security, etc.
148
154
  test_files:
149
155
  - spec/lib/secure_headers/headers/content_security_policy/script_hash_middleware_spec.rb
150
156
  - spec/lib/secure_headers/headers/content_security_policy_spec.rb
@@ -152,6 +158,7 @@ test_files:
152
158
  - spec/lib/secure_headers/headers/x_content_type_options_spec.rb
153
159
  - spec/lib/secure_headers/headers/x_download_options_spec.rb
154
160
  - spec/lib/secure_headers/headers/x_frame_options_spec.rb
161
+ - spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb
155
162
  - spec/lib/secure_headers/headers/x_xss_protection_spec.rb
156
163
  - spec/lib/secure_headers_spec.rb
157
164
  - spec/spec_helper.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 4d41b253fa38de884f864558563330b9e707e2dc
4
- data.tar.gz: 69b19dbc4ab124481e6f47dad73cd7a6497aa844
5
- SHA512:
6
- metadata.gz: fa7e778e7cb305a3273d4b3aa94bf8597972910da752b218ebf0779330c4c025c2906cec3974a410193db600fc899465a2da8bc7a8ca5720eb30ba95335e7a5d
7
- data.tar.gz: 21934fb364794d3fc08e7dde201e04cb1253686e362e46ec370b06021007cb897fc3182de9a1ac646fa2448f4ce7a9f45b33da31f4d2a8690b76c42527bb9001