perimeter_x 2.2.0 → 2.3.1

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: 475e2577bfe9b12bb7edbe3286fb4f1861a9c508791f38b0196dea0f493f355e
4
- data.tar.gz: b0c61698741743a62ad0a7c9fb67dc6d5ed9f9b78c01d08b764cb1297ee37c98
3
+ metadata.gz: b6018176a0638b42f0652e82640ef7e1365ab95eb2ab60eb590293abd46c6ada
4
+ data.tar.gz: 9f83381eebbf00b3d5ac3779471ca9b6a3b9f47d20186c73c09baf95e4cffabf
5
5
  SHA512:
6
- metadata.gz: 3bae8b3e45c8ee8aba86a56ed977158adec12bccfa2542e1a4e54344b6b6fb0503182585816c1b55640bd49ea4d6323831e93ad6c8d3335703e33d695df362ba
7
- data.tar.gz: d7a64faa2f03fd4bc467cdea545a2f530001431f37281c2a9561dd83c28c00006fe827e8cd510560fbbbd1a69d382993ae513edd214a18a277bcca57dd561fdc
6
+ metadata.gz: 5f68e2053d41f8e2a2e2e668c8db35f8d573c68840c9757210a7d5e52dcd46e38190c5579425c625afd4802df4c5333fe4069f582d71db61aadb6c78ac28c6f9
7
+ data.tar.gz: 1780884b590f3680969333f0c66d7e32b3ec402640fb5341e37cffcfef6904b79dc679c0de07acd291b0ddf7b6a46044add5f41a9713bff3b5bf6be0cd38c250
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright © 2016 PerimeterX, Inc.
1
+ Copyright © 2022 PerimeterX, Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/changelog.md CHANGED
@@ -5,6 +5,26 @@ 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.1] - 2022-04-11
9
+
10
+ ### Fixed
11
+
12
+ - URLs with query params did not render properly on new block page
13
+
14
+ ## [2.3.0] - 2022-04-10
15
+
16
+ ### Added
17
+
18
+ - Custom logo in block JSON response
19
+
20
+ ### Changed
21
+
22
+ - Updated block page to use new template
23
+
24
+ ## [2.2.1] - 2020-09-27
25
+ ### Fixed
26
+ - bypass_monitor_header type validation
27
+
8
28
  ## [2.2.0] - 2020-09-15
9
29
  ### Added
10
30
  - First Party
data/lib/perimeter_x.rb CHANGED
@@ -56,19 +56,22 @@ module PxModule
56
56
  end
57
57
 
58
58
  is_mobile = px_ctx.context[:cookie_origin] == 'header' ? '1' : '0'
59
- action = px_ctx.context[:block_action][0,1]
59
+ action = px_ctx.context[:block_action][0,1]
60
+ block_script_uri = "/captcha.js?a=#{action}&u=#{px_ctx.context[:uuid]}&v=#{px_ctx.context[:vid]}&m=#{is_mobile}"
60
61
 
61
62
  if px_config[:first_party_enabled]
62
63
  px_template_object = {
63
64
  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"
65
+ block_script: "/#{px_config[:app_id][2..-1]}/captcha/#{px_config[:app_id]}#{block_script_uri}",
66
+ host_url: "/#{px_config[:app_id][2..-1]}/xhr",
67
+ alt_block_script: "//#{PxModule::ALT_CAPTCHA_HOST}/#{px_config[:app_id]}#{block_script_uri}"
66
68
  }
67
69
  else
68
70
  px_template_object = {
69
71
  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
+ block_script: "//#{PxModule::CAPTCHA_HOST}/#{px_config[:app_id]}#{block_script_uri}",
73
+ host_url: "https://collector-#{px_config[:app_id]}.perimeterx.net",
74
+ alt_block_script: "//#{PxModule::ALT_CAPTCHA_HOST}/#{px_config[:app_id]}#{block_script_uri}"
72
75
  }
73
76
  end
74
77
 
@@ -92,6 +95,8 @@ module PxModule
92
95
  :vid => px_ctx.context[:vid],
