perimeter_x 1.1.0 → 2.1.0
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/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/Dockerfile +19 -43
- data/Gemfile.lock +36 -30
- data/Rakefile +1 -0
- data/changelog.md +63 -0
- data/examples/app/controllers/home_controller.rb +1 -1
- data/lib/perimeter_x.rb +152 -70
- data/lib/perimeterx/configuration.rb +71 -22
- data/lib/perimeterx/internal/clients/perimeter_x_activity_client.rb +36 -15
- data/lib/perimeterx/internal/exceptions/px_config_exception.rb +6 -0
- data/lib/perimeterx/internal/{perimeter_x_cookie_v1.rb → payload/perimeter_x_cookie_v1.rb} +1 -1
- data/lib/perimeterx/internal/{perimeter_x_cookie_v3.rb → payload/perimeter_x_cookie_v3.rb} +1 -1
- data/lib/perimeterx/internal/{perimeter_x_cookie.rb → payload/perimeter_x_payload.rb} +12 -4
- data/lib/perimeterx/internal/payload/perimeter_x_token_v1.rb +38 -0
- data/lib/perimeterx/internal/payload/perimeter_x_token_v3.rb +36 -0
- data/lib/perimeterx/internal/perimeter_x_context.rb +66 -31
- data/lib/perimeterx/internal/validators/hash_schema_validator.rb +26 -0
- data/lib/perimeterx/internal/validators/perimeter_x_cookie_validator.rb +29 -21
- data/lib/perimeterx/internal/validators/perimeter_x_s2s_validator.rb +34 -10
- data/lib/perimeterx/utils/px_constants.rb +35 -17
- data/lib/perimeterx/utils/px_http_client.rb +29 -35
- data/lib/perimeterx/utils/px_template_factory.rb +18 -8
- data/lib/perimeterx/utils/templates/block_template.mustache +175 -0
- data/lib/perimeterx/utils/templates/ratelimit.mustache +9 -0
- data/lib/perimeterx/version.rb +1 -1
- data/perimeter_x.gemspec +5 -4
- data/readme.md +95 -32
- metadata +53 -24
- data/lib/perimeterx/internal/validators/perimeter_x_captcha_validator.rb +0 -65
- 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: d65b91dbf3bdf1829dbfe7b1d44677d86ecde223bc0bd614618d1a9b1a188e84
|
4
|
+
data.tar.gz: 473dc3f4a54232d59c2f89dcc6a1bddbb6a95de0268fddf53cfa28b47e8653d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a89194401d9a60cd41fdb524724329bee547285742c218ffd157337203090ab66f4992fed517389868c639fea175a9c3561663b81b2463a9b1f3fb0011391e7b
|
7
|
+
data.tar.gz: 428757d1a7dafc96543a125db63a8a2c7639ba27673f96bd5222b1628bafcd117f26d1fefb8041179f30e89f5ea286454ebbfb897b0d81d54e5be2be24d6fb8e
|
data/.travis.yml
ADDED
data/Dockerfile
CHANGED
@@ -1,50 +1,26 @@
|
|
1
1
|
# Based on manual compile instructions at http://wiki.nginx.org/HttpLuaModule#Installation
|
2
|
-
FROM
|
3
|
-
RUN apt-get update && apt-get --force-yes -qq -y install \
|
4
|
-
build-essential \
|
5
|
-
ca-certificates \
|
6
|
-
curl \
|
7
|
-
git \
|
8
|
-
libpcre3 \
|
9
|
-
libpcre3-dev \
|
10
|
-
libssl-dev \
|
11
|
-
libreadline-dev \
|
12
|
-
libyaml-dev \
|
13
|
-
libgdbm-dev \
|
14
|
-
libtool \
|
15
|
-
automake \
|
16
|
-
bison \
|
17
|
-
lua-cjson \
|
18
|
-
libncurses5-dev \
|
19
|
-
m4 \
|
20
|
-
libsqlite3-dev \
|
21
|
-
rsyslog \
|
22
|
-
sqlite3 \
|
23
|
-
libxml2-dev \
|
24
|
-
libxslt1-dev \
|
25
|
-
libcurl4-openssl-dev \
|
26
|
-
python-software-properties \
|
27
|
-
libffi-dev \
|
28
|
-
nodejs \
|
29
|
-
wget \
|
30
|
-
zlib1g-dev
|
2
|
+
FROM ruby:2.7.1
|
31
3
|
|
32
|
-
RUN
|
33
|
-
RUN /
|
34
|
-
RUN
|
35
|
-
|
36
|
-
|
37
|
-
RUN
|
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
|
9
|
+
RUN gem install rails --version "$RAILS_VERSION"
|
10
|
+
RUN gem install bundler
|
38
11
|
RUN mkdir -p /tmp/ruby_sandbox
|
39
12
|
WORKDIR /tmp/ruby_sandbox
|
40
|
-
|
41
|
-
|
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/
|
17
|
+
RUN rails new webapp
|
42
18
|
WORKDIR /tmp/ruby_sandbox/webapp
|
43
|
-
|
19
|
+
|
20
|
+
RUN rails generate controller home index
|
44
21
|
WORKDIR /tmp/ruby_sandbox/webapp
|
45
22
|
EXPOSE 3000
|
46
|
-
|
47
|
-
RUN
|
48
|
-
|
49
|
-
|
50
|
-
CMD ["/bin/bash", "-l", "-c", "rails server -b 0.0.0.0;"]
|
23
|
+
RUN sed -i '2i gem "perimeter_x", :path => "/tmp/ruby_sandbox"' /tmp/ruby_sandbox/webapp/Gemfile
|
24
|
+
RUN bundler update
|
25
|
+
COPY ./dev/site/ /tmp/ruby_sandbox/webapp
|
26
|
+
CMD ["rails","server","-b","0.0.0.0"]
|
data/Gemfile.lock
CHANGED
@@ -1,55 +1,61 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
perimeter_x (
|
5
|
-
activesupport (>=
|
6
|
-
|
4
|
+
perimeter_x (2.0.0)
|
5
|
+
activesupport (>= 5.2.4.3)
|
6
|
+
concurrent-ruby (~> 1.0, >= 1.0.5)
|
7
7
|
mustache (~> 1.0, >= 1.0.3)
|
8
|
+
typhoeus (~> 1.1, >= 1.1.2)
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
11
12
|
specs:
|
12
|
-
activesupport (
|
13
|
+
activesupport (6.0.3.2)
|
13
14
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
|
-
i18n (
|
15
|
+
i18n (>= 0.7, < 2)
|
15
16
|
minitest (~> 5.1)
|
16
17
|
tzinfo (~> 1.1)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
rspec-
|
31
|
-
|
32
|
-
rspec-
|
33
|
-
rspec-
|
18
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
19
|
+
concurrent-ruby (1.1.6)
|
20
|
+
diff-lcs (1.4.4)
|
21
|
+
ethon (0.12.0)
|
22
|
+
ffi (>= 1.3.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)
|
34
37
|
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
-
rspec-support (~> 3.
|
36
|
-
rspec-mocks (3.
|
38
|
+
rspec-support (~> 3.9.0)
|
39
|
+
rspec-mocks (3.9.1)
|
37
40
|
diff-lcs (>= 1.2.0, < 2.0)
|
38
|
-
rspec-support (~> 3.
|
39
|
-
rspec-support (3.
|
41
|
+
rspec-support (~> 3.9.0)
|
42
|
+
rspec-support (3.9.3)
|
40
43
|
thread_safe (0.3.6)
|
41
|
-
|
44
|
+
typhoeus (1.4.0)
|
45
|
+
ethon (>= 0.9.0)
|
46
|
+
tzinfo (1.2.7)
|
42
47
|
thread_safe (~> 0.1)
|
48
|
+
zeitwerk (2.3.1)
|
43
49
|
|
44
50
|
PLATFORMS
|
45
51
|
ruby
|
46
52
|
|
47
53
|
DEPENDENCIES
|
48
|
-
bundler (
|
54
|
+
bundler (>= 2.1)
|
49
55
|
mocha (~> 1.2, >= 1.2.1)
|
50
56
|
perimeter_x!
|
51
|
-
rake (
|
57
|
+
rake (>= 12.3)
|
52
58
|
rspec (~> 3.0)
|
53
59
|
|
54
60
|
BUNDLED WITH
|
55
|
-
1.
|
61
|
+
2.1.4
|
data/Rakefile
CHANGED
data/changelog.md
CHANGED
@@ -5,6 +5,68 @@ 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
|
+
## [2.1.0] - 2020-09-01
|
9
|
+
### Added
|
10
|
+
- Added option to set a different px configuration on each request
|
11
|
+
- Added types validation on configuration fields
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
- New cookie logic for mobile requests
|
15
|
+
- Renamed api_connect_timeout to api_timeout_conncection on default configuration
|
16
|
+
- Removed unsapported configuration fields: max_buffer_len and local_proxy
|
17
|
+
- Send cookie_origin only if there is a cookie
|
18
|
+
|
19
|
+
## [2.0.0] - 2020-07-24
|
20
|
+
### Added
|
21
|
+
- Added fields to Block Activity: simulated_block, http_version, http_method, risk_rtt, px_orig_cookie
|
22
|
+
- Added fields to page_requested activity: pass_reason, risk_rtt, px_orig_cookie
|
23
|
+
- Added px_orig_cookie field to risk_api in case of cookie_decryption_failed
|
24
|
+
- Added support for captcha v2
|
25
|
+
- Added support for Advanced Blocking Response
|
26
|
+
- Added support for whitelise routes
|
27
|
+
- Added support for bypass monitor header
|
28
|
+
- Added support for extracting vid from _pxvid cookie
|
29
|
+
- Added support for rate limit
|
30
|
+
- Added risk_cookie_max_iterations configuration
|
31
|
+
|
32
|
+
### Fixed
|
33
|
+
- Updated dependencies
|
34
|
+
- Updated sample site dockerfile
|
35
|
+
- Fixed monitor mode
|
36
|
+
- Fixed send_page_activities and send_block_activities configurations
|
37
|
+
- Updated risk to v3
|
38
|
+
- Refactored ip header extraction
|
39
|
+
- Renamed block_uuid field to client_uuid
|
40
|
+
- Renamed perimeterx_server_host configuration to backend_url
|
41
|
+
- Updated risk_response handling: pass the request if risk_response.status is -1
|
42
|
+
- Forcing http header values to be utf8
|
43
|
+
|
44
|
+
## [1.4.0] - 2018-03-18
|
45
|
+
### Fixed
|
46
|
+
- Incorrect assigment for s2s_call_reason
|
47
|
+
- Fixed empty token result correct s2s reason
|
48
|
+
|
49
|
+
### Added
|
50
|
+
- Added support to captcha api v2
|
51
|
+
- Mobile sdk support for special tokens 1/2/3
|
52
|
+
|
53
|
+
|
54
|
+
## [1.3.0] - 2017-07-27
|
55
|
+
### Added
|
56
|
+
- Sending client_uuid on page_requested activities
|
57
|
+
- Supporting mobile sdk
|
58
|
+
### Fixed
|
59
|
+
- Using `request.env` instead of `env`
|
60
|
+
|
61
|
+
## [1.2.0] - 2017-06-04
|
62
|
+
### Fixed
|
63
|
+
- Default timeouts for post api requests
|
64
|
+
- Fixed Dockerfile
|
65
|
+
### Changed
|
66
|
+
- Removed httpclient and instead using typheous
|
67
|
+
### Added
|
68
|
+
- Using concurrent-ruby for async post requests
|
69
|
+
|
8
70
|
## [1.1.0] - 2017-06-04
|
9
71
|
### Added
|
10
72
|
- Added support for sensitive routes
|
@@ -18,3 +80,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
18
80
|
- Constants on px_constants
|
19
81
|
- Cookie Validation flow when cookie score was over the configured threshold
|
20
82
|
- Using symbols instead of strings for requests body
|
83
|
+
|
data/lib/perimeter_x.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'concurrent'
|
2
|
+
require 'json'
|
3
|
+
require 'base64'
|
4
|
+
require 'uri'
|
1
5
|
require 'perimeterx/configuration'
|
2
6
|
require 'perimeterx/utils/px_logger'
|
3
7
|
require 'perimeterx/utils/px_constants'
|
@@ -7,102 +11,167 @@ require 'perimeterx/internal/perimeter_x_context'
|
|
7
11
|
require 'perimeterx/internal/clients/perimeter_x_activity_client'
|
8
12
|
require 'perimeterx/internal/validators/perimeter_x_s2s_validator'
|
9
13
|
require 'perimeterx/internal/validators/perimeter_x_cookie_validator'
|
10
|
-
require 'perimeterx/internal/
|
14
|
+
require 'perimeterx/internal/exceptions/px_config_exception'
|
11
15
|
|
12
16
|
module PxModule
|
13
|
-
|
14
17
|
# Module expose API
|
15
|
-
def px_verify_request
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# Generate template
|
28
|
-
PerimeterX.instance.px_config[:logger].debug("PxModule[px_verify_request]: sending default block page")
|
29
|
-
html = PxTemplateFactory.get_template(px_ctx, PerimeterX.instance.px_config)
|
30
|
-
response.headers["Content-Type"] = "text/html"
|
31
|
-
response.status = 403
|
32
|
-
render :html => html
|
18
|
+
def px_verify_request(request_config={})
|
19
|
+
begin
|
20
|
+
px_instance = PerimeterX.new(request_config)
|
21
|
+
px_ctx = px_instance.verify(request.env)
|
22
|
+
px_config = px_instance.px_config
|
23
|
+
|
24
|
+
msg_title = 'PxModule[px_verify_request]'
|
25
|
+
|
26
|
+
# In case custom verification handler is in use
|
27
|
+
if px_config.key?(:custom_verification_handler)
|
28
|
+
px_config[:logger].debug("#{msg_title}: custom_verification_handler triggered")
|
29
|
+
return instance_exec(px_ctx, &px_config[:custom_verification_handler])
|
33
30
|
end
|
34
|
-
end
|
35
31
|
|
36
|
-
|
32
|
+
unless px_ctx.nil? || px_ctx.context[:verified] || (px_config[:module_mode] == PxModule::MONITOR_MODE && !px_ctx.context[:should_bypass_monitor])
|
33
|
+
# In case custom block handler exists (soon to be deprecated)
|
34
|
+
if px_config.key?(:custom_block_handler)
|
35
|
+
px_config[:logger].debug("#{msg_title}: custom_block_handler triggered")
|
36
|
+
px_config[:logger].debug(
|
37
|
+
"#{msg_title}: Please note that custom_block_handler is deprecated. Use custom_verification_handler instead.")
|
38
|
+
return instance_exec(px_ctx, &px_config[:custom_block_handler])
|
39
|
+
else
|
40
|
+
if px_ctx.context[:block_action]== 'rate_limit'
|
41
|
+
px_config[:logger].debug("#{msg_title}: sending rate limit page")
|
42
|
+
response.status = 429
|
43
|
+
else
|
44
|
+
px_config[:logger].debug("#{msg_title}: sending default block page")
|
45
|
+
response.status = 403
|
46
|
+
end
|
47
|
+
|
48
|
+
is_mobile = px_ctx.context[:cookie_origin] == 'header' ? '1' : '0'
|
49
|
+
action = px_ctx.context[:block_action][0,1]
|
50
|
+
|
51
|
+
px_template_object = {
|
52
|
+
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}",
|
53
|
+
js_client_src: "//#{PxModule::CLIENT_HOST}/#{px_config[:app_id]}/main.min.js"
|
54
|
+
}
|
55
|
+
|
56
|
+
html = PxTemplateFactory.get_template(px_ctx, px_config, px_template_object)
|
57
|
+
|
58
|
+
# Web handler
|
59
|
+
if px_ctx.context[:cookie_origin] == 'cookie'
|
60
|
+
|
61
|
+
accept_header_value = request.headers['accept'] || request.headers['content-type'];
|
62
|
+
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;
|
63
|
+
|
64
|
+
if (is_json_response)
|
65
|
+
px_config[:logger].debug("#{msg_title}: advanced blocking response response")
|
66
|
+
response.headers['Content-Type'] = 'application/json'
|
67
|
+
|
68
|
+
hash_json = {
|
69
|
+
:appId => px_config[:app_id],
|
70
|
+
:jsClientSrc => px_template_object[:js_client_src],
|
71
|
+
:firstPartyEnabled => false,
|
72
|
+
:uuid => px_ctx.context[:uuid],
|
73
|
+
:vid => px_ctx.context[:vid],
|
74
|
+
:hostUrl => "https://collector-#{px_config[:app_id]}.perimeterx.net",
|
75
|
+
:blockScript => px_template_object[:block_script],
|
76
|
+
}
|
77
|
+
|
78
|
+
render :json => hash_json
|
79
|
+
else
|
80
|
+
px_config[:logger].debug('#{msg_title}: web block')
|
81
|
+
response.headers['Content-Type'] = 'text/html'
|
82
|
+
render :html => html
|
83
|
+
end
|
84
|
+
else # Mobile SDK
|
85
|
+
px_config[:logger].debug("#{msg_title}: mobile sdk block")
|
86
|
+
response.headers['Content-Type'] = 'application/json'
|
87
|
+
hash_json = {
|
88
|
+
:action => px_ctx.context[:block_action],
|
89
|
+
:uuid => px_ctx.context[:uuid],
|
90
|
+
:vid => px_ctx.context[:vid],
|
91
|
+
:appId => px_config[:app_id],
|
92
|
+
:page => Base64.strict_encode64(html),
|
93
|
+
:collectorUrl => "https://collector-#{px_config[:app_id]}.perimeterx.net"
|
94
|
+
}
|
95
|
+
render :json => hash_json
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Request was verified
|
101
|
+
return px_ctx.nil? ? true : px_ctx.context[:verified]
|
102
|
+
|
103
|
+
rescue PxConfigurationException
|
104
|
+
raise
|
105
|
+
rescue Exception => e
|
106
|
+
error_logger = PxLogger.new(true)
|
107
|
+
error_logger.error("#{e.backtrace.first}: #{e.message} (#{e.class})")
|
108
|
+
e.backtrace.drop(1).map {|s| error_logger.error("\t#{s}")}
|
109
|
+
return nil
|
110
|
+
end
|
37
111
|
end
|
38
112
|
|
39
|
-
def self.configure(
|
40
|
-
|
113
|
+
def self.configure(basic_config)
|
114
|
+
PerimeterX.set_basic_config(basic_config)
|
41
115
|
end
|
42
116
|
|
43
117
|
|
44
|
-
#
|
118
|
+
# PerimeterX Module
|
45
119
|
class PerimeterX
|
46
|
-
@@__instance = nil
|
47
|
-
@@mutex = Mutex.new
|
48
120
|
|
49
121
|
attr_reader :px_config
|
50
122
|
attr_accessor :px_http_client
|
51
123
|
attr_accessor :px_activity_client
|
52
124
|
|
53
125
|
#Static methods
|
54
|
-
def self.
|
55
|
-
|
56
|
-
@@mutex.synchronize {
|
57
|
-
return @@__instance if @@__instance
|
58
|
-
@@__instance = new(params)
|
59
|
-
}
|
60
|
-
return true
|
126
|
+
def self.set_basic_config(basic_config)
|
127
|
+
Configuration.set_basic_config(basic_config)
|
61
128
|
end
|
62
129
|
|
63
|
-
def self.instance
|
64
|
-
return @@__instance if !@@__instance.nil?
|
65
|
-
raise Exception.new("Please initialize perimeter x first")
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
130
|
#Instance Methods
|
70
131
|
def verify(env)
|
71
132
|
begin
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
133
|
+
|
134
|
+
# check module_enabled
|
135
|
+
@logger.debug('PerimeterX[pxVerify]')
|
136
|
+
if !@px_config[:module_enabled]
|
137
|
+
@logger.warn('Module is disabled')
|
138
|
+
return nil
|
77
139
|
end
|
78
|
-
px_ctx = PerimeterXContext.new(@px_config, req)
|
79
140
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
141
|
+
req = ActionDispatch::Request.new(env)
|
142
|
+
|
143
|
+
# filter whitelist routes
|
144
|
+
url_path = URI.parse(req.original_url).path
|
145
|
+
if url_path && !url_path.empty?
|
146
|
+
if check_whitelist_routes(px_config[:whitelist_routes], url_path)
|
147
|
+
@logger.debug("PerimeterX[pxVerify]: whitelist route: #{url_path}")
|
148
|
+
return nil
|
149
|
+
end
|
84
150
|
end
|
151
|
+
|
152
|
+
# create context
|
153
|
+
px_ctx = PerimeterXContext.new(@px_config, req)
|
85
154
|
|
86
155
|
# Cookie phase
|
87
156
|
cookie_verified, px_ctx = @px_cookie_validator.verify(px_ctx)
|
88
|
-
if
|
157
|
+
if !cookie_verified
|
158
|
+
if !px_ctx.context[:mobile_error].nil?
|
159
|
+
px_ctx.context[:s2s_call_reason] = "mobile_error_#{px_ctx.context[:mobile_error]}"
|
160
|
+
end
|
89
161
|
@px_s2s_validator.verify(px_ctx)
|
90
162
|
end
|
91
163
|
|
92
|
-
|
93
|
-
return @px_config[:custom_verification_handler].call(px_ctx.context)
|
94
|
-
else
|
95
|
-
return handle_verification(px_ctx)
|
96
|
-
end
|
164
|
+
return handle_verification(px_ctx)
|
97
165
|
rescue Exception => e
|
98
166
|
@logger.error("#{e.backtrace.first}: #{e.message} (#{e.class})")
|
99
|
-
e.backtrace.drop(1).map {
|
100
|
-
return
|
167
|
+
e.backtrace.drop(1).map {|s| @logger.error("\t#{s}")}
|
168
|
+
return nil
|
101
169
|
end
|
102
170
|
end
|
103
171
|
|
104
|
-
|
105
|
-
|
172
|
+
def initialize(request_config)
|
173
|
+
|
174
|
+
@px_config = Configuration.new(request_config).configuration
|
106
175
|
@logger = @px_config[:logger]
|
107
176
|
@px_http_client = PxHttpClient.new(@px_config)
|
108
177
|
|
@@ -110,36 +179,49 @@ module PxModule
|
|
110
179
|
|
111
180
|
@px_cookie_validator = PerimeterxCookieValidator.new(@px_config)
|
112
181
|
@px_s2s_validator = PerimeterxS2SValidator.new(@px_config, @px_http_client)
|
113
|
-
@
|
114
|
-
@logger.debug("PerimeterX[initialize]")
|
182
|
+
@logger.debug('PerimeterX[initialize]')
|
115
183
|
end
|
116
184
|
|
117
185
|
private def handle_verification(px_ctx)
|
118
|
-
@logger.debug(
|
186
|
+
@logger.debug('PerimeterX[handle_verification]')
|
119
187
|
@logger.debug("PerimeterX[handle_verification]: processing ended - score:#{px_ctx.context[:score]}, uuid:#{px_ctx.context[:uuid]}")
|
120
188
|
|
121
189
|
score = px_ctx.context[:score]
|
190
|
+
px_ctx.context[:should_bypass_monitor] = @px_config[:bypass_monitor_header] && px_ctx.context[:headers][@px_config[:bypass_monitor_header].to_sym] == '1';
|
191
|
+
|
192
|
+
px_ctx.context[:verified] = score < @px_config[:blocking_score]
|
122
193
|
# Case PASS request
|
123
|
-
if
|
194
|
+
if px_ctx.context[:verified]
|
124
195
|
@logger.debug("PerimeterX[handle_verification]: score:#{score} < blocking score, passing request")
|
125
196
|
@px_activity_client.send_page_requested_activity(px_ctx)
|
126
|
-
return
|
197
|
+
return px_ctx
|
127
198
|
end
|
128
199
|
|
129
200
|
# Case blocking activity
|
130
201
|
@px_activity_client.send_block_activity(px_ctx)
|
131
202
|
|
132
203
|
# In case were in monitor mode, end here
|
133
|
-
if
|
204
|
+
if @px_config[:module_mode] == PxModule::MONITOR_MODE && !px_ctx.context[:should_bypass_monitor]
|
134
205
|
@logger.debug("PerimeterX[handle_verification]: monitor mode is on, passing request")
|
135
|
-
return
|
206
|
+
return px_ctx
|
136
207
|
end
|
137
208
|
|
138
|
-
@logger.debug(
|
209
|
+
@logger.debug('PerimeterX[handle_verification]: verification ended, the request should be blocked')
|
139
210
|
|
140
|
-
return
|
211
|
+
return px_ctx
|
212
|
+
end
|
213
|
+
|
214
|
+
private def check_whitelist_routes(whitelist_routes, path)
|
215
|
+
whitelist_routes.each do |whitelist_route|
|
216
|
+
if whitelist_route.is_a?(Regexp) && path.match(whitelist_route)
|
217
|
+
return true
|
218
|
+
end
|
219
|
+
if whitelist_route.is_a?(String) && path.start_with?(whitelist_route)
|
220
|
+
return true
|
221
|
+
end
|
222
|
+
end
|
223
|
+
false
|
141
224
|
end
|
142
225
|
|
143
|
-
private_class_method :new
|
144
226
|
end
|
145
227
|
end
|