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 +5 -5
- data/.travis.yml +1 -1
- data/Dockerfile +12 -7
- data/Gemfile.lock +32 -31
- data/changelog.md +55 -1
- data/lib/perimeter_x.rb +186 -82
- data/lib/perimeterx/configuration.rb +74 -22
- data/lib/perimeterx/internal/clients/perimeter_x_activity_client.rb +29 -6
- data/lib/perimeterx/internal/exceptions/px_config_exception.rb +6 -0
- data/lib/perimeterx/internal/first_party/px_first_party.rb +124 -0
- data/lib/perimeterx/internal/payload/perimeter_x_payload.rb +3 -0
- data/lib/perimeterx/internal/perimeter_x_context.rb +50 -19
- data/lib/perimeterx/internal/validators/hash_schema_validator.rb +26 -0
- data/lib/perimeterx/internal/validators/perimeter_x_cookie_validator.rb +17 -12
- data/lib/perimeterx/internal/validators/perimeter_x_s2s_validator.rb +30 -7
- data/lib/perimeterx/utils/px_constants.rb +17 -5
- data/lib/perimeterx/utils/px_http_client.rb +59 -2
- data/lib/perimeterx/utils/px_template_factory.rb +13 -9
- data/lib/perimeterx/utils/templates/{captcha.mobile.mustache → block_template.mustache} +48 -69
- data/lib/perimeterx/utils/templates/ratelimit.mustache +9 -0
- data/lib/perimeterx/version.rb +1 -1
- data/perimeter_x.gemspec +3 -3
- data/readme.md +106 -40
- metadata +18 -19
- data/lib/perimeterx/internal/validators/perimeter_x_captcha_validator.rb +0 -65
- data/lib/perimeterx/utils/templates/block.mobile.mustache +0 -133
- data/lib/perimeterx/utils/templates/block.mustache +0 -146
- data/lib/perimeterx/utils/templates/captcha.mustache +0 -185
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1cb2ccba081bcd941104fd775fc6d047b1b82f9adc6c43619ab860ab1c9685b5
|
4
|
+
data.tar.gz: 11b5d9a8addcbc817e7e8f30ba5216e3b16c8392088abbc6c72295b53a39720e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 205b0471f18b749671b9f481af16d032c4559b6505e1f6a1198883ea8935f8acf11583433b14ba88a1e51e0eadd004462e49d2167e6e7bd09fe0ddcf4a2afd98
|
7
|
+
data.tar.gz: 5767dbf74d101d8859b5c74453d9e5ea314721d7bb3489678e0837448bca5eff1210d7fe387d0bae40c5a3ae0de0d305eb55faa4c6d28619e32b29e704c2d0f7
|
data/.travis.yml
CHANGED
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.
|
2
|
+
FROM ruby:2.7.1
|
3
3
|
|
4
|
-
RUN
|
5
|
-
|
6
|
-
|
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
|
-
|
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
|
23
|
+
RUN sed -i '2i gem "perimeter_x", :path => "/tmp/ruby_sandbox"' /tmp/ruby_sandbox/webapp/Gemfile
|
19
24
|
RUN bundler update
|
20
|
-
COPY ./
|
25
|
+
COPY ./dev/site/ /tmp/ruby_sandbox/webapp
|
21
26
|
CMD ["rails","server","-b","0.0.0.0"]
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
perimeter_x (
|
5
|
-
activesupport (>=
|
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 (
|
13
|
+
activesupport (6.0.3.2)
|
14
14
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
|
-
i18n (
|
15
|
+
i18n (>= 0.7, < 2)
|
16
16
|
minitest (~> 5.1)
|
17
17
|
tzinfo (~> 1.1)
|
18
|
-
|
19
|
-
|
20
|
-
|
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.
|
23
|
-
i18n (
|
24
|
-
|
25
|
-
minitest (5.
|
26
|
-
mocha (1.2
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
rspec-
|
32
|
-
rspec-
|
33
|
-
|
34
|
-
|
35
|
-
|
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.
|
39
|
-
rspec-mocks (3.
|
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.
|
42
|
-
rspec-support (3.
|
41
|
+
rspec-support (~> 3.9.0)
|
42
|
+
rspec-support (3.9.3)
|
43
43
|
thread_safe (0.3.6)
|
44
|
-
typhoeus (1.
|
44
|
+
typhoeus (1.4.0)
|
45
45
|
ethon (>= 0.9.0)
|
46
|
-
tzinfo (1.2.
|
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 (
|
54
|
+
bundler (>= 2.1)
|
54
55
|
mocha (~> 1.2, >= 1.2.1)
|
55
56
|
perimeter_x!
|
56
|
-
rake (
|
57
|
+
rake (>= 12.3)
|
57
58
|
rspec (~> 3.0)
|
58
59
|
|
59
60
|
BUNDLED WITH
|
60
|
-
1.
|
61
|
+
2.1.4
|
data/changelog.md
CHANGED
@@ -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
|
-
## [
|
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
|
data/lib/perimeter_x.rb
CHANGED
@@ -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/
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
:
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
56
|
-
|
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(
|
60
|
-
|
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.
|
75
|
-
|
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(
|
174
|
+
def verify(req)
|
91
175
|
begin
|
176
|
+
|
177
|
+
# check module_enabled
|
92
178
|
@logger.debug('PerimeterX[pxVerify]')
|
93
|
-
if
|
179
|
+
if !@px_config[:module_enabled]
|
94
180
|
@logger.warn('Module is disabled')
|
95
|
-
return
|
181
|
+
return nil
|
96
182
|
end
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
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
|
-
|
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
|
209
|
+
return nil
|
121
210
|
end
|
122
211
|
end
|
123
212
|
|
124
|
-
|
125
|
-
|
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
|
-
@
|
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
|
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
|
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
|
154
|
-
@logger.debug(
|
155
|
-
return
|
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
|
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
|