93
96
  :hostUrl => "https://collector-#{px_config[:app_id]}.perimeterx.net",
94
97
  :blockScript => px_template_object[:block_script],
98
+ :altBlockScript => px_template_object[:alt_block_script],
99
+ :customLogo => px_config[:custom_logo]
95
100
  }
96
101
 
97
102
  render :json => hash_json
@@ -54,7 +54,7 @@ module PxModule
54
54
  :whitelist_routes => {types: [Array], allowed_element_types: [String, Regexp], required: false},
55
55
  :ip_headers => {types: [Array], allowed_element_types: [String], required: false},
56
56
  :ip_header_function => {types: [Proc], required: false},
57
- :bypass_monitor_header => {types: [FalseClass, TrueClass], required: false},
57
+ :bypass_monitor_header => {types: [String], required: false},
58
58
  :risk_cookie_max_iterations => {types: [Integer], required: false},
59
59
  :custom_verification_handler => {types: [Proc], required: false},
60
60
  :additional_activity_handler => {types: [Proc], required: false},
@@ -36,11 +36,11 @@ module PxModule
36
36
  PROP_APP_ID = :appId
37
37
  PROP_VID = :vid
38
38
  PROP_UUID = :uuid
39
- PROP_LOGO_VISIBILITY = :logoVisibility
40
39
  PROP_CUSTOM_LOGO = :customLogo
41
40
  PROP_CSS_REF = :cssRef
42
41
  PROP_JS_REF = :jsRef
43
42
  PROP_BLOCK_SCRIPT = :blockScript
43
+ PROP_ALT_BLOCK_SCRIPT = :altBlockScript
44
44
  PROP_JS_CLIENT_SRC = :jsClientSrc
45
45
  PROP_HOST_URL = :hostUrl
46
46
  PROP_FIRST_PARTY_ENABLED = :firstPartyEnabled
@@ -48,6 +48,7 @@ module PxModule
48
48
  # Hosts
49
49
  CLIENT_HOST = 'client.perimeterx.net'
50
50
  CAPTCHA_HOST = 'captcha.px-cdn.net'
51
+ ALT_CAPTCHA_HOST = 'captcha.px-cloud.net'
51
52
 
52
53
  VISIBLE = 'visible'
53
54
  HIDDEN = 'hidden'
@@ -6,7 +6,7 @@ module PxModule
6
6
  def self.get_template(px_ctx, px_config, px_template_object)
7
7
  logger = px_config[:logger]
8
8
  if (px_config[:challenge_enabled] && px_ctx.context[:block_action] == 'challenge')
9
- logger.debug('PxTemplateFactory[get_template]: px challange triggered')
9
+ logger.debug('PxTemplateFactory[get_template]: px challenge triggered')
10
10
  return px_ctx.context[:block_action_data].html_safe
11
11
  end
12
12
 
@@ -23,15 +23,14 @@ module PxModule
23
23
  Mustache.template_file = "#{File.dirname(__FILE__) }/templates/#{template_type}#{PxModule::TEMPLATE_EXT}"
24
24
 
25
25
  view[PxModule::PROP_APP_ID] = px_config[:app_id]
26
- view[PxModule::PROP_REF_ID] = px_ctx.context[:uuid]
27
26
  view[PxModule::PROP_VID] = px_ctx.context[:vid]
28
27
  view[PxModule::PROP_UUID] = px_ctx.context[:uuid]
29
28
  view[PxModule::PROP_CUSTOM_LOGO] = px_config[:custom_logo]
30
29
  view[PxModule::PROP_CSS_REF] = px_config[:css_ref]
31
30
  view[PxModule::PROP_JS_REF] = px_config[:js_ref]
32
31
  view[PxModule::PROP_HOST_URL] = px_template_object[:host_url]
33
- view[PxModule::PROP_LOGO_VISIBILITY] = px_config[:custom_logo] ? PxModule::VISIBLE : PxModule::HIDDEN
34
32
  view[PxModule::PROP_BLOCK_SCRIPT] = px_template_object[:block_script]
