perimeter_x 1.3.0 → 2.2.1

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
- SHA1:
3
- metadata.gz: 1f3a1b696f592b2f1478cc376a96475a5d5f0778
4
- data.tar.gz: e859865af132477c953d6aed1a7c70bb927b432e
2
+ SHA256:
3
+ metadata.gz: 1cb2ccba081bcd941104fd775fc6d047b1b82f9adc6c43619ab860ab1c9685b5
4
+ data.tar.gz: 11b5d9a8addcbc817e7e8f30ba5216e3b16c8392088abbc6c72295b53a39720e
5
5
  SHA512:
6
- metadata.gz: 1f67c50466d0a347d7d5e3dc6c30f66332a3dabb27a34152e49c36a6614fa06ce81bc02d8f50ba2e061f9fb4cef8b21e9fb684d2d2b8b138ffab87298d0e1f81
7
- data.tar.gz: 35d39968545b296e04f02bed0bb2c67b40ca1ff6773e352533fbe06e2795ad630a838d159fe517a12702e79d5054d81ef828fa966e9278dec7fd6eaa37dd2e06
6
+ metadata.gz: 205b0471f18b749671b9f481af16d032c4559b6505e1f6a1198883ea8935f8acf11583433b14ba88a1e51e0eadd004462e49d2167e6e7bd09fe0ddcf4a2afd98
7
+ data.tar.gz: 5767dbf74d101d8859b5c74453d9e5ea314721d7bb3489678e0837448bca5eff1210d7fe387d0bae40c5a3ae0de0d305eb55faa4c6d28619e32b29e704c2d0f7
@@ -1,3 +1,3 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.3
3
+ - 2.7.1
data/Dockerfile CHANGED
@@ -1,21 +1,26 @@
1
1
  # Based on manual compile instructions at http://wiki.nginx.org/HttpLuaModule#Installation
2
- FROM ruby:2.3.0
2
+ FROM ruby:2.7.1
3
3
 
4
- RUN apt-get update && apt-get --force-yes -qq -y install \
5
- nodejs
6
- ENV RAILS_VERSION 4.2.0
4
+ RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg -o /root/yarn-pubkey.gpg && apt-key add /root/yarn-pubkey.gpg
5
+ RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
6
+ RUN apt-get update && apt-get install -y --no-install-recommends nodejs yarn vim
7
+
8
+ ENV RAILS_VERSION 6.0.3.2
7
9
  RUN gem install rails --version "$RAILS_VERSION"
8
10
  RUN gem install bundler
9
11
  RUN mkdir -p /tmp/ruby_sandbox
10
12
  WORKDIR /tmp/ruby_sandbox
11
- RUN git clone https://github.com/PerimeterX/perimeterx-ruby-sdk.git
13
+ COPY lib /tmp/ruby_sandbox/lib
14
+ COPY Gemfile /tmp/ruby_sandbox/
15
+ COPY perimeter_x.gemspec /tmp/ruby_sandbox/
16
+ COPY Rakefile /tmp/ruby_sandbox/
12
17
  RUN rails new webapp
13
18
  WORKDIR /tmp/ruby_sandbox/webapp
14
19
 
15
20
  RUN rails generate controller home index
16
21
  WORKDIR /tmp/ruby_sandbox/webapp
17
22
  EXPOSE 3000
18
- RUN sed -i '2i gem "perimeter_x", :path => "/tmp/ruby_sandbox/perimeterx-ruby-sdk"' /tmp/ruby_sandbox/webapp/Gemfile
23
+ RUN sed -i '2i gem "perimeter_x", :path => "/tmp/ruby_sandbox"' /tmp/ruby_sandbox/webapp/Gemfile
19
24
  RUN bundler update
20
- COPY ./examples/ /tmp/ruby_sandbox/webapp
25
+ COPY ./dev/site/ /tmp/ruby_sandbox/webapp
21
26
  CMD ["rails","server","-b","0.0.0.0"]
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- perimeter_x (1.3.0)
5
- activesupport (>= 4.2.0)
4
+ perimeter_x (2.0.0)
5
+ activesupport (>= 5.2.4.3)
6
6
  concurrent-ruby (~> 1.0, >= 1.0.5)
7
7
  mustache (~> 1.0, >= 1.0.3)
8
8
  typhoeus (~> 1.1, >= 1.1.2)
