perimeter_x 2.3.1 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6018176a0638b42f0652e82640ef7e1365ab95eb2ab60eb590293abd46c6ada
4
- data.tar.gz: 9f83381eebbf00b3d5ac3779471ca9b6a3b9f47d20186c73c09baf95e4cffabf
3
+ metadata.gz: ea98817074a862f9cf5dca2d01fd56ab31f3376e92fd695cd9a8a86c0713dea6
4
+ data.tar.gz: 302bf6d40f9e0e9a4776153a53fc5315bbd4047ccbc54dca5c082ecc6156900d
5
5
  SHA512:
6
- metadata.gz: 5f68e2053d41f8e2a2e2e668c8db35f8d573c68840c9757210a7d5e52dcd46e38190c5579425c625afd4802df4c5333fe4069f582d71db61aadb6c78ac28c6f9
7
- data.tar.gz: 1780884b590f3680969333f0c66d7e32b3ec402640fb5341e37cffcfef6904b79dc679c0de07acd291b0ddf7b6a46044add5f41a9713bff3b5bf6be0cd38c250
6
+ metadata.gz: 4ab3a9adfcc046a69e9c0c43c7fb603ba62b7bc793919d0560eaeec2fcf52f5521dea5b9665883ecfc9fd667017898aebe73466bebf560af522a141184b13a13
7
+ data.tar.gz: 6a7ee7cd89f58d34edf035fc7762361738922ead805232bc607450df2479bef4d5545a0e55243b65d355ff36442ff9fd6089fbea3abcf626fdd3b54f9ce7c8ac
data/.gitignore CHANGED
@@ -17,6 +17,8 @@ examples/app/views/home/index.html.erb
17
17
  *.gem
18
18
  rerun.txt
19
19
  pickle-email-*.html
20
+ .idea/
21
+ .vscode/
20
22
 
21
23
  # TODO Comment out these rules if you are OK with secrets being uploaded to the repo
22
24
  config/initializers/secret_token.rb
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- perimeter_x (2.0.0)
5
- activesupport (>= 5.2.4.3)
4
+ perimeter_x (2.3.1)
6
5
  concurrent-ruby (~> 1.0, >= 1.0.5)
7
6
  mustache (~> 1.0, >= 1.0.3)
8
7
  typhoeus (~> 1.1, >= 1.1.2)
@@ -10,20 +9,11 @@ PATH
10
9
  GEM
11
10
  remote: https://rubygems.org/
12
11
  specs:
13
- activesupport (6.0.3.2)
14
- concurrent-ruby (~> 1.0, >= 1.0.2)
15
- i18n (>= 0.7, < 2)
16
- minitest (~> 5.1)
17
- tzinfo (~> 1.1)
18
- zeitwerk (~> 2.2, >= 2.2.2)
19
- concurrent-ruby (1.1.6)
12
+ concurrent-ruby (1.1.10)
20
13
  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)
14
+ ethon (0.15.0)
15
+ ffi (>= 1.15.0)
16
+ ffi (1.15.5)
27
17
  mocha (1.11.2)
28
18
  mustache (1.1.1)
29
19
  rake (13.0.1)
@@ -40,12 +30,8 @@ GEM
40
30
  diff-lcs (>= 1.2.0, < 2.0)
41
31
  rspec-support (~> 3.9.0)
42
32
  rspec-support (3.9.3)
43
- thread_safe (0.3.6)
44
33
  typhoeus (1.4.0)
45
34
  ethon (>= 0.9.0)
46
- tzinfo (1.2.7)
47
- thread_safe (~> 0.1)
48
- zeitwerk (2.3.1)
49
35
 
50
36
  PLATFORMS
51
37
  ruby
data/changelog.md CHANGED
@@ -5,6 +5,14 @@ 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.3.2] - 2022-xx-xx
9
+
10
+ ### Changed
11
+
12
+ - Removed dependency on Active Support
13
+ - Replaced `eval()` calls with `JSON.parse()` for improved security
14
+ - Small spec alignment changes (risk_api and block activities)
15
+
8
16
  ## [2.3.1] - 2022-04-11
9
17
 
10
18
  ### Fixed
@@ -82,8 +82,10 @@ module PxModule
82
82
  # merge request configuration into the basic configuration
83
83
  @configuration = @@basic_config.merge(params)
84
84
  validate_hash_schema(@configuration, CONFIG_SCHEMA)
85
-
86
- @configuration[:backend_url] = "https://sapi-#{@configuration[:app_id].downcase}.perimeterx.net"
85
+
86
+ if (! @configuration.key?(:backend_url))
87
+ @configuration[:backend_url] = "https://sapi-#{@configuration[:app_id].downcase}.perimeterx.net"
88
+ end
87
89
  @configuration[:logger] = PxLogger.new(@configuration[:debug])
88
90
  end
