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.
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <title>Too Many Requests</title>
4
+ </head>
5
+ <body>
6
+ <h1>Too Many Requests</h1>
7
+ <p>Reached maximum requests limitation, try again soon.</p>
8
+ </body>
9
+ </html>
@@ -1,3 +1,3 @@
1
1
  module PxModule
2
- VERSION = '1.3.0'
2
+ VERSION = '2.2.1'
3
3
  end
@@ -22,8 +22,8 @@ Gem::Specification.new do |gem|
22
22
  gem.bindir = "exe"
23
23
  gem.executables = gem.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
24
  gem.require_paths = ["lib"]
25
- gem.add_development_dependency "bundler", "~> 1.14"
26
- gem.add_development_dependency "rake", "~> 10.0"
25
+ gem.add_development_dependency "bundler", ">= 2.1"
26
+ gem.add_development_dependency "rake", ">= 12.3"
27
27
 
28
28
  gem.extra_rdoc_files = ["readme.md", "changelog.md"]
29
29
  gem.rdoc_options = ["--line-numbers", "--inline-source", "--title", "PerimeterX"]
@@ -33,7 +33,7 @@ Gem::Specification.new do |gem|
33
33
  gem.add_dependency('concurrent-ruby', '~> 1.0', '>= 1.0.5')
34
34
  gem.add_dependency('typhoeus', '~> 1.1', '>= 1.1.2')
35
35
  gem.add_dependency('mustache', '~> 1.0', '>= 1.0.3')
36
- gem.add_dependency('activesupport', '>= 4.2.0')
36
+ gem.add_dependency('activesupport', '>= 5.2.4.3')
37
37
 
38
38
  gem.add_development_dependency 'rspec', '~> 3.0'
39
39
  gem.add_development_dependency 'mocha', '~> 1.2', '>= 1.2.1'