@@ -10,51 +10,52 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (5.0.2)
13
+ activesupport (6.0.3.2)
14
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
15
- i18n (~> 0.7)
15
+ i18n (>= 0.7, < 2)
16
16
  minitest (~> 5.1)
17
17
  tzinfo (~> 1.1)
18
- concurrent-ruby (1.0.5)
19
- diff-lcs (1.3)
20
- ethon (0.10.1)
18
+ zeitwerk (~> 2.2, >= 2.2.2)
19
+ concurrent-ruby (1.1.6)
20
+ diff-lcs (1.4.4)
21
+ ethon (0.12.0)
21
22
  ffi (>= 1.3.0)
22
- ffi (1.9.18)
23
- i18n (0.8.6)
24
- metaclass (0.0.4)
25
- minitest (5.10.1)
26
- mocha (1.2.1)
27
- metaclass (~> 0.0.1)
28
- mustache (1.0.5)
29
- rake (10.4.2)
30
- rspec (3.5.0)
31
- rspec-core (~> 3.5.0)
32
- rspec-expectations (~> 3.5.0)
33
- rspec-mocks (~> 3.5.0)
34
- rspec-core (3.5.4)
35
- rspec-support (~> 3.5.0)
36
- rspec-expectations (3.5.0)
23
+ ffi (1.13.1)
24
+ i18n (1.8.3)
25
+ concurrent-ruby (~> 1.0)
26
+ minitest (5.14.1)
27
+ mocha (1.11.2)
28
+ mustache (1.1.1)
29
+ rake (13.0.1)
30
+ rspec (3.9.0)
31
+ rspec-core (~> 3.9.0)
32
+ rspec-expectations (~> 3.9.0)
33
+ rspec-mocks (~> 3.9.0)
34
+ rspec-core (3.9.2)
35
+ rspec-support (~> 3.9.3)
36
+ rspec-expectations (3.9.2)
37
37
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.5.0)
39
- rspec-mocks (3.5.0)
38
+ rspec-support (~> 3.9.0)
39
+ rspec-mocks (3.9.1)
40
40
  diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.5.0)
42
- rspec-support (3.5.0)
41
+ rspec-support (~> 3.9.0)
42
+ rspec-support (3.9.3)
43
43
  thread_safe (0.3.6)
44
- typhoeus (1.1.2)
44
+ typhoeus (1.4.0)
45
45
  ethon (>= 0.9.0)
46
- tzinfo (1.2.3)
46
+ tzinfo (1.2.7)
47
47
  thread_safe (~> 0.1)
48
+ zeitwerk (2.3.1)
48
49
 
49
50
  PLATFORMS
50
51
  ruby
51
52
 
52
53
  DEPENDENCIES
53
- bundler (~> 1.14)
54
+ bundler (>= 2.1)
54
55
  mocha (~> 1.2, >= 1.2.1)
55
56
  perimeter_x!
56
- rake (~> 10.0)
57
+ rake (>= 12.3)
57
58
  rspec (~> 3.0)
58
59
 
59
60
  BUNDLED WITH
60
- 1.14.6
61
+ 2.1.4
@@ -5,7 +5,61 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/).
7
7
 
8
- ## [1.3.0] - 2017-06-04
8
+ ## [2.2.1] - 2020-09-27
9
+ ### Fixed
10
+ - bypass_monitor_header type validation
11
+
12
+ ## [2.2.0] - 2020-09-15
13
+ ### Added
14
+ - First Party
15
+
16
+ ## [2.1.0] - 2020-09-01
17
+ ### Added
18
+ - Added option to set a different px configuration on each request
19
+ - Added types validation on configuration fields
20
+
21
+ ### Fixed
22
+ - New cookie logic for mobile requests
23
+ - Renamed api_connect_timeout to api_timeout_conncection on default configuration
24
+ - Removed unsapported configuration fields: max_buffer_len and local_proxy
25
+ - Send cookie_origin only if there is a cookie
26
+
27
+ ## [2.0.0] - 2020-07-24
28
+ ### Added
29
+ - Added fields to Block Activity: simulated_block, http_version, http_method, risk_rtt, px_orig_cookie
30
+ - Added fields to page_requested activity: pass_reason, risk_rtt, px_orig_cookie
31
+ - Added px_orig_cookie field to risk_api in case of cookie_decryption_failed
32
+ - Added support for captcha v2
33
+ - Added support for Advanced Blocking Response
34
+ - Added support for whitelise routes
35
+ - Added support for bypass monitor header
36
+ - Added support for extracting vid from _pxvid cookie
37
+ - Added support for rate limit
38
+ - Added risk_cookie_max_iterations configuration
39
+
40
+ ### Fixed
41
+ - Updated dependencies
42
+ - Updated sample site dockerfile
43
+ - Fixed monitor mode
44
+ - Fixed send_page_activities and send_block_activities configurations
45
+ - Updated risk to v3
46
+ - Refactored ip header extraction
47
+ - Renamed block_uuid field to client_uuid
48
+ - Renamed perimeterx_server_host configuration to backend_url
49
+ - Updated risk_response handling: pass the request if risk_response.status is -1
50
+ - Forcing http header values to be utf8
51
+
52
+ ## [1.4.0] - 2018-03-18
53
+ ### Fixed
54
+ - Incorrect assigment for s2s_call_reason
55
+ - Fixed empty token result correct s2s reason
56
+
57
+ ### Added
58
+ - Added support to captcha api v2
59
+ - Mobile sdk support for special tokens 1/2/3
60
+
61
+
62
+ ## [1.3.0] - 2017-07-27
9
63
  ### Added
