http-security 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +21 -0
  5. data/.yardopts +1 -0
  6. data/ChangeLog.md +17 -0
  7. data/Gemfile +17 -0
  8. data/LICENSE.txt +20 -0
  9. data/README.md +90 -0
  10. data/Rakefile +34 -0
  11. data/http-security.gemspec +23 -0
  12. data/lib/http/security.rb +2 -0
  13. data/lib/http/security/exceptions.rb +8 -0
  14. data/lib/http/security/headers.rb +12 -0
  15. data/lib/http/security/headers/cache_control.rb +36 -0
  16. data/lib/http/security/headers/content_security_policy.rb +71 -0
  17. data/lib/http/security/headers/content_security_policy_report_only.rb +10 -0
  18. data/lib/http/security/headers/pragma.rb +24 -0
  19. data/lib/http/security/headers/public_key_pins.rb +60 -0
  20. data/lib/http/security/headers/public_key_pins_report_only.rb +10 -0
  21. data/lib/http/security/headers/set_cookie.rb +75 -0
  22. data/lib/http/security/headers/strict_transport_security.rb +29 -0
  23. data/lib/http/security/headers/x_content_type_options.rb +24 -0
  24. data/lib/http/security/headers/x_frame_options.rb +39 -0
  25. data/lib/http/security/headers/x_permitted_cross_domain_policies.rb +47 -0
  26. data/lib/http/security/headers/x_xss_protection.rb +34 -0
  27. data/lib/http/security/http_date.rb +13 -0
  28. data/lib/http/security/malformed_header.rb +33 -0
  29. data/lib/http/security/parsers.rb +14 -0
  30. data/lib/http/security/parsers/cache_control.rb +62 -0
  31. data/lib/http/security/parsers/content_security_policy.rb +128 -0
  32. data/lib/http/security/parsers/content_security_policy_report_only.rb +10 -0
  33. data/lib/http/security/parsers/expires.rb +19 -0
  34. data/lib/http/security/parsers/parser.rb +408 -0
  35. data/lib/http/security/parsers/pragma.rb +25 -0
  36. data/lib/http/security/parsers/public_key_pins.rb +43 -0
  37. data/lib/http/security/parsers/public_key_pins_report_only.rb +10 -0
  38. data/lib/http/security/parsers/set_cookie.rb +62 -0
  39. data/lib/http/security/parsers/strict_transport_security.rb +42 -0
  40. data/lib/http/security/parsers/x_content_type_options.rb +19 -0
  41. data/lib/http/security/parsers/x_frame_options.rb +47 -0
  42. data/lib/http/security/parsers/x_permitted_cross_domain_policies.rb +33 -0
  43. data/lib/http/security/parsers/x_xss_protection.rb +27 -0
  44. data/lib/http/security/response.rb +323 -0
  45. data/lib/http/security/version.rb +5 -0
  46. data/spec/data/alexa.csv +100 -0
  47. data/spec/headers/cache_control_spec.rb +40 -0
  48. data/spec/headers/content_security_policy_spec.rb +46 -0
  49. data/spec/headers/pragma_spec.rb +26 -0
  50. data/spec/headers/public_key_pins_spec.rb +68 -0
  51. data/spec/headers/set_cookie_spec.rb +122 -0
  52. data/spec/headers/strict_transport_security_spec.rb +39 -0
  53. data/spec/headers/x_content_type_options_spec.rb +26 -0
  54. data/spec/headers/x_frame_options_spec.rb +86 -0
  55. data/spec/headers/x_permitted_cross_domain_policies_spec.rb +108 -0
  56. data/spec/headers/x_xss_protection_spec.rb +59 -0
  57. data/spec/parsers/cache_control_spec.rb +26 -0
  58. data/spec/parsers/content_security_policy_report_only_spec.rb +48 -0
  59. data/spec/parsers/content_security_policy_spec.rb +74 -0
  60. data/spec/parsers/expires_spec.rb +71 -0
  61. data/spec/parsers/parser_spec.rb +317 -0
  62. data/spec/parsers/pragma_spec.rb +10 -0
  63. data/spec/parsers/public_key_pins_spec.rb +81 -0
  64. data/spec/parsers/set_cookie_spec.rb +55 -0
  65. data/spec/parsers/strict_transport_security_spec.rb +62 -0
  66. data/spec/parsers/x_content_type_options_spec.rb +10 -0
  67. data/spec/parsers/x_frame_options_spec.rb +24 -0
  68. data/spec/parsers/x_permitted_cross_domain_policies_spec.rb +34 -0
  69. data/spec/parsers/x_xss_protection_spec.rb +39 -0
  70. data/spec/response_spec.rb +262 -0
  71. data/spec/spec_helper.rb +13 -0
  72. data/tasks/alexa.rb +40 -0
  73. metadata +171 -0
