perimeter_x 1.0.5 → 1.0.6.pre.alpha
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 +4 -4
- data/.gitignore +3 -5
- data/Dockerfile +3 -5
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -44
- data/LICENSE.txt +12 -9
- data/Rakefile +2 -9
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/changelog.md +0 -16
- data/examples/home_controller.rb.dist +23 -0
- data/examples/{config/routes.rb → routes.rb} +0 -0
- data/lib/perimeter_x.rb +33 -109
- data/lib/perimeterx/configuration.rb +17 -24
- data/lib/perimeterx/internal/perimeter_x_context.rb +53 -74
- data/lib/perimeterx/internal/perimeter_x_risk_client.rb +29 -0
- data/lib/perimeterx/internal/perimeter_x_s2s_validator.rb +67 -0
- data/lib/perimeterx/utils/px_http_client.rb +26 -47
- data/lib/perimeterx/utils/px_logger.rb +6 -12
- data/lib/perimeterx/version.rb +2 -2
- data/perimeter_x.gemspec +1 -6
- data/readme.md +34 -218
- metadata +11 -90
- data/examples/app/controllers/home_controller.rb +0 -9
- data/examples/app/views/home/index.html.erb.dist +0 -20
- data/examples/config/initializers/perimeterx.rb.dist +0 -8
- data/lib/perimeterx/internal/clients/perimeter_x_activity_client.rb +0 -92
- data/lib/perimeterx/internal/clients/perimeter_x_risk_client.rb +0 -28
- data/lib/perimeterx/internal/exceptions/px_cookie_decryption_exception.rb +0 -5
- data/lib/perimeterx/internal/perimeter_x_cookie.rb +0 -140
- data/lib/perimeterx/internal/perimeter_x_cookie_v1.rb +0 -42
- data/lib/perimeterx/internal/perimeter_x_cookie_v3.rb +0 -37
- data/lib/perimeterx/internal/validators/perimeter_x_captcha_validator.rb +0 -65
- data/lib/perimeterx/internal/validators/perimeter_x_cookie_validator.rb +0 -70
- data/lib/perimeterx/internal/validators/perimeter_x_s2s_validator.rb +0 -114
- data/lib/perimeterx/utils/px_constants.rb +0 -44
- data/lib/perimeterx/utils/px_template_factory.rb +0 -31
- 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
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2d1e967ee5f87625d37e4c7ca523b00ae089f512
|
|
4
|
+
data.tar.gz: b08932769740ec74416a0072dc0313c12ce4ea78
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52a63dd5557e73e43f7db668f804997d57c27dd3a609f252346353e264a85c8649254e5053e3cd3db86b6a531dd45f40a97bf9de3195daee89e4b21cce2dfb6b
|
|
7
|
+
data.tar.gz: 5d213eb7b31094d369959acbd2ea240d2f747298466a922a760836b1d706017a96a6f4a3b9bac7f6865c268ec70f7f718b53fb5b1bea04de61ec83a62f21b8aa
|
data/.gitignore
CHANGED
|
@@ -3,20 +3,18 @@ capybara-*.html
|
|
|
3
3
|
.rspec
|
|
4
4
|
/log
|
|
5
5
|
/tmp
|
|
6
|
-
/bin
|
|
7
6
|
/dev
|
|
8
7
|
/db/*.sqlite3
|
|
9
8
|
/db/*.sqlite3-journal
|
|
10
9
|
/public/system
|
|
11
10
|
/coverage/
|
|
12
11
|
/spec/tmp
|
|
13
|
-
examples/
|
|
14
|
-
examples/app/views/home/index.html.erb
|
|
12
|
+
examples/home_controller.rb
|
|
15
13
|
**.orig
|
|
16
14
|
*.gem
|
|
17
15
|
rerun.txt
|
|
18
16
|
pickle-email-*.html
|
|
19
|
-
|
|
17
|
+
dev
|
|
20
18
|
# TODO Comment out these rules if you are OK with secrets being uploaded to the repo
|
|
21
19
|
config/initializers/secret_token.rb
|
|
22
20
|
config/secrets.yml
|
|
@@ -24,7 +22,7 @@ config/secrets.yml
|
|
|
24
22
|
# dotenv
|
|
25
23
|
# TODO Comment out this rule if environment variables can be committed
|
|
26
24
|
.env
|
|
27
|
-
|
|
25
|
+
.idea
|
|
28
26
|
## Environment normalization:
|
|
29
27
|
/.bundle
|
|
30
28
|
/vendor/bundle
|
data/Dockerfile
CHANGED
|
@@ -37,14 +37,12 @@ RUN /bin/bash -l -c "gem install bundler"
|
|
|
37
37
|
RUN /bin/bash -l -c "gem install rails -v 4.2.0"
|
|
38
38
|
RUN mkdir -p /tmp/ruby_sandbox
|
|
39
39
|
WORKDIR /tmp/ruby_sandbox
|
|
40
|
-
RUN git clone https://github.com/PerimeterX/perimeterx-ruby-sdk.git
|
|
41
40
|
RUN /bin/bash -l -c "rails new webapp"
|
|
42
41
|
WORKDIR /tmp/ruby_sandbox/webapp
|
|
43
42
|
RUN /bin/bash -l -c "rails generate controller home index"
|
|
44
43
|
WORKDIR /tmp/ruby_sandbox/webapp
|
|
45
44
|
EXPOSE 3000
|
|
46
|
-
|
|
47
|
-
RUN sed -i '2i gem "perimeter_x", :path => "/tmp/ruby_sandbox/perimeterx-ruby-sdk"' /tmp/ruby_sandbox/webapp/Gemfile
|
|
45
|
+
RUN sed -i "2i gem 'perimeter_x', '~> 1.0.5.pre.alpha'" /tmp/ruby_sandbox/webapp/Gemfile
|
|
48
46
|
RUN /bin/bash -l -c "bundler update"
|
|
49
|
-
|
|
50
|
-
CMD ["/bin/bash", "-l", "-c", "rails server -b 0.0.0.0;"]
|
|
47
|
+
RUN /bin/bash -l -c "gem list|grep peri"
|
|
48
|
+
CMD ["/bin/bash", "-l", "-c", "rails server -b 0.0.0.0;"]
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,55 +1,13 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
perimeter_x (1.0.3)
|
|
5
|
-
activesupport (>= 4.2.0)
|
|
6
|
-
httpclient (= 2.8.2.4)
|
|
7
|
-
mustache (~> 1.0, >= 1.0.3)
|
|
8
|
-
|
|
9
1
|
GEM
|
|
10
2
|
remote: https://rubygems.org/
|
|
11
3
|
specs:
|
|
12
|
-
|
|
13
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
14
|
-
i18n (~> 0.7)
|
|
15
|
-
minitest (~> 5.1)
|
|
16
|
-
tzinfo (~> 1.1)
|
|
17
|
-
concurrent-ruby (1.0.5)
|
|
18
|
-
diff-lcs (1.3)
|
|
19
|
-
httpclient (2.8.2.4)
|
|
20
|
-
i18n (0.8.1)
|
|
21
|
-
metaclass (0.0.4)
|
|
22
|
-
minitest (5.10.1)
|
|
23
|
-
mocha (1.2.1)
|
|
24
|
-
metaclass (~> 0.0.1)
|
|
25
|
-
mustache (1.0.4)
|
|
26
|
-
rake (10.4.2)
|
|
27
|
-
rspec (3.5.0)
|
|
28
|
-
rspec-core (~> 3.5.0)
|
|
29
|
-
rspec-expectations (~> 3.5.0)
|
|
30
|
-
rspec-mocks (~> 3.5.0)
|
|
31
|
-
rspec-core (3.5.4)
|
|
32
|
-
rspec-support (~> 3.5.0)
|
|
33
|
-
rspec-expectations (3.5.0)
|
|
34
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
35
|
-
rspec-support (~> 3.5.0)
|
|
36
|
-
rspec-mocks (3.5.0)
|
|
37
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
38
|
-
rspec-support (~> 3.5.0)
|
|
39
|
-
rspec-support (3.5.0)
|
|
40
|
-
thread_safe (0.3.6)
|
|
41
|
-
tzinfo (1.2.3)
|
|
42
|
-
thread_safe (~> 0.1)
|
|
4
|
+
httpclient (2.8.3)
|
|
43
5
|
|
|
44
6
|
PLATFORMS
|
|
45
7
|
ruby
|
|
46
8
|
|
|
47
9
|
DEPENDENCIES
|
|
48
|
-
|
|
49
|
-
mocha (~> 1.2, >= 1.2.1)
|
|
50
|
-
perimeter_x!
|
|
51
|
-
rake (~> 10.0)
|
|
52
|
-
rspec (~> 3.0)
|
|
10
|
+
httpclient (= 2.8.3)
|
|
53
11
|
|
|
54
12
|
BUNDLED WITH
|
|
55
13
|
1.14.6
|
data/LICENSE.txt
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 nitzanpx
|
|
2
4
|
|
|
3
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -7,12 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
7
9
|
copies of the Software, and to permit persons to whom the Software is
|
|
8
10
|
furnished to do so, subject to the following conditions:
|
|
9
11
|
|
|
10
|
-
The above copyright notice and this permission notice shall be included in
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
11
14
|
|
|
12
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/Rakefile
CHANGED
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "perimeter_x"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/changelog.md
CHANGED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Change Log
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
6
|
-
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
7
|
-
|
|
8
|
-
## [1.0.5] - 2017-05-07
|
|
9
|
-
### Fixed
|
|
10
|
-
- Added request format into context for custom callbacks
|
|
11
|
-
|
|
12
|
-
## [1.0.4] - 2017-04-27
|
|
13
|
-
### Fixed
|
|
14
|
-
- Constants on px_constants
|
|
15
|
-
- Cookie Validation flow when cookie score was over the configured threshold
|
|
16
|
-
- Using symbols instead of strings for requests body
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class HomeController < ApplicationController
|
|
2
|
+
include PerimeterX
|
|
3
|
+
|
|
4
|
+
before_action :px_middleware
|
|
5
|
+
|
|
6
|
+
attr_accessor :px
|
|
7
|
+
|
|
8
|
+
def initialize()
|
|
9
|
+
params = {
|
|
10
|
+
"app_id" => <APP_ID>,
|
|
11
|
+
"cookie_key" => <COOKIE_KEY>,
|
|
12
|
+
"auth_token" => <AUTH_TOKEN>
|
|
13
|
+
}
|
|
14
|
+
@px = PxModule.instance(params)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def index
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def px_middleware
|
|
21
|
+
px.px_verify(request.env)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
File without changes
|
data/lib/perimeter_x.rb
CHANGED
|
@@ -1,145 +1,69 @@
|
|
|
1
1
|
require 'perimeterx/configuration'
|
|
2
2
|
require 'perimeterx/utils/px_logger'
|
|
3
|
-
require 'perimeterx/utils/px_constants'
|
|
4
3
|
require 'perimeterx/utils/px_http_client'
|
|
5
|
-
require 'perimeterx/utils/px_template_factory'
|
|
6
4
|
require 'perimeterx/internal/perimeter_x_context'
|
|
7
|
-
require 'perimeterx/internal/
|
|
8
|
-
require 'perimeterx/internal/validators/perimeter_x_s2s_validator'
|
|
9
|
-
require 'perimeterx/internal/validators/perimeter_x_cookie_validator'
|
|
10
|
-
require 'perimeterx/internal/validators/perimeter_x_captcha_validator'
|
|
5
|
+
require 'perimeterx/internal/perimeter_x_s2s_validator'
|
|
11
6
|
|
|
12
|
-
module
|
|
7
|
+
module PerimeterX
|
|
8
|
+
class PxModule
|
|
9
|
+
L = PxLogger.instance
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
verified, px_ctx = PerimeterX.instance.verify(env)
|
|
17
|
-
|
|
18
|
-
# Invalidate _pxCaptcha, can be done only on the controller level
|
|
19
|
-
cookies[:_pxCaptcha] = { value: "", expires: -1.minutes.from_now }
|
|
20
|
-
|
|
21
|
-
if (!verified)
|
|
22
|
-
# In case custon block handler exists
|
|
23
|
-
if (PerimeterX.instance.px_config.key?(:custom_block_handler))
|
|
24
|
-
PerimeterX.instance.px_config[:logger].debug("PxModule[px_verify_request]: custom_block_handler triggered")
|
|
25
|
-
return instance_exec(px_ctx, &PerimeterX.instance.px_config[:custom_block_handler])
|
|
26
|
-
else
|
|
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
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
return verified
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def self.configure(params)
|
|
40
|
-
@px_instance = PerimeterX.configure(params)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# PerimtereX Module
|
|
45
|
-
class PerimeterX
|
|
46
|
-
@@__instance = nil
|
|
47
|
-
@@mutex = Mutex.new
|
|
11
|
+
@@singleton__instance__ = nil
|
|
12
|
+
@@singleton__mutex__ = Mutex.new
|
|
48
13
|
|
|
49
14
|
attr_reader :px_config
|
|
50
15
|
attr_accessor :px_http_client
|
|
51
|
-
attr_accessor :px_activity_client
|
|
52
16
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@@__instance = new(params)
|
|
17
|
+
def self.instance(params)
|
|
18
|
+
return @@singleton__instance__ if @@singleton__instance__
|
|
19
|
+
@@singleton__mutex__.synchronize {
|
|
20
|
+
return @@singleton__instance__ if @@singleton__instance__
|
|
21
|
+
@@singleton__instance__ = new(params)
|
|
59
22
|
}
|
|
60
|
-
|
|
23
|
+
@@singleton__instance__
|
|
61
24
|
end
|
|
62
25
|
|
|
63
|
-
def self.instance
|
|
64
|
-
return @@__instance if !@@__instance.nil?
|
|
65
|
-
raise Exception.new("Please initialize perimeter x first")
|
|
66
|
-
end
|
|
67
26
|
|
|
27
|
+
private def initialize(params)
|
|
28
|
+
L.info("PerimeterX[initialize]")
|
|
29
|
+
@px_config = Configuration.new(params).configuration
|
|
30
|
+
@px_http_client = PxHttpClient.new(@px_config)
|
|
31
|
+
end
|
|
68
32
|
|
|
69
|
-
|
|
70
|
-
def verify(env)
|
|
33
|
+
def px_verify(env)
|
|
71
34
|
begin
|
|
72
|
-
|
|
35
|
+
L.info("PerimeterX[pxVerify]")
|
|
73
36
|
req = ActionDispatch::Request.new(env)
|
|
74
|
-
|
|
75
|
-
|
|
37
|
+
|
|
38
|
+
if (!@px_config['module_enabled'])
|
|
39
|
+
L.warn("Module is disabled")
|
|
76
40
|
return true
|
|
77
41
|
end
|
|
78
|
-
px_ctx = PerimeterXContext.new(@px_config, req)
|
|
79
42
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (captcha_verified)
|
|
83
|
-
return handle_verification(px_ctx)
|
|
84
|
-
end
|
|
43
|
+
px_ctx = PerimeterXContext.new(@px_config, req)
|
|
44
|
+
px_ctx.context[:s2s_call_reason] = "no_cookie"
|
|
85
45
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (!cookie_verified)
|
|
89
|
-
@px_s2s_validator.verify(px_ctx)
|
|
90
|
-
end
|
|
46
|
+
s2sValidator = PerimeterxS2SValidator.new(px_ctx, @px_config, @px_http_client)
|
|
47
|
+
px_ctx = s2sValidator.verify()
|
|
91
48
|
|
|
92
|
-
if (
|
|
93
|
-
return
|
|
49
|
+
if (px_config.key?('custom_verification_handler'))
|
|
50
|
+
return px_config['custom_verification_handler'].call(px_ctx.context)
|
|
94
51
|
else
|
|
95
52
|
return handle_verification(px_ctx)
|
|
96
53
|
end
|
|
97
54
|
rescue Exception => e
|
|
98
|
-
|
|
99
|
-
e.backtrace.drop(1).map { |s| @logger.error("\t#{s}") }
|
|
55
|
+
puts("#{e.backtrace.first}: #{e.message} (#{e.class})", e.backtrace.drop(1).map { |s| "\t#{s}" })
|
|
100
56
|
return true
|
|
101
57
|
end
|
|
102
58
|
end
|
|
103
59
|
|
|
104
|
-
private
|
|
105
|
-
@px_config = Configuration.new(params).configuration
|
|
106
|
-
@logger = @px_config[:logger]
|
|
107
|
-
@px_http_client = PxHttpClient.new(@px_config)
|
|
108
|
-
|
|
109
|
-
@px_activity_client = PerimeterxActivitiesClient.new(@px_config, @px_http_client)
|
|
110
|
-
|
|
111
|
-
@px_cookie_validator = PerimeterxCookieValidator.new(@px_config)
|
|
112
|
-
@px_s2s_validator = PerimeterxS2SValidator.new(@px_config, @px_http_client)
|
|
113
|
-
@px_captcha_validator = PerimeterxCaptchaValidator.new(@px_config, @px_http_client)
|
|
114
|
-
@logger.debug("PerimeterX[initialize]")
|
|
115
|
-
end
|
|
116
|
-
|
|
60
|
+
# private methods
|
|
117
61
|
private def handle_verification(px_ctx)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
score = px_ctx.context[:score]
|
|
122
|
-
# Case PASS request
|
|
123
|
-
if (score < @px_config[:blocking_score])
|
|
124
|
-
@logger.debug("PerimeterX[handle_verification]: score:#{score} < blocking score, passing request")
|
|
125
|
-
@px_activity_client.send_page_requested_activity(px_ctx)
|
|
126
|
-
return true
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# Case blocking activity
|
|
130
|
-
@px_activity_client.send_block_activity(px_ctx)
|
|
131
|
-
|
|
132
|
-
# In case were in monitor mode, end here
|
|
133
|
-
if(@px_config[:module_mode] == PxModule::MONITOR_MODE)
|
|
134
|
-
@logger.debug("PerimeterX[handle_verification]: monitor mode is on, passing request")
|
|
135
|
-
return true
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
@logger.debug("PerimeterX[handle_verification]: verification ended, the request should be blocked")
|
|
139
|
-
|
|
140
|
-
return false, px_ctx
|
|
62
|
+
L.info("perimeterx processing ended - score:#{px_ctx.context[:score]}, uuid:#{px_ctx.context[:uuid]}")
|
|
63
|
+
return true
|
|
141
64
|
end
|
|
142
65
|
|
|
143
66
|
private_class_method :new
|
|
144
67
|
end
|
|
68
|
+
|
|
145
69
|
end
|
|
@@ -1,37 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
require 'perimeterx/utils/px_constants'
|
|
3
|
-
|
|
4
|
-
module PxModule
|
|
1
|
+
module PerimeterX
|
|
5
2
|
class Configuration
|
|
6
3
|
|
|
7
4
|
attr_accessor :configuration
|
|
8
5
|
attr_accessor :PX_DEFAULT
|
|
6
|
+
attr_accessor :MONITOR_MODE
|
|
7
|
+
attr_accessor :ACTIVE_MODE
|
|
8
|
+
|
|
9
|
+
MONITOR_MODE = 1
|
|
10
|
+
ACTIVE_MODE = 2
|
|
9
11
|
|
|
10
12
|
PX_DEFAULT = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
:api_timeout => 0,
|
|
22
|
-
:max_buffer_len => 30,
|
|
23
|
-
:send_page_activities => false,
|
|
24
|
-
:send_block_activities => true,
|
|
25
|
-
:sdk_name => PxModule::SDK_NAME,
|
|
26
|
-
:debug => false,
|
|
27
|
-
:module_mode => PxModule::ACTIVE_MODE,
|
|
28
|
-
:local_proxy => false
|
|
13
|
+
"app_id" => nil,
|
|
14
|
+
"auth_token" => nil,
|
|
15
|
+
"module_enabled" => true,
|
|
16
|
+
"blocking_score" => 70,
|
|
17
|
+
"sensitive_headers" => ["cookie", "cookies"],
|
|
18
|
+
"api_connect_timeout" => 1,
|
|
19
|
+
"api_timeout" => 1,
|
|
20
|
+
"sdk_name" => "RUBY SLIM SDK v1.0.0",
|
|
21
|
+
"debug_mode" => false,
|
|
22
|
+
"module_mode" => MONITOR_MODE,
|
|
29
23
|
}
|
|
30
24
|
|
|
31
25
|
def initialize(params)
|
|
32
|
-
PX_DEFAULT[
|
|
26
|
+
PX_DEFAULT["perimeterx_server_host"] = "https://sapi-#{params['app_id'].downcase}.perimeterx.net"
|
|
33
27
|
@configuration = PX_DEFAULT.merge(params);
|
|
34
|
-
@configuration[:logger] = PxLogger.new(@configuration[:debug])
|
|
35
28
|
end
|
|
36
29
|
end
|
|
37
30
|
end
|
|
@@ -1,83 +1,62 @@
|
|
|
1
1
|
require 'perimeterx/utils/px_logger'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@context[:px_captcha] = v
|
|
27
|
-
end
|
|
28
|
-
end #end case
|
|
29
|
-
end #end empty cookies
|
|
30
|
-
|
|
31
|
-
req.headers.each do |k, v|
|
|
32
|
-
if (k.start_with? "HTTP_")
|
|
33
|
-
header = k.to_s.gsub("HTTP_", "")
|
|
34
|
-
header = header.gsub("_", "-").downcase
|
|
35
|
-
@context[:headers][header.to_sym] = v
|
|
3
|
+
class PerimeterXContext
|
|
4
|
+
L = PxLogger.instance
|
|
5
|
+
|
|
6
|
+
attr_accessor :context
|
|
7
|
+
attr_accessor :px_config
|
|
8
|
+
|
|
9
|
+
def initialize(px_config, req)
|
|
10
|
+
L.info("PerimeterXContext: initialize")
|
|
11
|
+
@context = Hash.new
|
|
12
|
+
|
|
13
|
+
@context[:px_cookies] = Hash.new
|
|
14
|
+
@context[:headers] = Hash.new
|
|
15
|
+
cookies = req.cookies
|
|
16
|
+
if (!cookies.empty?)
|
|
17
|
+
# Prepare hashed cookies
|
|
18
|
+
cookies.each do |k, v|
|
|
19
|
+
case k
|
|
20
|
+
when "_px3"
|
|
21
|
+
@context[:px_cookies] = v
|
|
22
|
+
when "_px"
|
|
23
|
+
@context[:px_cookies] = v
|
|
24
|
+
when "_pxCaptcha"
|
|
25
|
+
@context[:px_captcha] = v
|
|
36
26
|
end
|
|
37
|
-
end #end
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if px_config.key?(:custom_user_ip)
|
|
47
|
-
@context[:ip] = req.headers[px_config[:custom_user_ip]]
|
|
48
|
-
elsif px_config.key?(:px_custom_user_ip_method)
|
|
49
|
-
@context[:ip] = px_config[:px_custom_user_ip_method].call(req)
|
|
50
|
-
else
|
|
51
|
-
@context[:ip] = req.ip
|
|
27
|
+
end #end case
|
|
28
|
+
end #end empty cookies
|
|
29
|
+
|
|
30
|
+
req.headers.each do |k, v|
|
|
31
|
+
if (k.start_with? "HTTP_")
|
|
32
|
+
header = k.to_s.gsub("HTTP_", "")
|
|
33
|
+
header = header.gsub("_", "-").downcase
|
|
34
|
+
@context[:headers][header.to_sym] = v
|
|
52
35
|
end
|
|
36
|
+
end #end headers foreach
|
|
37
|
+
|
|
38
|
+
@context[:hostname]= req.headers['HTTP_HOST']
|
|
39
|
+
@context[:user_agent] = req.headers['HTTP_USER_AGENT'] ? req.headers['HTTP_USER_AGENT'] : ''
|
|
40
|
+
@context[:full_url] = req.original_url
|
|
41
|
+
@context[:score] = 0
|
|
42
|
+
|
|
43
|
+
if px_config.key?('custom_user_ip')
|
|
44
|
+
@context[:ip] = px_config['custom_user_ip']
|
|
45
|
+
elsif px_config.key?('px_custom_user_ip_method')
|
|
46
|
+
puts "px_custom_user_ip_method triggered"
|
|
47
|
+
@context[:ip] = px_config['px_custom_user_ip_method'].call(req)
|
|
48
|
+
else
|
|
49
|
+
@context[:ip] = req.headers['REMOTE_ADDR'];
|
|
50
|
+
end
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
end
|
|
52
|
+
if req.headers['SERVER_PROTOCOL']
|
|
53
|
+
httpVer = req.headers['SERVER_PROTOCOL'].split("/")
|
|
54
|
+
if httpVer.size > 0
|
|
55
|
+
@context[:http_version] = httpVer[1];
|
|
59
56
|
end
|
|
60
|
-
@context[:http_method] = req.method
|
|
61
|
-
|
|
62
|
-
end #end init
|
|
63
|
-
|
|
64
|
-
def set_block_action_type(action)
|
|
65
|
-
@context[:block_action] = case action
|
|
66
|
-
when "c"
|
|
67
|
-
"captcha"
|
|
68
|
-
when "b"
|
|
69
|
-
return "block"
|
|
70
|
-
when "j"
|
|
71
|
-
return "challenge"
|
|
72
|
-
else
|
|
73
|
-
return "captcha"
|
|
74
|
-
end
|
|
75
57
|
end
|
|
58
|
+
@context[:http_method] = req.headers['REQUEST_METHOD'];
|
|
76
59
|
|
|
77
|
-
|
|
78
|
-
cookie = @context[:px_cookie].key?(:v3) ? @context[:px_cookie][:v3] : @context[:px_cookie][:v1]
|
|
79
|
-
return cookie.tr(' ','+') if !cookie.nil?
|
|
80
|
-
end
|
|
60
|
+
end #end init
|
|
81
61
|
|
|
82
|
-
|
|
83
|
-
end
|
|
62
|
+
end #end class
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'perimeterx/utils/px_logger'
|
|
2
|
+
|
|
3
|
+
class PerimeterxRiskClient
|
|
4
|
+
L = PxLogger.instance
|
|
5
|
+
|
|
6
|
+
attr_accessor :px_ctx
|
|
7
|
+
attr_accessor :px_config
|
|
8
|
+
attr_accessor :http_client
|
|
9
|
+
|
|
10
|
+
def initialize(px_ctx, px_config, http_client)
|
|
11
|
+
@px_ctx = px_ctx
|
|
12
|
+
@px_config = px_config
|
|
13
|
+
@http_client = http_client;
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def format_headers()
|
|
17
|
+
formated_headers = []
|
|
18
|
+
@px_ctx.context[:headers].each do |k,v|
|
|
19
|
+
if (!@px_config["sensitive_headers"].include? k.to_s)
|
|
20
|
+
formated_headers.push({
|
|
21
|
+
:name => k.to_s,
|
|
22
|
+
:value => v
|
|
23
|
+
})
|
|
24
|
+
end #end if
|
|
25
|
+
end #end forech
|
|
26
|
+
return formated_headers
|
|
27
|
+
end #end method
|
|
28
|
+
|
|
29
|
+
end #end class
|