10
64
  - Sending client_uuid on page_requested activities
11
65
  - Supporting mobile sdk
@@ -1,6 +1,7 @@
1
1
  require 'concurrent'
2
2
  require 'json'
3
3
  require 'base64'
4
+ require 'uri'
4
5
  require 'perimeterx/configuration'
5
6
  require 'perimeterx/utils/px_logger'
6
7
  require 'perimeterx/utils/px_constants'
@@ -10,128 +11,217 @@ require 'perimeterx/internal/perimeter_x_context'
10
11
  require 'perimeterx/internal/clients/perimeter_x_activity_client'
11
12
  require 'perimeterx/internal/validators/perimeter_x_s2s_validator'
12
13
  require 'perimeterx/internal/validators/perimeter_x_cookie_validator'
13
- require 'perimeterx/internal/validators/perimeter_x_captcha_validator'
14
+ require 'perimeterx/internal/exceptions/px_config_exception'
15
+ require 'perimeterx/internal/first_party/px_first_party'
14
16
 
15
17
  module PxModule
16
18
  # Module expose API
17
- def px_verify_request
18
- verified, px_ctx = PerimeterX.instance.verify(request.env)
19
-
20
- # Invalidate _pxCaptcha, can be done only on the controller level
21
- cookies[:_pxCaptcha] = {value: "", expires: -1.minutes.from_now}
22
-
23
- unless verified
24
- # In case custon block handler exists
25
- if (PerimeterX.instance.px_config.key?(:custom_block_handler))
26
- PerimeterX.instance.px_config[:logger].debug('PxModule[px_verify_request]: custom_block_handler triggered')
27
- return instance_exec(px_ctx, &PerimeterX.instance.px_config[:custom_block_handler])
28
- else
29
- # Generate template
30
- PerimeterX.instance.px_config[:logger].debug('PxModule[px_verify_request]: sending default block page')
31
- html = PxTemplateFactory.get_template(px_ctx, PerimeterX.instance.px_config)
32
- response.headers['Content-Type'] = 'text/html'
33
- response.status = 403
34
- # Web handler
35
- if px_ctx.context[:cookie_origin] == 'cookie'
36
- PerimeterX.instance.px_config[:logger].debug('PxModule[px_verify_request]: web block')
37
- response.headers['Content-Type'] = 'text/html'
38
- render :html => html
39
- else # Mobile SDK
40
- PerimeterX.instance.px_config[:logger].debug('PxModule[px_verify_request]: mobile sdk block')
41
- response.headers['Content-Type'] = 'application/json'
42
- hash_json = {
43
- :action => px_ctx.context[:block_action],
44
- :uuid => px_ctx.context[:uuid],
45
- :vid => px_ctx.context[:vid],
46
- :appId => PerimeterX.instance.px_config[:app_id],
47
- :page => Base64.strict_encode64(html),
48
- :collectorUrl => "https://collector-#{PerimeterX.instance.px_config[:app_id]}.perimeterx.net"
49
- }
50
- render :json => hash_json
19
+ def px_verify_request(request_config={})
20
+ begin
21
+ px_instance = PerimeterX.new(request_config)
22
+ req = ActionDispatch::Request.new(request.env)
23
+
24
+ # handle first party requests
25
+ if px_instance.first_party.is_first_party_request(req)
26
+ render_first_party_response(req, px_instance)
27
+ return true
28
+ end
29
+
30
+ # verify request
31
+ px_ctx = px_instance.verify(req)
32
+ px_config = px_instance.px_config
33
+
34
+ msg_title = 'PxModule[px_verify_request]'
35
+
36
+ # In case custom verification handler is in use
37
+ if px_config.key?(:custom_verification_handler)
38
+ px_config[:logger].debug("#{msg_title}: custom_verification_handler triggered")
39
+ return instance_exec(px_ctx, &px_config[:custom_verification_handler])
40
+ end
41
+
42
+ unless px_ctx.nil? || px_ctx.context[:verified] || (px_config[:module_mode] == PxModule::MONITOR_MODE && !px_ctx.context[:should_bypass_monitor])
43
+ # In case custom block handler exists (soon to be deprecated)
44
+ if px_config.key?(:custom_block_handler)
45
+ px_config[:logger].debug("#{msg_title}: custom_block_handler triggered")
46
+ px_config[:logger].debug(
47
+ "#{msg_title}: Please note that custom_block_handler is deprecated. Use custom_verification_handler instead.")
48
+ return instance_exec(px_ctx, &px_config[:custom_block_handler])
49
+ else
50
+ if px_ctx.context[:block_action]== 'rate_limit'
51
+ px_config[:logger].debug("#{msg_title}: sending rate limit page")
52
+ response.status = 429
53
+ else
54
+ px_config[:logger].debug("#{msg_title}: sending default block page")
55
+ response.status = 403
56
+ end
57
+
58
+ is_mobile = px_ctx.context[:cookie_origin] == 'header' ? '1' : '0'
59
+ action = px_ctx.context[:block_action][0,1]
60
+
61
+ if px_config[:first_party_enabled]
62
+ px_template_object = {
63
+ js_client_src: "/#{px_config[:app_id][2..-1]}/init.js",
64
+ block_script: "/#{px_config[:app_id][2..-1]}/captcha/#{px_config[:app_id]}/captcha.js?a=#{action}&u=#{px_ctx.context[:uuid]}&v=#{px_ctx.context[:vid]}&m=#{is_mobile}",
65
+ host_url: "/#{px_config[:app_id][2..-1]}/xhr"
66
+ }
67
+ else
68
+ px_template_object = {
69
+ js_client_src: "//#{PxModule::CLIENT_HOST}/#{px_config[:app_id]}/main.min.js",
70
+ block_script: "//#{PxModule::CAPTCHA_HOST}/#{px_config[:app_id]}/captcha.js?a=#{action}&u=#{px_ctx.context[:uuid]}&v=#{px_ctx.context[:vid]}&m=#{is_mobile}",
71
+ host_url: "https://collector-#{px_config[:app_id]}.perimeterx.net"
72
+ }
73
+ end
74
+
75
+ html = PxTemplateFactory.get_template(px_ctx, px_config, px_template_object)
76
+
77
+ # Web handler
78
+ if px_ctx.context[:cookie_origin] == 'cookie'
79
+
80
+ accept_header_value = request.headers['accept'] || request.headers['content-type'];
81
+ is_json_response = px_ctx.context[:block_action] != 'rate_limit' && accept_header_value && accept_header_value.split(',').select {|e| e.downcase.include? 'application/json'}.length > 0;
82
+
83
+ if (is_json_response)
84
+ px_config[:logger].debug("#{msg_title}: advanced blocking response response")
85
+ response.headers['Content-Type'] = 'application/json'
86
+
87
+ hash_json = {
88
+ :appId => px_config[:app_id],
89
+ :jsClientSrc => px_template_object[:js_client_src],
90
+ :firstPartyEnabled => px_ctx.context[:first_party_enabled],
91
+ :uuid => px_ctx.context[:uuid],
92
+ :vid => px_ctx.context[:vid],
93
+ :hostUrl => "https://collector-#{px_config[:app_id]}.perimeterx.net",
94
+ :blockScript => px_template_object[:block_script],
95
+ }
96
+
97
+ render :json => hash_json
98
+ else
99
+ px_config[:logger].debug('#{msg_title}: web block')
100
+ response.headers['Content-Type'] = 'text/html'
101
+ render :html => html
102
+ end
103
+ else # Mobile SDK
104
+ px_config[:logger].debug("#{msg_title}: mobile sdk block")
105
+ response.headers['Content-Type'] = 'application/json'
106
+ hash_json = {
107
+ :action => px_ctx.context[:block_action],
108
+ :uuid => px_ctx.context[:uuid],
109
+ :vid => px_ctx.context[:vid],
110
+ :appId => px_config[:app_id],
111
+ :page => Base64.strict_encode64(html),
112
+ :collectorUrl => "https://collector-#{px_config[:app_id]}.perimeterx.net"
113
+ }
114
+ render :json => hash_json
115
+ end
51
116
  end