@@ -0,0 +1,5 @@
1
+ module HTTP
2
+ module Security
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,100 @@
1
+ 1,Google.com
2
+ 2,Facebook.com
3
+ 3,Youtube.com
4
+ 4,Yahoo.com
5
+ 5,Baidu.com
6
+ 6,Wikipedia.org
7
+ 7,Amazon.com
8
+ 8,Twitter.com
9
+ 9,Taobao.com
10
+ 10,Qq.com
11
+ 11,Google.co.in
12
+ 12,Live.com
13
+ 13,Linkedin.com
14
+ 14,Sina.com.cn
15
+ 15,Hao123.com
16
+ 16,Weibo.com
17
+ 17,Blogspot.com
18
+ 18,Yahoo.co.jp
19
+ 19,Tmall.com
20
+ 20,Yandex.ru
21
+ 21,Vk.com
22
+ 22,Ebay.com
23
+ 23,Google.de
24
+ 24,Sohu.com
25
+ 25,Bing.com
26
+ 26,Ask.com
27
+ 27,Wordpress.com
28
+ 28,Pinterest.com
29
+ 29,360.cn
30
+ 30,Google.co.uk
31
+ 31,Msn.com
32
+ 32,Google.co.jp
33
+ 33,Instagram.com
34
+ 34,Reddit.com
35
+ 35,Tumblr.com
36
+ 36,Google.fr
37
+ 37,Apple.com
38
+ 38,Google.com.br
39
+ 39,Mail.ru
40
+ 40,Imgur.com
41
+ 41,Xvideos.com
42
+ 42,163.com
43
+ 43,Paypal.com
44
+ 44,Google.ru
45
+ 45,Microsoft.com
46
+ 46,Alibaba.com
47
+ 47,Soso.com
48
+ 48,Adcash.com
49
+ 49,Aliexpress.com
50
+ 50,T.co
51
+ 51,Google.it
52
+ 52,Imdb.com
53
+ 53,Amazon.co.jp
54
+ 54,Go.com
55
+ 55,Google.es
56
+ 56,Craigslist.org
57
+ 57,Stackoverflow.com
58
+ 58,Xhamster.com
59
+ 59,Amazon.de
60
+ 60,Fc2.com
61
+ 61,Google.ca
62
+ 62,Espn.go.com
63
+ 63,Google.com.mx
64
+ 64,Onclickads.net
65
+ 65,Akamaihd.net
66
+ 66,Netflix.com
67
+ 67,Flipkart.com
68
+ 68,Gmw.cn
69
+ 69,Cnn.com
70
+ 70,Bbc.co.uk
71
+ 71,Adobe.com
72
+ 72,Google.com.hk
73
+ 73,Google.com.tr
74
+ 74,Amazon.co.uk
75
+ 75,Pornhub.com
76
+ 76,Huffingtonpost.com
77
+ 77,Dropbox.com
78
+ 78,Ebay.de
79
+ 79,Google.com.au
80
+ 80,Google.pl
81
+ 81,Kickass.to
82
+ 82,Odnoklassniki.ru
83
+ 83,Googleusercontent.com
84
+ 84,Dailymotion.com
85
+ 85,Blogger.com
86
+ 86,People.com.cn
87
+ 87,Rakuten.co.jp
88
+ 88,Amazon.in
89
+ 89,Thepiratebay.se
90
+ 90,Naver.com
91
+ 91,Xnxx.com
92
+ 92,Nytimes.com
93
+ 93,Xinhuanet.com
94
+ 94,Buzzfeed.com
95
+ 95,Pixnet.net
96
+ 96,Alipay.com
97
+ 97,Indiatimes.com
98
+ 98,Ebay.co.uk
99
+ 99,Outbrain.com
100
+ 100,Dailymail.co.uk
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'http/security/headers/cache_control'
3
+
4
+ describe HTTP::Security::Headers::CacheControl do
5
+ let(:max_age) { 0 }
6
+
7
+ subject do
8
+ described_class.new(
9
+ private: true,
10
+ max_age: max_age,
11
+ no_cache: true
12
+ )
13
+ end
14
+
15
+ describe "#initialize" do
16
+ it "should set max_age" do
17
+ expect(subject.max_age).to be == max_age
18
+ end
19
+ end
20
+
21
+ describe "#private?" do
22
+ context "when private: is true" do
23
+ subject { described_class.new(private: true) }
24
+
25
+ it { expect(subject.private?).to be(true) }
26
+ end
27
+
28
+ context "when private: is false" do
29
+ subject { described_class.new(private: false) }
30
+
31
+ it { expect(subject.private?).to be(false) }
32
+ end
33
+ end
34
+
35
+ describe "#to_s" do
36
+ it "should return a comma separated list of directives" do
37
+ expect(subject.to_s).to be == "private, max-age=#{max_age}, no-cache"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require 'http/security/headers/content_security_policy'
3
+
4
+ describe HTTP::Security::Headers::ContentSecurityPolicy do
5
+ let(:default_src) { "'self'" }
6
+ let(:img_src) { '*' }
7
+ let(:object_src) { 'media1.example.com media2.example.com *.cdn.example.com' }
8
+ let(:script_src) { 'trustedscripts.example.com' }
9
+
10
+ subject do
11
+ described_class.new(
12
+ default_src: default_src,
13
+ img_src: img_src,
14
+ object_src: object_src,
15
+ script_src: script_src
16
+ )
17
+ end
18
+
19
+ describe "#initialize" do
20
+ it "should set default_src"
21
+ it "should set script_src"
22
+ it "should set object_src"
23
+ it "should set style_src"
24
+ it "should set img_src"
25
+ it "should set media_src"
26
+ it "should set frame_src"
27
+ it "should set font_src"
28
+ it "should set connect_src"
29
+
30
+ context "when report_uri: is omitted" do
31
+ subject { described_class.new() }
32
+
33
+ it "should default it to []" do
34
+ expect(subject.report_uri).to be == []
35
+ end
36
+ end
37
+
38
+ it "should set sandbox"
39
+ end
40
+
41
+ describe "#to_s" do
42
+ it "should return a semicolon separated list of directives" do
43
+ expect(subject.to_s).to be == "default-src #{default_src}; script-src #{script_src}; object-src #{object_src}; img-src #{img_src}"
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'http/security/headers/pragma'
3
+
4
+ describe HTTP::Security::Headers::Pragma do
5
+ subject { described_class.new(no_cache: true) }
6
+
7
+ describe "no_cache?" do
8
+ context "when no_cache: was true" do
9
+ subject { described_class.new(no_cache: true) }
10
+
11
+ it { expect(subject.no_cache?).to be true }
12
+ end
13
+
14
+ context "when no_cache: was false" do
15
+ subject { described_class.new(no_cache: false) }
16
+
17
+ it { expect(subject.no_cache?).to be false }
18
+ end
19
+ end
20
+
21
+ describe "#to_s" do
22
+ it "should return a string" do
23
+ expect(subject.to_s).to be == "no-cache"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+ require 'http/security/headers/public_key_pins'
3
+
4
+ require 'uri'
5
+
6
+ describe HTTP::Security::Headers::PublicKeyPins do
7
+ let(:pin_sha256) do
8
+ [
9
+ 'klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=',
10
+ 'M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE='
11
+ ]
12
+ end
13
+ let(:pin_sha9000) { 'jlkfsjlksjlkfsjfs' }
14
+ let(:max_age) { 31536000 }
15
+ let(:include_sub_domains) { true }
16
+ let(:report_uri) { URI('https://www.example.com/') }
17
+ let(:strict) { true }
18
+
19
+ subject do
20
+ described_class.new(
21
+ pin_sha256: pin_sha256,
22
+ 'pin-sha9000' => pin_sha9000,
23
+ max_age: max_age,
24
+ includesubdomains: include_sub_domains,
25
+ report_uri: report_uri,
26
+ strict: strict
27
+ )
28
+ end
29
+
30
+ describe "#initialize" do
31
+ it "should group together pin options" do
32
+ expect(subject.pin).to be == {
33
+ sha256: pin_sha256,
34
+ 'sha9000' => [pin_sha9000]
35
+ }
36
+ end
37
+
38
+ it "should set max_age" do
39
+ expect(subject.max_age).to be max_age
40
+ end
41
+
42
+ it "should set include_sub_domains" do
43
+ expect(subject.include_sub_domains?).to be include_sub_domains
44
+ end
45
+
46
+ it "should set report_uri" do
47
+ expect(subject.report_uri).to be report_uri
48
+ end
49
+
50
+ it "should set strict" do
51
+ expect(subject.strict?).to be strict
52
+ end
53
+ end
54
+
55
+ describe "#to_s" do
56
+ it "should return a semicolon separated list of directives" do
57
+ expect(subject.to_s).to be == [
58
+ "pin-sha256=\"#{pin_sha256[0]}\"",
59
+ "pin-sha256=\"#{pin_sha256[1]}\"",
60
+ "pin-sha9000=\"#{pin_sha9000}\"",
61
+ "max-age=#{max_age}",
62
+ "includeSubdomains",
63
+ "report-uri=\"#{report_uri}\"",
64
+ "strict"
65
+ ].join('; ')
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+ require 'http/security/headers/set_cookie'
3
+
4
+ require 'date'
5
+
6
+ describe HTTP::Security::Headers::SetCookie do
7
+ let(:path) { '/accounts' }
8
+ let(:expires) { Date.parse("Wed, 09 Jun 2021 10:18:14 GMT") }
9
+ let(:secure) { 'Secure' }
10
+ let(:domain) { '.example.com' }
11
+ let(:http_only) { 'HttpOnly' }
12
+
13
+ describe described_class::Cookie do
14
+ let(:name) { :foo }
15
+ let(:value) { 'bar' }
16
+
17
+ subject do
18
+ described_class.new(
19
+ cookie: {name => value},
20
+ path: path,
21
+ expires: expires,
22
+ secure: secure,
23
+ domain: domain,
24
+ http_only: http_only
25
+ )
26
+ end
27
+
28
+ describe "#initialize" do
29
+ it "should set cookie" do
30
+ expect(subject.cookie).to be == {name => value}
31
+ end
32
+ end
33
+
34
+ describe "#name" do
35
+ it "should return the name" do
36
+ expect(subject.name).to be == name
37
+ end
38
+ end
39
+
40
+ describe "#value" do
41
+ it "should return the value" do
42
+ expect(subject.value).to be == value
43
+ end
44
+ end
45
+
46
+ describe "#secure?" do
47
+ context "when secure: was present" do
48
+ subject { described_class.new(secure: 'Secure') }
49
+
50
+ it { expect(subject.secure?).to be true}
51
+ end
52
+
53
+ context "when secure: was not present" do
54
+ subject { described_class.new() }
55
+
56
+ it { expect(subject.secure?).to be false }
57
+ end
58
+ end
59
+
60
+ describe "#http_only?" do
61
+ context "when http_only: was present" do
62
+ subject { described_class.new(http_only: 'HttpOnly') }
63
+
64
+ it { expect(subject.http_only?).to be true}
65
+ end
66
+
67
+ context "when http_only: was not present" do
68
+ subject { described_class.new() }
69
+
70
+ it { expect(subject.http_only?).to be false }
71
+ end
72
+ end
73
+
74
+ describe "#to_s" do
75
+ it "should format the cookie" do
76
+ expect(subject.to_s).to be == "#{name}=#{value}; Path=#{path}; Domain=#{domain}; Expires=#{expires.httpdate}; #{secure}; #{http_only}"
77
+ end
78
+ end
79
+ end
80
+
81
+ let(:cookies) do
82
+ [
83
+ {
84
+ cookie: {foo: 'bar'},
85
+ path: path,
86
+ domain: domain,
87
+ secure: secure,
88
+ http_only: http_only
89
+ },
90
+
91
+ {
92
+ cookie: {bar: 'baz'},
93
+ domain: domain,
94
+ path: path,
95
+ expires: expires
96
+ }
97
+ ]
98
+ end
99
+
100
+ subject { described_class.new(cookies) }
101
+
102
+ describe "#initialize" do
103
+ it "should set cookies" do
104
+ expect(subject.cookies.length).to be == cookies.length
105
+ expect(subject.cookies).to all(be_kind_of(described_class::Cookie))
106
+ end
107
+ end
108
+
109
+ describe "#each" do
110
+ it "should enumerate over each cookie" do
111
+ expect { |b|
112
+ subject.each(&b)
113
+ }.to yield_successive_args(*subject.cookies)
114
+ end
115
+ end
116
+
117
+ describe "#to_s" do
118
+ it "should return a semicolon separated list of directives" do
119
+ expect(subject.to_s).to be == "foo=bar; Path=#{path}; Domain=#{domain}; Secure; HttpOnly, bar=baz; Path=#{path}; Domain=#{domain}; Expires=#{expires.httpdate}"
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'http/security/headers/strict_transport_security'
3
+
4
+ describe HTTP::Security::Headers::StrictTransportSecurity do
5
+ let(:max_age) { 31536000 }
6
+
7
+ subject do
8
+ described_class.new(
9
+ max_age: max_age,
10
+ includesubdomains: true
11
+ )
12
+ end
13
+
14
+ describe "#initialize" do
15
+ it "should set max_age" do
16
+ expect(subject.max_age).to be == max_age
17
+ end
18
+ end
19
+
20
+ describe "#include_sub_domains?" do
21
+ context "when includesubdomains: was true" do
22
+ subject { described_class.new(includesubdomains: true) }
23
+
24
+ it { expect(subject.include_sub_domains?).to be true }
25
+ end
26
+
27
+ context "when includesubdomains: was false" do
28
+ subject { described_class.new(includesubdomains: false) }
29
+
30
+ it { expect(subject.include_sub_domains?).to be false }
31
+ end
32
+ end
33
+
34
+ describe "#to_s" do
35
+ it "should return a string" do
36
+ expect(subject.to_s).to be == "max-age=#{max_age}; includeSubDomains"
37
+ end
38
+ end
39
+ end