data/readme.md CHANGED
@@ -1,20 +1,24 @@
1
- ![image](http://media.marketwire.com/attachments/201604/34215_PerimeterX_logo.jpg)
1
+ [![Build Status](https://travis-ci.org/PerimeterX/perimeterx-ruby-sdk.svg?branch=master)](https://travis-ci.org/PerimeterX/perimeterx-ruby-sdk)
2
+
3
+ ![image](https://storage.googleapis.com/perimeterx-logos/primary_logo_red_cropped.png)
2
4
  #
3
5
  [PerimeterX](http://www.perimeterx.com) Ruby SDK
4
6
  =============================================================
5
7
 
8
+ > Latest stable version: [v2.2.1](https://rubygems.org/gems/perimeter_x)
9
+
6
10
  Table of Contents
7
11
  -----------------
8
- - [Usage](#usage)
12
+ **[Usage](#usage)**
9
13
  * [Dependencies](#dependencies)
10
14
  * [Installation](#installation)
11
15
  * [Basic Usage Example](#basic-usage)
12
- - [Configuration](#configuration)
16
+
17
+ **[Configuration](#configuration)**
13
18
  * [Configuring Required Parameters](#requireied-params)
14
19
  * [Blocking Score](#blocking-score)
20
+ * [Custom Verification Action](#custom-verification-action)
15
21
  * [Custom Block Page](#custom-block-page)
16
- * [Custom Block Action](#custom-block-action)
17
- * [Enable/Disable Captcha](#captcha-support)
18
22
  * [Extracting Real IP Address](#real-ip)
19
23
  * [Custom URI](#custom-uri)
20
24
  * [Filter Sensitive Headers](#sensitive-headers)
@@ -23,7 +27,11 @@ Table of Contents
23
27
  * [Additional Page Activity Handler](#additional-page-activity-handler)
24
28
  * [Monitor Only](#logging)
25
29
  * [Debug Mode](#debug-mode)
26
- - [Contributing](#contributing)
30
+ * [Whitelist Routes](#whitelist-routes)
31
+ * [Update Configuration on Runtime](#update-config)
32
+ * [First Party](#first-party)
33
+
34
+ **[Contributing](#contributing)**
27
35
 
28
36
  <a name="Usage"></a>
29
37
  <a name="dependencies"></a> Dependencies
@@ -80,7 +88,7 @@ All parameters are obtainable via the PerimeterX Portal. (Applications and Polic
80
88
 
81
89
  <a name="blocking-score"></a>**Changing the Minimum Score for Blocking**
82
90
 
83
- >Note: Default blocking value: 70
91
+ >Note: Default blocking value: 100
84
92
 
85
93
  ```ruby
86
94
  params = {
@@ -90,69 +98,71 @@ params = {
90
98
  }
91
99
  ```
92
100
 
101
+ <a name="custom-verification-action"></a>**Custom Verification Handler**
93
102
 
103
+ > Note: This handler replaces the now deprecated `custom_block_handler`.
94
104
 
95
- <a name="custom-block-action"></a>**Custom Verification Handler**
105
+ A custom verification handler is being executed inside `px_verify_request` instead of the the default behavior and allows a user to use a custom action based on the risk score returned by PerimeterX.
96
106
 
97
- A custom verification handler is being executed inside ``px_verify_request`` instead of the the default behavior and allows a user to use a custom action based on the risk score returned by PerimeterX.
107
+ When implemented, this method receives a hash variable as input which represents data from the PerimeterX context of the request (px_ctx).
98
108
 
99
- When implemented, this method receives a hash variable as input which represents data from the PerimeterX context of the request (px_ctx).
109
+ - `px_ctx.context[:score]` - contains the risk score
110
+ - `px_ctx.context[:uuid]` - contains the request UUID
111
+ - `px_ctx.context[:verified]` - contains indication whether the request passed verification or was blocked (inspect `px_ctx.context[:block_reason]` for block reason)
100
112
 
101
- - `px_ctx[:score] ` contains the risk score
102
- - `px_ctx[:uuid] ` contains the request UUID
103
-
104
- >> Note: to determine whether to return a captcha/block page (HTML) or block JSON payload a reference key on the context will be available: ```px_ctx.context[:format]```
113
+ > Note: to determine whether to return a captcha/block page (HTML) or block JSON payload a reference key on the context will be available: ```px_ctx.context[:format]```
105
114
 
106
115
  To replace the default verification behavior, add the configuration a lambda member as shown in the example below.
107
116
 
108
- The method must return boolen value.
109
-
110
117
  ```ruby
111
118
  params = {
112
119
  :app_id => <APP_ID>,
113
120
  :auth_token => <AUTH_TOKEN>,
114
- :custom_block_handler => -> (px_ctx) {
121
+ :custom_verification_handler => -> (px_ctx) {
115
122
  if px_ctx.context[:score] >= 60
116
- # take your action and retun a message or JSON with a status code of 403 and option UUID of the request. Can return false and include action in the px_middleware method.
123
+ # take your action and render an html page or JSON with applicable status code.
124
+ render json: { :score => px_ctx.context[:score] }
117
125
  end
118
- return true
119
126
  }
120
127
  }
121
128
  ```
122
129
 
130
+ > Note: Unlike previous versions, the method no longer needs to return a boolean value.
131
+
123
132
  **Example**
124
- ### Serving a Custom HTML Page ###
133
+ #### Serving a Custom HTML Page ####
125
134
  ```ruby
126
135
 
127
- params[:custom_block_handler] = -> (px_ctx)
128
- {
136
+ params = {
137
+ :app_id => <APP_ID>,
138
+ :auth_token => <AUTH_TOKEN>,
139
+ ...
140
+ :custom_verification_handler => -> (px_ctx) {
129
141
  block_score = px_ctx.context[:score];
130
- block_uuid = px_ctx.context[:uuid];
142
+ client_uuid = px_ctx.context[:uuid];
131
143
  full_url = px_ctx.context[:full_url];
132
144
 
133
145
  html = "<html>
134
146
  <body>
135
147
  <div>Access to #{full_url} has been blocked.</div>
136
- <div>Block reference - #{block_uuid} </div>
148
+ <div>Block reference - #{client_uuid} </div>
137
149
  <div>Block score - #{block_score} </div>
138
150
  </body>
139
151
  </html>".html_safe
140
152
  response.headers["Content-Type"] = "text/html"
141
153
  response.status = 403
142
154
  render :html => html
143
- return false
144
- };
145
-
146
- PxModule.configure(params)
155
+ }
156
+ }
147
157
  ```
148
158
 
149
- <a name="real-ip"></a>** Custom User IP **
159
+ <a name="real-ip"></a>**Custom User IP**
150
160
 
151
161
  > Note: IP extraction, according to your network setup, is very important. It is common to have a load balancer/proxy on top of your applications, in which case the PerimeterX module will send the system's internal IP as the user's. In order to properly perform processing and detection on server-to-server calls, PerimeterX module needs the real user's IP.
152
162
 
153
163
  By default the clients IP is taken from the ``REMOTE_ADDR`` header, in case the user decides to use different header or custom function that extract the header the following key should be added to the configuration
154
164
 
155
- *** Custom header ***
165
+ ***Custom header***
156
166
  ```ruby
157
167
  configuration = {
158
168
  "app_id" => <APP_ID>,
@@ -160,7 +170,7 @@ configuration = {
160
170
  "custom_user_ip" => <HTTP_HEADER_NAME>,
161
171
  ```
162
172
 
163
- *** Custom Function ***
173
+ ***Custom Function***
164
174
  > Note: the function receive as a first parameter the controller request and must return the ip at the end as string
165
175
 
166
176
  ```ruby
@@ -213,15 +223,6 @@ Default mode: PxModule::ACTIVE_MODE
213
223
  params[:module_mode] = PxModule::MONITOR_MODE
214
224
  ```
215
225
 
216
- <a name="captcha-support"></a>**Enable/Disable CAPTCHA on the block page**
217
- Default mode: enabled
218
-
219
- By enabling CAPTCHA support, a CAPTCHA will be served as part of the block page, giving real users the ability to identify as a human. By solving the CAPTCHA, the user's score is then cleaned up and the user is allowed to continue normal use.
220
-
221
- ```ruby
222
- params[:captcha_enabled] = false
223
- ```
224
-
225
226
  <a name="custom-uri"></a>**Custom URI**
226
227
 
227
228
  Default: 'REQUEST_URI'
@@ -285,6 +286,71 @@ Enables debug logging mode to STDOUT
285
286
  params[:debug] = true
286
287
  ```
287
288
 
289
+ <a name="whitelist-routes"></a>**Whitelist Routes**
290
+ Default: []
291
+
292
+ An array of route prefixes and/or regular expressions that are always whitelisted and not validated by PerimeterX.
293
+ A string value of a path will be treated as a prefix.
294
+ A regexp value of a path will be treated as is.
295
+
296
+ ```ruby
297
+ params[:whitelist_routes] = ["/example", /\A\/example\z/]
298
+ ```
299
+
300
+ <a name="update-config"></a>**Update Configuration on Runtime**
301
+
302
+ As mentioned before, PerimeterX Module should be configured in `<rails_app>/config/initializers/perimeterx.rb`.
303
+ However, it is possible to override configuration options on each request.
304
+ To do so, send the configuration options as an argument when calling to `px_verify_request` as described in the following example.
305
+ Notice that in case of an invalid argument, the module will raise an error. Therefore, when using this feature, make sure to wrap the call to `px_verify_request` with begin and rescue. It is highly recommended to log the error message to follow such errors.
306
+
307
+ Usage example:
308
+
309
+ ```ruby
310
+ class HomeController < ApplicationController
311
+ include PxModule
312
+
313
+ before_action do call_perimeterx_verify_request end
314
+
315
+ def call_perimeterx_verify_request
316
+ params = {
317
+ :blocking_score => 70,
318
+ :module_mode => 2
319
+ }
320
+ begin
321
+ px_verify_request(params)
322
+ rescue StandardError => e
323
+ # $stdout.write(e.message)
324
+ end
325
+ end
326
+
327
+ end
328
+ ```
329
+
330
+ <a name="first-party"></a>**First Party**
331
+
332
+ To enable first party on your enforcer, add the following routes to your `config/routes.rb` file:
333
+
334
+ ```ruby
335
+ get '/:appid_postfix/init.js', to: 'home#index', constraints: { appid_postfix: /XXXXXXXX/ }
336
+ get '/:appid_postfix/captcha/:all', to: 'home#index', constraints: { appid_postfix: /XXXXXXXX/, all:/.*/ }
337
+ post '/:appid_postfix/xhr/:all', to: 'home#index', constraints: { appid_postfix: /XXXXXXXX/, all:/.*/ }
338
+ ```
339
+
340
+ Notice that all occurences of `XXXXXXXX` should be replaced with your px_app_id without the "PX" prefix. For example, if your px_app_id is `PX2H4seK9L`, replace `XXXXXXXX` with `2H4seK9L`.
341
+
342
+ In case you are using more than one px_app_id, provide all of them with a `|` sign between them. For example: 2H4seK9L|9bMs6K94|Lc5kPMNx
343
+
344
+
345
+ First Party configuration:
346
+
347
+ Default: true
348
+
349
+ ```ruby
350
+ params[:first_party_enabled] = false
351
+ ```
352
+
353
+
288
354
  <a name="contributing"></a># Contributing #
289
355
  ------------------------------
290
356
  The following steps are welcome when contributing to our project.
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perimeter_x
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nitzan Goldfeder
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-27 00:00:00.000000000 Z
11
+ date: 2020-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.14'
19
+ version: '2.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.14'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '12.3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '12.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: concurrent-ruby
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -104,14 +104,14 @@ dependencies:
104
104
  requirements:
105
105
  - - ">="
106
106
  - !ruby/object:Gem::Version
107
- version: 4.2.0
107
+ version: 5.2.4.3
108
108
  type: :runtime
109
109
  prerelease: false
110
110
  version_requirements: !ruby/object:Gem::Requirement
111
111
  requirements:
112
112
  - - ">="
113
113
  - !ruby/object:Gem::Version
114
- version: 4.2.0
114
+ version: 5.2.4.3
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: rspec
117
117
  requirement: !ruby/object:Gem::Requirement
@@ -171,24 +171,24 @@ files:
171
171
  - lib/perimeterx/configuration.rb
172
172
  - lib/perimeterx/internal/clients/perimeter_x_activity_client.rb
173
173
  - lib/perimeterx/internal/clients/perimeter_x_risk_client.rb
174
+ - lib/perimeterx/internal/exceptions/px_config_exception.rb
174
175
  - lib/perimeterx/internal/exceptions/px_cookie_decryption_exception.rb
176
+ - lib/perimeterx/internal/first_party/px_first_party.rb
175
177
  - lib/perimeterx/internal/payload/perimeter_x_cookie_v1.rb
176
178
  - lib/perimeterx/internal/payload/perimeter_x_cookie_v3.rb
177
179
  - lib/perimeterx/internal/payload/perimeter_x_payload.rb
178
180
  - lib/perimeterx/internal/payload/perimeter_x_token_v1.rb
179
181
  - lib/perimeterx/internal/payload/perimeter_x_token_v3.rb
180
182
  - lib/perimeterx/internal/perimeter_x_context.rb
181
- - lib/perimeterx/internal/validators/perimeter_x_captcha_validator.rb
183
+ - lib/perimeterx/internal/validators/hash_schema_validator.rb
182
184
  - lib/perimeterx/internal/validators/perimeter_x_cookie_validator.rb
183
185
  - lib/perimeterx/internal/validators/perimeter_x_s2s_validator.rb
184
186
  - lib/perimeterx/utils/px_constants.rb
185
187
  - lib/perimeterx/utils/px_http_client.rb
186
188
  - lib/perimeterx/utils/px_logger.rb
187
189
  - lib/perimeterx/utils/px_template_factory.rb
188
- - lib/perimeterx/utils/templates/block.mobile.mustache
189
- - lib/perimeterx/utils/templates/block.mustache
190
- - lib/perimeterx/utils/templates/captcha.mobile.mustache
191
- - lib/perimeterx/utils/templates/captcha.mustache
190
+ - lib/perimeterx/utils/templates/block_template.mustache
191
+ - lib/perimeterx/utils/templates/ratelimit.mustache
192
192
  - lib/perimeterx/version.rb
193
193
  - perimeter_x.gemspec
194
194
  - readme.md
@@ -215,8 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
215
215
  - !ruby/object:Gem::Version
216
216
  version: '0'
217
217
  requirements: []
218
- rubyforge_project:
219
- rubygems_version: 2.6.11
218
+ rubygems_version: 3.0.3
220
219
  signing_key:
221
220
  specification_version: 4
222
221
  summary: PerimeterX ruby implmentation
@@ -1,65 +0,0 @@
1
- require 'perimeterx/internal/clients/perimeter_x_risk_client'
2
-
3
- module PxModule
4
- class PerimeterxCaptchaValidator < PerimeterxRiskClient
5
-
6
- def initialize(px_config, http_client)
7
- super(px_config, http_client)
8
- end
9
-
10
- def send_captcha_request(vid, uuid, captcha, px_ctx)
11
-
12
- request_body = {
13
- :request => {
14
- :ip => px_ctx.context[:ip],
15
- :headers => format_headers(px_ctx),
16
- :uri => px_ctx.context[:uri]
17
- },
18
- :pxCaptcha => captcha,
19
- :vid => vid,
20
- :uuid => uuid,
21
- :hostname => px_ctx.context[:hostname]
22
- }
23
-
24
- # Prepare request
25
- headers = {
26
- "Authorization" => "Bearer #{@px_config[:auth_token]}" ,
27
- "Content-Type" => "application/json"
28
- };
29
-
30
- return @http_client.post(PxModule::API_V1_CAPTCHA, request_body, headers, @px_config[:api_timeout], @px_config[:api_timeout_connection])
31
-
32
- end
33
-
34
- def verify(px_ctx)
35
- captcha_validated = false
36
- begin
37
- if(!px_ctx.context.key?(:px_captcha))
38
- return captcha_validated, px_ctx
39
- end
40
- captcha, vid, uuid = px_ctx.context[:px_captcha].split(':', 3)
41
- if captcha.nil? || vid.nil? || uuid.nil?
42
- return captcha_validated, px_ctx
43
- end
44
-
45
- px_ctx.context[:vid] = vid
46
- px_ctx.context[:uuid] = uuid
47
- response = send_captcha_request(vid, uuid, captcha, px_ctx)
48
-
49
- if (response.status_code == 200)
50
- response_body = eval(response.body)
51
- if ( response_body[:code] == 0 )
52
- captcha_validated = true
53
- end
54
- end
55
-
56
- return captcha_validated, px_ctx
57
-
58
- rescue Exception => e
59
- @logger.error("PerimeterxCaptchaValidator[verify]: failed, returning false")
60
- return captcha_validated, px_ctx
61
- end
62
- end
63
-
64
- end
65
- end