89
91
  end
@@ -63,6 +63,7 @@ module PxModule
63
63
  :client_uuid => px_ctx.context[:uuid],
64
64
  :block_score => px_ctx.context[:score],
65
65
  :block_reason => px_ctx.context[:blocking_reason],
66
+ :block_action => px_ctx.context[:block_action],
66
67
  :simulated_block => @px_config[:module_mode] == PxModule::MONITOR_MODE
67
68
  }
68
69
 
@@ -22,7 +22,7 @@ module PxModule
22
22
  end
23
23
 
24
24
  def valid_format?(cookie)
25
- return cookie.key?(:t) && cookie.key?(:s) && cookie.key?(:u) && cookie.key?(:u) && cookie.key?(:a)
25
+ return cookie.key?(:t) && cookie.key?(:s) && cookie.key?(:u) && cookie.key?(:a)
26
26
  end
27
27
 
28
28
  def cookie_block_action
@@ -1,6 +1,6 @@
1
- require 'active_support/security_utils'
2
1
  require 'base64'
3
2
  require 'openssl'
3
+ require 'json'
4
4
  require 'perimeterx/internal/exceptions/px_cookie_decryption_exception'
5
5
 
6
6
  module PxModule
@@ -123,7 +123,7 @@ module PxModule
123
123
  cipher.iv = iv
124
124
  plaintext = cipher.update(cipher_text) + cipher.final
125
125
 
126
- return eval(plaintext)
126
+ return JSON.parse(plaintext, symbolize_names: true)
127
127
  rescue Exception => e
128
128
  @logger.debug("PerimeterxCookie[decrypt]: Cookie decrypt fail #{e.message}")
129
129
  raise PxCookieDecryptionException.new("Cookie decrypt fail => #{e.message}");
@@ -131,18 +131,26 @@ module PxModule
131
131
  end
132
132
 
133
133
  def decode(px_cookie)
134
- return eval(Base64.decode64(px_cookie))
134
+ return JSON.parse(Base64.decode64(px_cookie), symbolize_names: true)
135
135
  end
136
136
 
137
137
 
138
138
  def hmac_valid?(hmac_str, cookie_hmac)
139
139
  hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, @cookie_secret, hmac_str)
140
- # ref: https://thisdata.com/blog/timing-attacks-against-string-comparison/
141
- password_correct = ActiveSupport::SecurityUtils.secure_compare(
142
- ::Digest::SHA256.hexdigest(cookie_hmac),
143
- ::Digest::SHA256.hexdigest(hmac)
144
- )
140
+ password_correct = secure_compare(hmac, cookie_hmac)
141
+ end
142
+
143
+ def secure_compare(a, b)
144
+ # https://github.com/rails/rails/blob/main/activesupport/lib/active_support/security_utils.rb
145
+ if (a.bytesize != b.bytesize)
146
+ return false
147
+ end
148
+
149
+ l = a.unpack "C#{a.bytesize}"
145
150
 
151
+ res = 0
152
+ b.each_byte { |byte| res |= byte ^ l.shift }
153
+ res == 0
146
154
  end
147
155
  end
148
156
  end
@@ -101,17 +101,17 @@ module PxModule
101
101
  @context[:sensitive_route] = check_sensitive_route(px_config[:sensitive_routes], @context[:uri])
102
102
  end #end init
103
103
 
104
- def check_sensitive_route(sensitive_routes, uri)
105
- sensitive_routes.each do |sensitive_route|
106
- return true if uri.start_with? sensitive_route
107
- end
108
- false
109
- end
104
+ def check_sensitive_route(sensitive_routes, uri)
105
+ sensitive_routes.each do |sensitive_route|
106
+ return true if uri.start_with? sensitive_route
107
+ end
108
+ false
109
+ end
110
110
 
111
111
  def set_block_action_type(action)
112
112
  @context[:block_action] = case action
113
113
  when 'c'
114
- 'captcha'
114
+ return 'captcha'
115
115
  when 'b'
116
116
  return 'block'
117
117
  when 'j'
@@ -119,7 +119,7 @@ module PxModule
119
119
  when 'r'
120
120
  return 'rate_limit'
121
121
  else
122
- return captcha
122
+ return 'captcha'
123
123
  end
124
124
  end
125
125
 
@@ -1,3 +1,4 @@
1
+ require 'json'
1
2
  require 'perimeterx/internal/clients/perimeter_x_risk_client'
2
3
 
3
4
  module PxModule
@@ -20,7 +21,6 @@ module PxModule
20
21
  :request => {
21
22
  :ip => px_ctx.context[:ip],
22
23
  :headers => format_headers(px_ctx),
23
- :uri => px_ctx.context[:uri],
24
24
  :url => px_ctx.context[:full_url]
25
25
  },
