http-security 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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