33
+ view[PxModule::PROP_ALT_BLOCK_SCRIPT] = px_template_object[:alt_block_script]
35
34
  view[PxModule::PROP_JS_CLIENT_SRC] = px_template_object[:js_client_src]
36
35
  view[PxModule::PROP_FIRST_PARTY_ENABLED] = px_ctx.context[:first_party_enabled]
37
36
 
@@ -3,173 +3,42 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>Access to this page has been denied.</title>
7
- <link href="https://fonts.googleapis.com/css?family=Open+Sans:300" rel="stylesheet">
8
- <style>
9
- html, body {
10
- margin: 0;
11
- padding: 0;
12
- font-family: 'Open Sans', sans-serif;
13
- color: #000;
14
- }
15
-
16
- a {
17
- color: #c5c5c5;
18
- text-decoration: none;
19
- }
20
-
21
- .container {
22
- align-items: center;
23
- display: flex;
24
- flex: 1;
25
- justify-content: space-between;
26
- flex-direction: column;
27
- height: 100%;
28
- }
29
-
30
- .container > div {
31
- width: 100%;
32
- display: flex;
33
- justify-content: center;
34
- }
35
-
36
- .container > div > div {
37
- display: flex;
38
- width: 80%;
39
- }
40
-
41
- .customer-logo-wrapper {
42
- padding-top: 2rem;
43
- flex-grow: 0;
44
- background-color: #fff;
45
- visibility: {{logoVisibility}};
46
- }
47
-
48
- .customer-logo {
49
- border-bottom: 1px solid #000;
50
- }
51
-
52
- .customer-logo > img {
53
- padding-bottom: 1rem;
54
- max-height: 50px;
55
- max-width: 100%;
56
- }
57
-
58
- .page-title-wrapper {
59
- flex-grow: 2;
60
- }
61
-
62
- .page-title {
63
- flex-direction: column-reverse;
64
- }
65
-
66
- .content-wrapper {
67
- flex-grow: 5;
68
- }
69
-
70
- .content {
71
- flex-direction: column;
72
- }
73
-
74
- .page-footer-wrapper {
75
- align-items: center;
76
- flex-grow: 0.2;
77
- background-color: #000;
78
- color: #c5c5c5;
79
- font-size: 70%;
80
- }
81
-
82
- @media (min-width: 768px) {
83
- html, body {
84
- height: 100%;
85
- }
86
- }
87
- </style>
88
- <!-- Custom CSS -->
6
+ <meta name="description" content="px-captcha">
7
+ <title>Access to this page has been denied</title>
89
8
  {{#cssRef}}
90
9
  <link rel="stylesheet" type="text/css" href="{{{cssRef}}}"/>
91
10
  {{/cssRef}}
92
11
  </head>
93
-
94
12
  <body>
95
- <section class="container">
96
- <div class="customer-logo-wrapper">
97
- <div class="customer-logo">
98
- <img src="{{customLogo}}" alt="Logo"/>
99
- </div>
100
- </div>
101
- <div class="page-title-wrapper">
102
- <div class="page-title">
103
- <h1>Please verify you are a human</h1>
104
- </div>
105
- </div>
106
- <div class="content-wrapper">
107
- <div class="content">
108
-
109
- <div id="px-captcha">
110
- </div>
111
- <p>
112
- Access to this page has been denied because we believe you are using automation tools to browse the
113
- website.
114
- </p>
115
- <p>
116
- This may happen as a result of the following:
117
- </p>
118
- <ul>
119
- <li>
120
- Javascript is disabled or blocked by an extension (ad blockers for example)
121
- </li>
122
- <li>
123
- Your browser does not support cookies
124
- </li>
125
- </ul>
126
- <p>
127
- Please make sure that Javascript and cookies are enabled on your browser and that you are not blocking
128
- them from loading.
129
- </p>
130
- <p>
131
- Reference ID: #{{refId}}
132
- </p>
133
- </div>
134
- </div>
135
- <div class="page-footer-wrapper">
136
- <div class="page-footer">
137
- <p>
138
- Powered by
139
- <a href="https://www.perimeterx.com/whywasiblocked">PerimeterX</a>
140
- , Inc.
141
- </p>
142
- </div>
143
- </div>
144
- </section>
145
- <!-- Px -->
146
- <script>
147
- window._pxAppId = '{{appId}}';
148
- window._pxJsClientSrc = '{{{jsClientSrc}}}';
149
- window._pxFirstPartyEnabled = {{firstPartyEnabled}};
150
- window._pxVid = '{{vid}}';
151
- window._pxUuid = '{{uuid}}';
152
- window._pxHostUrl = '{{{hostUrl}}}';
153
- </script>
154
- <script>
155
- var s = document.createElement('script');
156
- s.src = '{{{blockScript}}}';
157
- var p = document.getElementsByTagName('head')[0];
158
- p.insertBefore(s, null);
159
- if ({{firstPartyEnabled}}) {
160
- s.onerror = function () {
161
- s = document.createElement('script');
162
- var suffixIndex = '{{{blockScript}}}'.indexOf('captcha.js');
163
- var temperedBlockScript = '{{{blockScript}}}'.substring(suffixIndex);
164
- s.src = '//captcha.px-cdn.net/{{appId}}/' + temperedBlockScript;
165
- p.parentNode.insertBefore(s, p);
13
+ <script>
14
+ window._pxVid = '{{vid}}';
15
+ window._pxUuid = '{{uuid}}';
16
+ window._pxAppId = '{{appId}}';
17
+ window._pxCustomLogo = '{{{customLogo}}}';
18
+ window._pxHostUrl = '{{{hostUrl}}}';
19
+ window._pxJsClientSrc = '{{{jsClientSrc}}}';
20
+ window._pxFirstPartyEnabled = {{firstPartyEnabled}};
21
+ var script = document.createElement('script');
22
+ script.src = '{{{blockScript}}}';
23
+ document.head.appendChild(script);
24
+ script.onerror = function () {
25
+ script = document.createElement('script');
26
+ script.src = '{{{altBlockScript}}}';
27
+ script.onerror = window._pxDisplayErrorMessage;
28
+ document.head.appendChild(script);
166
29
  };
167
- }
168
- </script>
169
-
170
- <!-- Custom Script -->
171
- {{#jsRef}}
172
- <script src="{{{jsRef}}}"></script>
173
- {{/jsRef}}
30
+ window._pxDisplayErrorMessage = function () {
31
+ var style = document.createElement('style');
32
+ style.innerText = '@import url(https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap);body{background-color:#fafbfc}@media (max-width:480px){body{background-color:#fff}}.px-captcha-error-container{position:fixed;height:328px;background-color:#fff;font-family:Roboto,sans-serif}.px-captcha-error-header{color:#f0f1f2;font-size:29px;margin:67px 0 33px;font-weight:500;line-height:.83;text-align:center}.px-captcha-error-message{color:#f0f1f2;font-size:18px;margin:0 0 29px;line-height:1.33;text-align:center}div.px-captcha-error-button{text-align:center;line-height:50px;width:253px;margin:auto;border-radius:25px;border:solid 1px #f0f1f2;font-size:20px;color:#f0f1f2}div.px-captcha-error-wrapper{margin:23px 0 0}div.px-captcha-error{margin:auto;text-align:center;width:400px;height:30px;font-size:12px;background-color:#fcf0f2;color:#ce0e2d}img.px-captcha-error{margin:6px 10px -2px 0}@media (min-width:620px){.px-captcha-error-container{width:528px;top:50%;left:50%;margin-top:-164px;margin-left:-264px;border-radius:3px;box-shadow:0 2px 9px -1px rgba(0,0,0,.13)}}@media (min-width:481px) and (max-width:620px){.px-captcha-error-container{width:85%;top:50%;left:50%;margin-top:-164px;margin-left:-42.5%;border-radius:3px;box-shadow:0 2px 9px -1px rgba(0,0,0,.13)}}@media (max-width:480px){.px-captcha-error-container{width:528px;top:50%;left:50%;margin-top:-164px;margin-left:-264px}}';
33
+ document.head.appendChild(style);
34
+ var div = document.createElement('div');
35
+ div.className = 'px-captcha-error-container';
36
+ div.innerHTML = '<div class="px-captcha-error-header">Before we continue...</div><div class="px-captcha-error-message">Press & Hold to confirm you are<br>a human (and not a bot).</div><div class="px-captcha-error-button">Press & Hold</div><div class="px-captcha-error-wrapper"><div class="px-captcha-error"><img class="px-captcha-error" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAQCAMAAADDGrRQAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAABFUExURUdwTNYELOEGONQILd0AONwALtwEL+AAL9MFLfkJSNQGLdMJLdQJLdQGLdQKLtYFLNcELdUGLdcBL9gFL88OLdUFLNEOLglBhT4AAAAXdFJOUwC8CqgNIRgRoAS1dWWuR4RTjzgryZpYblfkcAAAAI9JREFUGNNdj+sWhCAIhAdvqGVa1r7/oy6RZ7eaH3D4ZACBIed9wlOOMtUnSrEmZ6cHa9YAIfsbCkWrdpi/c50Bk2CO9mNLdMAu03wJA3HpEnfpxbyOg6ruyx8JJi6KNstnslp1dbPd9GnqmuYq7mmcv1zjnbQw8cV0xzkqo+fX1zkjUOO7wnrInUTxJiruC3vtBNRoQQn2AAAAAElFTkSuQmCC">Please check your network connection or disable your ad-blocker.</div></div>';
37
+ document.body.appendChild(div);
38
+ };
39
+ </script>
40
+ {{#jsRef}}
41
+ <script src="{{{jsRef}}}"></script>
42
+ {{/jsRef}}
174
43
  </body>
175
- </html>
44
+ </html>
@@ -1,3 +1,3 @@
1
1
  module PxModule
2
- VERSION = '2.2.0'
2
+ VERSION = '2.3.1'
3
3
  end
data/px_metadata.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "version": "2.3.1",
3
+ "supported_features": [
4
+ "additional_activity_handler",
5
+ "advanced_blocking_response",
6
+ "batched_activities",
7
+ "block_activity",
8
+ "block_page_captcha",
9
+ "block_page_rate_limit",
10
+ "bypass_monitor_header",
11
+ "client_ip_extraction",
12
+ "cookie_v3",
13
+ "css_ref",
14
+ "custom_logo",
15
+ "logger",
16
+ "filter_by_route",
17
+ "first_party",
18
+ "js_ref",
19
+ "mobile_support",
20
+ "module_enable",
21
+ "module_mode",
22
+ "page_requested_activity",
23
+ "vid_extraction",
24
+ "risk_api",
25
+ "sensitive_headers",
26
+ "sensitive_routes"
27
+ ]
28
+ }
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.1.0](https://rubygems.org/gems/perimeter_x)
8
+ > Latest stable version: [v2.3.1](https://rubygems.org/gems/perimeter_x)
9
9
 
10
10
  Table of Contents
11
11
  -----------------
@@ -19,8 +19,6 @@ Table of Contents
19
19
  * [Blocking Score](#blocking-score)
20
20
  * [Custom Verification Action](#custom-verification-action)
21
21
  * [Custom Block Page](#custom-block-page)
22
- * [Enable/Disable Captcha](#captcha-support)
23
- * [Select Captcha Provider](#captcha-provider)
24
22
  * [Extracting Real IP Address](#real-ip)
25
23
  * [Custom URI](#custom-uri)
26
24
  * [Filter Sensitive Headers](#sensitive-headers)
@@ -33,6 +31,7 @@ Table of Contents
33
31
  * [Update Configuration on Runtime](#update-config)
34
32
  * [First Party](#first-party)
35
33
 
34
+ **[Additional Information](#additional-information)**
36
35
  **[Contributing](#contributing)**
37
36
 
38
37
  <a name="Usage"></a>
@@ -225,26 +224,6 @@ Default mode: PxModule::ACTIVE_MODE
225
224
  params[:module_mode] = PxModule::MONITOR_MODE
226
225
  ```
227
226
 
228
- <a name="captcha-support"></a>**Enable/Disable CAPTCHA on the block page**
229
- Default mode: enabled
230
-
231
- 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.
232
-
233
- ```ruby
234
- params[:captcha_enabled] = false
235
- ```
236
-
237
- <a name="captcha-provider"></a>**Select CAPTCHA Provider**
238
-
239
- The CAPTCHA part of the block page can use one of the following:
240
- * [reCAPTCHA](https://www.google.com/recaptcha)
241
-
242
- Default: 'reCaptcha'
243
-
244
- ```ruby
245
- captchaProvider = "reCaptcha"
246
- ```
247
-
248
227
  <a name="custom-uri"></a>**Custom URI**
249
228
 
250
229
  Default: 'REQUEST_URI'
@@ -326,11 +305,12 @@ However, it is possible to override configuration options on each request.
326
305
  To do so, send the configuration options as an argument when calling to `px_verify_request` as described in the following example.
327
306
  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.
328
307
 
308
+ Usage example:
309
+
329
310
  ```ruby
330
311
  class HomeController < ApplicationController
331
312
  include PxModule
332
313
 
333
-
334
314
  before_action do call_perimeterx_verify_request end
335
315
 
336
316
  def call_perimeterx_verify_request
@@ -349,6 +329,7 @@ end
349
329
  ```
350
330
 
351
331
  <a name="first-party"></a>**First Party**
332
+
352
333
  To enable first party on your enforcer, add the following routes to your `config/routes.rb` file:
353
334
 
354
335
  ```ruby
@@ -357,19 +338,25 @@ To enable first party on your enforcer, add the following routes to your `config
357
338
  post '/:appid_postfix/xhr/:all', to: 'home#index', constraints: { appid_postfix: /XXXXXXXX/, all:/.*/ }
358
339
  ```
359
340
 
360
- 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`, reeplace `XXXXXXXX` with `2H4seK9L`.
341
+ 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`.
342
+
361
343
  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
362
344
 
363
345
 
364
346
  First Party configuration:
347
+
365
348
  Default: true
366
349
 
367
350
  ```ruby
368
351
  params[:first_party_enabled] = false
369
352
  ```
370
353
 
354
+ <a name="additional_information"></a> Additional Information
355
+ ------------------------------
356
+ ### URI Delimiters
357
+ PerimeterX processes URI paths with general- and sub-delimiters according to RFC 3986. General delimiters (e.g., `?`, `#`) are used to separate parts of the URI. Sub-delimiters (e.g., `$`, `&`) are not used to split the URI as they are considered valid characters in the URI path.
371
358
 
372
- <a name="contributing"></a># Contributing #
359
+ <a name="contributing"></a> Contributing
373
360
  ------------------------------
374
361
  The following steps are welcome when contributing to our project.
375
362
  ###Fork/Clone
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.2.0
4
+ version: 2.3.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: 2020-09-15 00:00:00.000000000 Z
11
+ date: 2022-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -191,6 +191,7 @@ files:
191
191
  - lib/perimeterx/utils/templates/ratelimit.mustache
192
192
  - lib/perimeterx/version.rb
193
193
  - perimeter_x.gemspec
194
+ - px_metadata.json
194
195
  - readme.md
195
196
  homepage: https://www.perimeterx.com
196
197
  licenses:
@@ -215,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
215
216
  - !ruby/object:Gem::Version
216
217
  version: '0'
217
218
  requirements: []
218
- rubygems_version: 3.0.3
219
+ rubygems_version: 3.0.3.1
219
220
  signing_key:
220
221
  specification_version: 4
221
222
  summary: PerimeterX ruby implmentation