securenative 0.1.33 → 0.1.38

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3fe3afee2e1f23bf0d5170952904e4e66078fb392a791dee566da36b39df2e7
4
- data.tar.gz: 8b36837fe92f5a823a12d456cfc33f462a754bac28917a85a736fc37988ec72c
3
+ metadata.gz: dc768adcdfbc198fdda7606be0d78ae33399136a7747ec6487560c0b3e43eedc
4
+ data.tar.gz: bc3e5226d0bd77997b713348c9d774d3fa8f3251df5729d432b66d23761a4eee
5
5
  SHA512:
6
- metadata.gz: ee1cde9a072ac6292dcb80ca41da67d925ede12be54f10c79ff59c17a2be29b566b2a0ae4cdcd17c69446e996bcc863ae4e98c4079748b184842fb2c55f171f1
7
- data.tar.gz: c2c3cd008ffd8719acf11d4b31792b303cd649f090c2bb81567995fe5802d205c97601ff050f03d8bd33c1931a9cc65cca6873405df674768cfcca3a134c9f38
6
+ metadata.gz: f24b407bcb3dc2d90458d0c0f59d9c55f19210d82fe4cf87671271a1ff5b48c30312a84976cab76923f4720b27f2a41b9208d9bd101804115e1f7ad34086e978
7
+ data.tar.gz: e54bc315a48ebb30ad9355a1d89b1eeea3226608e833f16b1cd8b9906b64b89e0e0f03029e7fb946d0f5fadc8b5eb220d01b37c75aeb89d218aba75a7807b21f
@@ -1,61 +1,61 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- securenative (0.1.33)
4
+ securenative (0.1.38)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- actioncable (6.0.3.3)
10
- actionpack (= 6.0.3.3)
9
+ actioncable (6.0.3.4)
10
+ actionpack (= 6.0.3.4)
11
11
  nio4r (~> 2.0)
12
12
  websocket-driver (>= 0.6.1)
13
- actionmailbox (6.0.3.3)
14
- actionpack (= 6.0.3.3)
15
- activejob (= 6.0.3.3)
16
- activerecord (= 6.0.3.3)
17
- activestorage (= 6.0.3.3)
18
- activesupport (= 6.0.3.3)
13
+ actionmailbox (6.0.3.4)
14
+ actionpack (= 6.0.3.4)
15
+ activejob (= 6.0.3.4)
16
+ activerecord (= 6.0.3.4)
17
+ activestorage (= 6.0.3.4)
18
+ activesupport (= 6.0.3.4)
19
19
  mail (>= 2.7.1)
20
- actionmailer (6.0.3.3)
21
- actionpack (= 6.0.3.3)
22
- actionview (= 6.0.3.3)
23
- activejob (= 6.0.3.3)
20
+ actionmailer (6.0.3.4)
21
+ actionpack (= 6.0.3.4)
22
+ actionview (= 6.0.3.4)
23
+ activejob (= 6.0.3.4)
24
24
  mail (~> 2.5, >= 2.5.4)
25
25
  rails-dom-testing (~> 2.0)
26
- actionpack (6.0.3.3)
27
- actionview (= 6.0.3.3)
28
- activesupport (= 6.0.3.3)
26
+ actionpack (6.0.3.4)
27
+ actionview (= 6.0.3.4)
28
+ activesupport (= 6.0.3.4)
29
29
  rack (~> 2.0, >= 2.0.8)
30
30
  rack-test (>= 0.6.3)
31
31
  rails-dom-testing (~> 2.0)
32
32
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
33
- actiontext (6.0.3.3)
34
- actionpack (= 6.0.3.3)
35
- activerecord (= 6.0.3.3)
36
- activestorage (= 6.0.3.3)
37
- activesupport (= 6.0.3.3)
33
+ actiontext (6.0.3.4)
34
+ actionpack (= 6.0.3.4)
35
+ activerecord (= 6.0.3.4)
36
+ activestorage (= 6.0.3.4)
37
+ activesupport (= 6.0.3.4)
38
38
  nokogiri (>= 1.8.5)