52
117
  end
118
+
119
+ # Request was verified
120
+ return px_ctx.nil? ? true : px_ctx.context[:verified]
121
+
122
+ rescue PxConfigurationException
123
+ raise
124
+ rescue Exception => e
125
+ error_logger = PxLogger.new(true)
126
+ error_logger.error("#{e.backtrace.first}: #{e.message} (#{e.class})")
127
+ e.backtrace.drop(1).map {|s| error_logger.error("\t#{s}")}
128
+ return nil
53
129
  end
130
+ end
54
131
 
55
- # Request was verified
56
- return verified
132
+ def render_first_party_response(req, px_instance)
133
+ fp = px_instance.first_party
134
+ px_config = px_instance.px_config
135
+
136
+ if px_config[:first_party_enabled]
137
+ # first party enabled - proxy response
138
+ fp_response = fp.send_first_party_request(req)
139
+ response.status = fp_response.code
140
+ fp_response.to_hash.each do |header_name, header_value_arr|
141
+ if header_name!="content-length"
142
+ response.headers[header_name] = header_value_arr[0]
143
+ end
144
+ end
145
+ res_type = fp.get_response_content_type(req)
146
+ render res_type => fp_response.body
147
+ else
148
+ # first party disabled - return empty response
149
+ response.status = 200
150
+ res_type = fp.get_response_content_type(req)
151
+ render res_type => ""
152
+ end
57
153
  end