26
26
  :additional => {
@@ -103,7 +103,7 @@ module PxModule
103
103
  px_ctx.context[:made_s2s_risk_api_call] = true
104
104
 
105
105
  # From here response should be valid, if success or error
106
- response_body = eval(response.body);
106
+ response_body = JSON.parse(response.body, symbolize_names: true);
107
107
  # When success
108
108
  if (response.code == 200 && response_body.key?(:score) && response_body.key?(:action) && response_body.key?(:status) && response_body[:status] == 0 )
109
109
  @logger.debug("PerimeterxS2SValidator[verify]: response ok")
@@ -1,3 +1,3 @@
1
1
  module PxModule
2
- VERSION = '2.3.1'
2
+ VERSION = '2.3.2'
3
3
  end
data/perimeter_x.gemspec CHANGED
@@ -33,7 +33,6 @@ 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', '>= 5.2.4.3')
37
36
 
38
37
  gem.add_development_dependency 'rspec', '~> 3.0'
39
38
  gem.add_development_dependency 'mocha', '~> 1.2', '>= 1.2.1'
data/px_metadata.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.3.1",
2
+ "version": "2.3.2",
3
3
  "supported_features": [
4
4
  "additional_activity_handler",
5
5
  "advanced_blocking_response",
data/readme.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [PerimeterX](http://www.perimeterx.com) Ruby SDK
6
6
  =============================================================
7
7
 
8
- > Latest stable version: [v2.3.1](https://rubygems.org/gems/perimeter_x)
8
+ > Latest stable version: [v2.3.2](https://rubygems.org/gems/perimeter_x)
9
9
 
10
10
  Table of Contents
11
11
  -----------------
@@ -161,14 +161,15 @@ params = {
161
161
 
162
162
  > 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.
163
163
 
164
- 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
164
+ 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.
165
165
 
166
166
  ***Custom header***
167
+ > Note: If there are multiple headers configured, the module will evaluate the headers in order and use the first value it finds.
167
168
  ```ruby
168
169
  configuration = {
169
170
  "app_id" => <APP_ID>,
170
171
  "auth_token" => <AUTH_TOKEN>,
171
- "custom_user_ip" => <HTTP_HEADER_NAME>,
172
+ "ip_headers" => [<HTTP_HEADER_NAME>, <BACKUP_HTTP_HEADER_NAME>],
172
173
  ```
173
174
 
174
175
  ***Custom Function***
@@ -178,7 +179,7 @@ configuration = {
178
179
  configuration = {
179
180
  "app_id" => <APP_ID>,
180
181
  "auth_token" => <AUTH_TOKEN>,
181
- "custom_user_ip_method" => -> (req) {
182
+ "ip_header_function" => -> (req) {
182
183
  # Method body
183
184
  return "1.2.3.4"
184
185
  }
@@ -214,14 +215,14 @@ params = [
214
215
  > Note: Custom logo/js/css can be added together
215
216
 
216
217
  <a name="logging"></a>**No Blocking, Monitor Only**
217
- Default mode: PxModule::ACTIVE_MODE
218
+ Default mode: PxModule::MONITOR_MODE
218
219
 
219
220
  - PxModule::ACTIVE_MODE - Module blocks users crossing the predefined block threshold. Server-to-server requests are sent synchronously.
220
221
 
221
- - PxModule::$MONITOR_MODE - Module does not block users crossing the predefined block threshold. The `custom_block_handler` function will be eval'd in case one is supplied, upon crossing the defined block threshold.
222
+ - PxModule::MONITOR_MODE - Module does not block users crossing the predefined block threshold. The `custom_block_handler` function will be eval'd in case one is supplied, upon crossing the defined block threshold.
222
223
 
223
224
  ```ruby
224
- params[:module_mode] = PxModule::MONITOR_MODE
225
+ params[:module_mode] = PxModule::ACTIVE_MODE
225
226
  ```
226
227
 
227
228
  <a name="custom-uri"></a>**Custom URI**
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perimeter_x
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nitzan Goldfeder
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-11 00:00:00.000000000 Z
11
+ date: 2022-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -98,20 +98,6 @@ dependencies:
98
98
  - - ">="
99
99
  - !ruby/object:Gem::Version
100
100
  version: 1.0.3
101
- - !ruby/object:Gem::Dependency
102
- name: activesupport
103
- requirement: !ruby/object:Gem::Requirement
104
- requirements:
105
- - - ">="
106
- - !ruby/object:Gem::Version
107
- version: 5.2.4.3
108
- type: :runtime
109
- prerelease: false
110
- version_requirements: !ruby/object:Gem::Requirement
111
- requirements:
112
- - - ">="
113
- - !ruby/object:Gem::Version
114
- version: 5.2.4.3
115
101
  - !ruby/object:Gem::Dependency
116
102
  name: rspec
117
103
  requirement: !ruby/object:Gem::Requirement