39
- actionview (6.0.3.3)
40
- activesupport (= 6.0.3.3)
39
+ actionview (6.0.3.4)
40
+ activesupport (= 6.0.3.4)
41
41
  builder (~> 3.1)
42
42
  erubi (~> 1.4)
43
43
  rails-dom-testing (~> 2.0)
44
44
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
45
- activejob (6.0.3.3)
46
- activesupport (= 6.0.3.3)
45
+ activejob (6.0.3.4)
46
+ activesupport (= 6.0.3.4)
47
47
  globalid (>= 0.3.6)
48
- activemodel (6.0.3.3)
49
- activesupport (= 6.0.3.3)
50
- activerecord (6.0.3.3)
51
- activemodel (= 6.0.3.3)
52
- activesupport (= 6.0.3.3)
53
- activestorage (6.0.3.3)
54
- actionpack (= 6.0.3.3)
55
- activejob (= 6.0.3.3)
56
- activerecord (= 6.0.3.3)
48
+ activemodel (6.0.3.4)
49
+ activesupport (= 6.0.3.4)
50
+ activerecord (6.0.3.4)
51
+ activemodel (= 6.0.3.4)
52
+ activesupport (= 6.0.3.4)
53
+ activestorage (6.0.3.4)
54
+ actionpack (= 6.0.3.4)
55
+ activejob (= 6.0.3.4)
56
+ activerecord (= 6.0.3.4)
57
57
  marcel (~> 0.3.1)
58
- activesupport (6.0.3.3)
58
+ activesupport (6.0.3.4)
59
59
  concurrent-ruby (~> 1.0, >= 1.0.2)
60
60
  i18n (>= 0.7, < 2)
61
61
  minitest (~> 5.1)
@@ -64,7 +64,7 @@ GEM
64
64
  addressable (2.7.0)
65
65
  public_suffix (>= 2.0.2, < 5.0)
66
66
  builder (3.2.4)
67
- codecov (0.2.11)
67
+ codecov (0.2.12)
68
68
  json
69
69
  simplecov
70
70
  concurrent-ruby (1.1.7)
@@ -177,29 +177,29 @@ GEM
177
177
  rack
178
178
  rack-test (1.1.0)
179
179
  rack (>= 1.0, < 3)
180
- rails (6.0.3.3)
181
- actioncable (= 6.0.3.3)
182
- actionmailbox (= 6.0.3.3)
183
- actionmailer (= 6.0.3.3)
184
- actionpack (= 6.0.3.3)
185
- actiontext (= 6.0.3.3)
186
- actionview (= 6.0.3.3)
187
- activejob (= 6.0.3.3)
188
- activemodel (= 6.0.3.3)
189
- activerecord (= 6.0.3.3)
190
- activestorage (= 6.0.3.3)
191
- activesupport (= 6.0.3.3)
180
+ rails (6.0.3.4)
181
+ actioncable (= 6.0.3.4)
182
+ actionmailbox (= 6.0.3.4)
183
+ actionmailer (= 6.0.3.4)
184
+ actionpack (= 6.0.3.4)
185
+ actiontext (= 6.0.3.4)
186
+ actionview (= 6.0.3.4)
187
+ activejob (= 6.0.3.4)
188
+ activemodel (= 6.0.3.4)
189
+ activerecord (= 6.0.3.4)
190
+ activestorage (= 6.0.3.4)
191
+ activesupport (= 6.0.3.4)
192
192
  bundler (>= 1.3.0)
193
- railties (= 6.0.3.3)
193
+ railties (= 6.0.3.4)
194
194
  sprockets-rails (>= 2.0.0)
195
195
  rails-dom-testing (2.0.3)
196
196
  activesupport (>= 4.2.0)
