perimeter_x 1.3.0 → 2.2.1

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.
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