58
154
 
59
- def self.configure(params)
60
- @px_instance = PerimeterX.configure(params)
155
+ def self.configure(basic_config)
156
+ PerimeterX.set_basic_config(basic_config)
61
157
  end
62
158
 
63
159
 
64
160
  # PerimeterX Module
65
161
  class PerimeterX
66
- @@__instance = nil
67
- @@mutex = Mutex.new
68
162
 
69
163
  attr_reader :px_config
164
+ attr_reader :first_party
70
165
  attr_accessor :px_http_client
71
166
  attr_accessor :px_activity_client
72
167
 
73
168
  #Static methods
74
- def self.configure(params)
75
- return true if @@__instance
76
- @@mutex.synchronize {
77
- return @@__instance if @@__instance
78
- @@__instance = new(params)
79
- }
80
- return true
169
+ def self.set_basic_config(basic_config)
170
+ Configuration.set_basic_config(basic_config)
81
171
  end
82
172
 
83
- def self.instance
84
- return @@__instance if !@@__instance.nil?
85
- raise Exception.new('Please initialize perimeter x first')
86
- end
87
-
88
-
89
173
  #Instance Methods
90
- def verify(env)
174
+ def verify(req)
91
175
  begin
176
+
177
+ # check module_enabled
92
178
  @logger.debug('PerimeterX[pxVerify]')
93
- if (!@px_config[:module_enabled])
179
+ if !@px_config[:module_enabled]
94
180
  @logger.warn('Module is disabled')
95
- return true
181
+ return nil
96
182
  end
97
- req = ActionDispatch::Request.new(env)
98
- px_ctx = PerimeterXContext.new(@px_config, req)
99
-
100
- # Captcha phase
101
- captcha_verified, px_ctx = @px_captcha_validator.verify(px_ctx)
102
- if (captcha_verified)
103
- return handle_verification(px_ctx)
183
+
184
+ # filter whitelist routes
185
+ url_path = URI.parse(req.original_url).path
186
+ if url_path && !url_path.empty?
187
+ if check_whitelist_routes(px_config[:whitelist_routes], url_path)
188
+ @logger.debug("PerimeterX[pxVerify]: whitelist route: #{url_path}")
189
+ return nil
190
+ end
104
191
  end
192
+
193
+ # create context
194
+ px_ctx = PerimeterXContext.new(@px_config, req)
105
195
 
106
196
  # Cookie phase
107
197
  cookie_verified, px_ctx = @px_cookie_validator.verify(px_ctx)
108
- if (!cookie_verified)
198
+ if !cookie_verified
199
+ if !px_ctx.context[:mobile_error].nil?
200
+ px_ctx.context[:s2s_call_reason] = "mobile_error_#{px_ctx.context[:mobile_error]}"
201
+ end
109
202
  @px_s2s_validator.verify(px_ctx)
110
203
  end
111
204
 
112
- if (@px_config.key?(:custom_verification_handler))
113
- return @px_config[:custom_verification_handler].call(px_ctx.context)
114
- else
115
- return handle_verification(px_ctx)
116
- end
205
+ return handle_verification(px_ctx)
117
206
  rescue Exception => e
118
207
  @logger.error("#{e.backtrace.first}: #{e.message} (#{e.class})")
119
208
  e.backtrace.drop(1).map {|s| @logger.error("\t#{s}")}
120
- return true
209
+ return nil
121
210
  end
122
211
  end
123
212
 
124
- private def initialize(params)
125
- @px_config = Configuration.new(params).configuration
213
+ def initialize(request_config)
214
+
215
+ @px_config = Configuration.new(request_config).configuration
126
216
  @logger = @px_config[:logger]
127
217
  @px_http_client = PxHttpClient.new(@px_config)
128
218
 
129
219
  @px_activity_client = PerimeterxActivitiesClient.new(@px_config, @px_http_client)
220
+ @first_party = FirstPartyManager.new(@px_config, @px_http_client, @logger)
130
221
 
131
222
  @px_cookie_validator = PerimeterxCookieValidator.new(@px_config)
132
223
  @px_s2s_validator = PerimeterxS2SValidator.new(@px_config, @px_http_client)
133
- @px_captcha_validator = PerimeterxCaptchaValidator.new(@px_config, @px_http_client)
134
- @logger.debug('PerimeterX[initialize]Z')
224
+ @logger.debug('PerimeterX[initialize]')
135
225
  end
136
226
 
137
227
  private def handle_verification(px_ctx)
@@ -139,27 +229,41 @@ module PxModule
139
229
  @logger.debug("PerimeterX[handle_verification]: processing ended - score:#{px_ctx.context[:score]}, uuid:#{px_ctx.context[:uuid]}")
140
230
 
141
231
  score = px_ctx.context[:score]
232
+ px_ctx.context[:should_bypass_monitor] = @px_config[:bypass_monitor_header] && px_ctx.context[:headers][@px_config[:bypass_monitor_header].to_sym] == '1';
233
+
234
+ px_ctx.context[:verified] = score < @px_config[:blocking_score]
142
235
  # Case PASS request
143
- if (score < @px_config[:blocking_score])
236
+ if px_ctx.context[:verified]
144
237
  @logger.debug("PerimeterX[handle_verification]: score:#{score} < blocking score, passing request")
145
238
  @px_activity_client.send_page_requested_activity(px_ctx)
146
- return true
239
+ return px_ctx
147
240
  end
148
241
 
149
242
  # Case blocking activity
150
243
  @px_activity_client.send_block_activity(px_ctx)
151
244
 
152
245
  # In case were in monitor mode, end here
153
- if (@px_config[:module_mode] == PxModule::MONITOR_MODE)
154
- @logger.debug('PerimeterX[handle_verification]: monitor mode is on, passing request')
155
- return true
246
+ if @px_config[:module_mode] == PxModule::MONITOR_MODE && !px_ctx.context[:should_bypass_monitor]
247
+ @logger.debug("PerimeterX[handle_verification]: monitor mode is on, passing request")
248
+ return px_ctx
156
249
  end
157
250
 
158
251
  @logger.debug('PerimeterX[handle_verification]: verification ended, the request should be blocked')
159
252
 
160
- return false, px_ctx
253
+ return px_ctx
254
+ end
255
+
256
+ private def check_whitelist_routes(whitelist_routes, path)
257
+ whitelist_routes.each do |whitelist_route|
258
+ if whitelist_route.is_a?(Regexp) && path.match(whitelist_route)
259
+ return true
260
+ end
261
+ if whitelist_route.is_a?(String) && path.start_with?(whitelist_route)
262
+ return true
263
+ end
264
+ end
265
+ false
161
266
  end
162
267
 
163
- private_class_method :new
164
268
  end
165
269
  end