197
197
  nokogiri (>= 1.6)
198
198
  rails-html-sanitizer (1.3.0)
199
199
  loofah (~> 2.3)
200
- railties (6.0.3.3)
201
- actionpack (= 6.0.3.3)
202
- activesupport (= 6.0.3.3)
200
+ railties (6.0.3.4)
201
+ actionpack (= 6.0.3.4)
202
+ activesupport (= 6.0.3.4)
203
203
  method_source
204
204
  rake (>= 0.8.7)
205
205
  thor (>= 0.20.3, < 2.0)
@@ -242,7 +242,7 @@ GEM
242
242
  thread_safe (~> 0.1)
243
243
  url_mount (0.2.1)
244
244
  rack
245
- webmock (3.9.1)
245
+ webmock (3.9.2)
246
246
  addressable (>= 2.3.6)
247
247
  crack (>= 0.3.2)
248
248
  hashdiff (>= 0.4.0, < 2.0.0)
data/README.md CHANGED
@@ -176,7 +176,7 @@ SECURENATIVE_API_KEY: dsbe27fh3437r2yd326fg3fdg36f43
176
176
  SECURENATIVE_PROXY_HEADERS: ["CF-Connecting-IP"]
177
177
  ```
178
178
 
179
- Initialize sdk as showed above.
179
+ Initialize sdk as shown above.
180
180
 
181
181
  ### Options 2: Using ConfigurationBuilder
182
182
 
@@ -20,6 +20,12 @@ module SecureNative
20
20
  begin
21
21
  res = @event_manager.send_sync(event, SecureNative::Enums::ApiRoute::VERIFY)
22
22
  ver_result = JSON.parse(res.body)
23
+ if res.code != "200"
24
+ if @options.fail_over_strategy == SecureNative::FailOverStrategy::FAIL_OPEN
25
+ return SecureNative::VerifyResult.new(risk_level: SecureNative::Enums::RiskLevel::LOW, score: 0, triggers: [])
26
+ end
27
+ return VerifyResult.new(risk_level: SecureNative::Enums::RiskLevel::HIGH, score: 1, triggers: [])
28
+ end
23
29
  return VerifyResult.new(risk_level: ver_result['riskLevel'], score: ver_result['score'], triggers: ver_result['triggers'])
24
30
  rescue StandardError => e
25
31
  SecureNative::Log.debug("Failed to call verify; #{e}")
@@ -34,7 +34,7 @@ module SecureNative
34
34
  # Standard Ruby request
35
35
  headers = request.header.to_hash if headers.nil?
36
36
  rescue StandardError
37
- headers = []
37
+ headers = {}
38
38
  end
39
39
 
40
40
  url = SecureNative::Frameworks::Rails.get_url(request)
@@ -62,7 +62,7 @@ class EventManager
62
62
  res = @http_client.post(resource_path, EventManager.serialize(event).to_json)
63
63
 
64
64
  if res.nil? || res.code != '200'
65
- SecureNative::Log.info("SecureNative failed to call endpoint #{resource_path} with event #{event}. adding back to queue")
65
+ SecureNative::Log.info("SecureNative failed to call endpoint #{resource_path} with event #{event}")
66
66
  end
67
67
 
68
68
  res
@@ -35,8 +35,18 @@ module SecureNative
35
35
 
36
36
  def self.get_headers(request)
37
37
  begin
38
- # Note: At the moment we're filtering out everything but user-agent since ruby's payload is way too big
39
- { 'user-agent' => request.env['HTTP_USER_AGENT'] }
38
+ headers = {}
39
+
40
+ request.env.select { |k, _| k.in?(ActionDispatch::Http::Headers::CGI_VARIABLES) || k =~ /^HTTP_/ }.each { |header|
41
+ headers[header[0].downcase.gsub("http_", "").gsub("_", "-")] = header[1]
42
+ }
43
+
44
+ if headers.length == 0
45
+ request.headers.env.select { |k, _| k.in?(ActionDispatch::Http::Headers::CGI_VARIABLES) || k =~ /^HTTP_/ }.each { |header|
46
+ headers[header[0].downcase.gsub("http_", "").gsub("_", "-")] = header[1]
47
+ }
48
+ end
49
+ return headers
40
50
  rescue StandardError
41
51
  nil
42
52
  end
@@ -37,8 +37,18 @@ module SecureNative
37
37
 
38
38
  def self.get_headers(request)
39
39
  begin
40
- # Note: At the moment we're filtering out everything but user-agent since ruby's payload is way too big
41
- {'user-agent' => request.env['HTTP_USER_AGENT']}
40
+ headers = {}
41
+
42
+ request.env.select { |k, _| k.in?(ActionDispatch::Http::Headers::CGI_VARIABLES) || k =~ /^HTTP_/ }.each { |header|
43
+ headers[header[0].downcase.gsub("http_", "").gsub("_", "-")] = header[1]
44
+ }
45
+
46
+ if headers.length == 0
47
+ request.headers.env.select { |k, _| k.in?(ActionDispatch::Http::Headers::CGI_VARIABLES) || k =~ /^HTTP_/ }.each { |header|
48
+ headers[header[0].downcase.gsub("http_", "").gsub("_", "-")] = header[1]
49
+ }
50
+ end
51
+ return headers
42
52
  rescue StandardError
43
53
  nil
44
54
  end
@@ -35,8 +35,18 @@ module SecureNative
35
35
 
36
36
  def self.get_headers(request)
37
37
  begin
38
- # Note: At the moment we're filtering out everything but user-agent since ruby's payload is way too big
39
- {'user-agent' => request.env['HTTP_USER_AGENT']}
38
+ headers = {}
39
+
40
+ request.env.select { |k, _| k.in?(ActionDispatch::Http::Headers::CGI_VARIABLES) || k =~ /^HTTP_/ }.each { |header|
41
+ headers[header[0].downcase.gsub("http_", "").gsub("_", "-")] = header[1]
42
+ }
43
+
44
+ if headers.length == 0
45
+ request.headers.env.select { |k, _| k.in?(ActionDispatch::Http::Headers::CGI_VARIABLES) || k =~ /^HTTP_/ }.each { |header|
46
+ headers[header[0].downcase.gsub("http_", "").gsub("_", "-")] = header[1]
47
+ }
48
+ end
49
+ return headers
40
50
  rescue StandardError
41
51
  nil
42
52
  end
@@ -27,7 +27,7 @@ module SecureNative
27
27
  headers = _headers
28
28
 
29
29
  client = Net::HTTP.new(uri.host, uri.port)
30
- client.read_timeout = @options.timeout
30
+ client.read_timeout = @options.timeout / 1000
31
31
  client.use_ssl = true
32
32
  client.verify_mode = OpenSSL::SSL::VERIFY_NONE
33
33
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ipaddr'
4
+
3
5
  module SecureNative
4
6
  module Utils
5
7
  class RequestUtils
@@ -24,14 +26,20 @@ module SecureNative
24
26
  if h.nil?
25
27
  h = request.env[self.parse_ip(header)]
26
28
  end
27
- return h.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless h.nil?
29
+ parsed = self.parse_proxy_header(h, header)
30
+ if self.validate_ip(parsed)
31
+ return parsed
32
+ end
28
33
  rescue NoMethodError
29
34
  begin
30
35
  h = request[header]
31
36
  if h.nil?
32
37
  h = request.env[self.parse_ip(header)]
33
38
  end
34
- return h.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless h.nil?
39
+ parsed = self.parse_proxy_header(h, header)
40
+ if self.validate_ip(parsed)
41
+ return parsed
42
+ end
35
43
  rescue NoMethodError
36
44
  # Ignored
37
45
  end
@@ -40,36 +48,66 @@ module SecureNative
40
48
  end
41
49
 
42
50
  begin
43
- x_forwarded_for = request.env['HTTP_X_FORWARDED_FOR']
44
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
51
+ header_value = request.env['HTTP_X_FORWARDED_FOR']
52
+ if header_value.include? ','
53
+ header_value = ip.split(',')[0]
54
+ end
55
+ if self.validate_ip(header_value)
56
+ return header_value
57
+ end
45
58
  rescue NoMethodError
46
59
  begin
47
- x_forwarded_for = request['HTTP_X_FORWARDED_FOR']
48
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
60
+ header_value = request['HTTP_X_FORWARDED_FOR']
61
+ if header_value.include? ','
62
+ header_value = ip.split(',')[0]
63
+ end
64
+ if self.validate_ip(header_value)
65
+ return header_value
66
+ end
49
67
  rescue NoMethodError
50
68
  # Ignored
51
69
  end
52
70
  end
53
71
 
54
72
  begin
55
- x_forwarded_for = request.env['HTTP_X_REAL_IP']
56
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
73
+ header_value = request.env['HTTP_X_REAL_IP']
74
+ if header_value.include? ','
75
+ header_value = ip.split(',')[0]
76
+ end
77
+ if self.validate_ip(header_value)
78
+ return header
79
+ end
57
80
  rescue NoMethodError
58
81
  begin
59
- x_forwarded_for = request['HTTP_X_REAL_IP']
60
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
82
+ header_value = request['HTTP_X_REAL_IP']
83
+ if header_value.include? ','
84
+ header_value = ip.split(',')[0]
85
+ end
86
+ if self.validate_ip(header_value)
87
+ return header_value
88
+ end
61
89
  rescue NoMethodError
62
90
  # Ignored
63
91
  end
64
92
  end
65
93
 
66
94
  begin
67
- x_forwarded_for = request.env['REMOTE_ADDR']
68
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
95
+ header_value = request.env['REMOTE_ADDR']
96
+ if header_value.include? ','
97
+ header_value = ip.split(',')[0]
98
+ end
99
+ if self.validate_ip(header_value)
100
+ return header_value
101
+ end
69
102
  rescue NoMethodError
70
103
  begin
71
- x_forwarded_for = request['REMOTE_ADDR']
72
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
104
+ header_value = request['REMOTE_ADDR']
105
+ if header_value.include? ','
106
+ header_value = ip.split(',')[0]
107
+ end
108
+ if self.validate_ip(header_value)
109
+ return header_value
110
+ end
73
111
  rescue NoMethodError
74
112
  # Ignored
75
113
  end
@@ -96,6 +134,35 @@ module SecureNative
96
134
  h = headers.gsub('-', '_')
97
135
  return PREFIX + h.upcase
98
136
  end
137
+
138
+ def self.parse_proxy_header(headers, header_key)
139
+ h = headers.gsub(header_key + ': ', '')
140
+ if headers.include? ','
141
+ h = h.split(',')[0]
142
+ end
143
+ return h
144
+ end
145
+
146
+ def self.validate_ip(ip)
147
+ if ip.nil?
148
+ return false
149
+ end
150
+
151
+ begin
152
+ ipaddr = IPAddr.new(ip)
153
+ if ipaddr.ipv4?
154
+ return true
155
+ end
156
+
157
+ if ipaddr.ipv6?
158
+ return true
159
+ end
160
+ rescue Exception
161
+ # Ignored
162
+ end
163
+
164
+ return false
165
+ end
99
166
  end
100
167
  end
101
168
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SecureNative
4
- VERSION = '0.1.33'
4
+ VERSION = '0.1.38'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: securenative
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.33
4
+ version: 0.1.38
5
5
  platform: ruby
6
6
  authors:
7
7
  - SecureNative
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-04 00:00:00.000000000 Z
11
+ date: 2020-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler