Skip to content

Commit 26dffd2

Browse files
author
Yaron Schwimmer
authored
Merge pull request #153 from PerimeterX/dev
Version 5.1.0
2 parents 8a14ffe + 59996f5 commit 26dffd2

File tree

7 files changed

+90
-12
lines changed

7 files changed

+90
-12
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## [5.1.0] - 2018-09-26
9+
### Added
10+
- Support for Advanced Blocking Response
11+
12+
### Fixed
13+
- Updated http/2 documentation section
14+
- firstPartyEnabled property for Captcha
15+
816
## [5.0.1] - 2018-09-02
917
### Added
1018
- Refreshed documentation

README.md

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
# [PerimeterX](http://www.perimeterx.com) NGINX Lua Plugin
66

7-
> Latest stable version: [v5.0.1](https://luarocks.org/modules/bendpx/perimeterx-nginx-plugin/5.0-1)
7+
> Latest stable version: [v5.1.0](https://luarocks.org/modules/bendpx/perimeterx-nginx-plugin/5.1-0)
88
99

1010
## [Introduction](#introduction)
@@ -50,7 +50,9 @@
5050
## [Enrichment](#enrichment)
5151
* [Data Enrichment](#data-enrichment)
5252
* [Log Enrichment](#log-enrichment)
53-
53+
54+
## [Advanced Blocking Response](#advancedBlockingResponse)
55+
5456
## [Appendix](#appendix)
5557
* [HTTP v2 Support](#http2)
5658
* [NGINX Plus](#nginxplus)
@@ -555,6 +557,8 @@ The following configurations are set in:
555557
}
556558
```
557559

560+
> NOTE: If your NGINX version supports HTTP v2, refer to the [HTTP v2 section of the Appendix](#http2).
561+
558562
> NOTE: The PerimeterX NGINX Lua Plugin Configuration Requirements must be completed before proceeding to the next stage of installation.
559563
560564
##### <a name="perimterx_first_party_js_snippet"></a> First-Party JS Snippet
@@ -863,8 +867,41 @@ For more information and the available fields in the JSON, refer to the Perimete
863867
}
864868
...
865869
```
870+
871+
<a name="advancedBlockingResponse"></a> Advanced Blocking Response
872+
------------------------------------------------------------------
873+
In special cases, (such as XHR post requests) a full Captcha page render might not be an option. In such cases, using the Advanced Blocking Response returns a JSON object continaing all the information needed to render your own Captcha challenge implementation, be it a popup modal, a section on the page, etc. The Advanced Blocking Response occurs when a request contains the *Accept* header with the value of `application/json`. A sample JSON response appears as follows:
874+
875+
```javascript
876+
{
877+
"appId": String,
878+
"jsClientSrc": String,
879+
"firstPartyEnabled": Boolean,
880+
"vid": String,
881+
"uuid": String,
882+
"hostUrl": String,
883+
"blockScript": String
884+
}
885+
```
886+
887+
Once you have the JSON response object, you can pass it to your implementation (with query strings or any other solution) and render the Captcha challenge.
888+
889+
In addition, you can add the `_pxOnCaptchaSuccess` callback function on the window object of your Captcha page to react according to the Captcha status. For example when using a modal, you can use this callback to close the modal once the Captcha is successfullt solved. <br/> An example of using the `_pxOnCaptchaSuccess` callback is as follows:
890+
891+
```javascript
892+
window._pxOnCaptchaSuccess = function(isValid) {
893+
if(isValid) {
894+
alert("yay");
895+
} else {
896+
alert("nay");
897+
}
898+
}
899+
```
900+
901+
For details on how to create a custom Captcha page, refer to the [documentation](https://console.perimeterx.com/docs/server_integration_new.html#custom-captcha-section)
902+
866903
<a name="appendix"></a> Appendix
867-
-----------------------------------------------
904+
--------------------------------
868905

869906
### <a name="http2"></a> HTTP v2 Support
870907
The PerimeterX NGINX module supports HTTP v2 for both Third-Party and First-Party implementations. To verify that your NGINX is running with HTTP v2 support, run:

lib/px/block/pxblock.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ function M.load(px_config)
2323
local ngx_exit = ngx.exit
2424
local string_gsub = string.gsub
2525

26+
local function is_accept_header_json(header)
27+
for h in string.gmatch(header, '[^,]+') do
28+
if string.lower(h) == "application/json" then
29+
return true;
30+
end
31+
end
32+
return false
33+
end
34+
2635
local function inject_captcha_script(vid, uuid)
2736
return '<script type="text/javascript">window._pxVid = "' .. vid .. '";' ..
2837
'window._pxUuid = "' .. uuid .. '";</script>'
@@ -104,6 +113,26 @@ function M.load(px_config)
104113
return
105114
end
106115

116+
-- json response
117+
local accept_header = ngx.req.get_headers()["accept"] or ngx.req.get_headers()["content-type"]
118+
local isJsonResponse = accept_header and is_accept_header_json(accept_header) and not ngx.ctx.px_is_mobile
119+
if isJsonResponse then
120+
local props = px_template.get_props(px_config, details.block_uuid, vid, parse_action(ngx.ctx.px_action))
121+
local result = {
122+
appId = props.appId,
123+
jsClientSrc = props.jsClientSrc,
124+
firstPartyEnabled = props.firstPartyEnabled,
125+
vid = props.firstPartyEnabled,
126+
uuid = props.uuid,
127+
hostUrl = props.hostUrl,
128+
blockScript = props.blockScript
129+
}
130+
ngx.header["Content-Type"] = 'application/json';
131+
ngx.status = ngx_HTTP_FORBIDDEN;
132+
ngx.say(cjson.encode(result))
133+
ngx_exit(ngx.OK)
134+
end
135+
107136
-- web scenarios
108137
ngx.header["Content-Type"] = 'text/html';
109138

lib/px/block/pxtemplate.lua

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,23 @@ function M.load(px_config)
1111
local px_constants = require "px.utils.pxconstants"
1212
local px_logger = require("px.utils.pxlogger").load(px_config)
1313

14-
local function get_props(px_config, uuid, vid, action)
14+
function _M.get_props(px_config, uuid, vid, action)
1515
local logo_css_style = 'visible'
1616
if (px_config.custom_logo == nil) then
1717
logo_css_style = 'hidden'
1818
end
1919

20-
local is_mobile = ngx.ctx.px_cookie_origin == 'header'
2120
local js_client_src = string.format('//client.perimeterx.net/%s/main.min.js', px_config.px_appId)
2221
local collectorUrl = '//' .. px_config.collector_host
23-
local captcha_url_prefix = 'https://' .. px_config.captcha_script_host
22+
local captcha_url_prefix = '//' .. px_config.captcha_script_host
23+
local first_party_enabled = false
2424
-- in case we are in first party mode (not relevant for mobile), change the base paths to use first party
25-
if px_config.first_party_enabled and not is_mobile then
25+
if px_config.first_party_enabled and not ngx.ctx.px_is_mobile then
2626
local reverse_prefix = string.sub(px_config.px_appId, 3, string.len(px_config.px_appId))
2727
js_client_src = string.format('/%s%s', reverse_prefix, px_constants.FIRST_PARTY_VENDOR_PATH)
2828
collectorUrl = string.format('/%s%s', reverse_prefix, px_constants.FIRST_PARTY_XHR_PATH)
2929
captcha_url_prefix = string.format('/%s%s', reverse_prefix, px_constants.FIRST_PARTY_CAPTCHA_PATH)
30+
first_party_enabled = true
3031
end
3132
local captcha_src = ''
3233
if action ~= 'r' then
@@ -44,7 +45,7 @@ function M.load(px_config)
4445
logoVisibility = logo_css_style,
4546
hostUrl = collectorUrl,
4647
jsClientSrc = js_client_src,
47-
firstPartyEnabled = px_config.first_party_enabled,
48+
firstPartyEnabled = first_party_enabled,
4849
blockScript = captcha_src
4950
}
5051
end
@@ -72,7 +73,7 @@ function M.load(px_config)
7273
end
7374

7475
function _M.get_template(action, uuid, vid)
75-
local props = get_props(px_config, uuid, vid, action)
76+
local props = _M.get_props(px_config, uuid, vid, action)
7677
local templateStr = get_content(action)
7778

7879
return lustache:render(templateStr, props)

lib/px/utils/pxconstants.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
----------------------------------------------
44

55
local _M = {
6-
MODULE_VERSION = "NGINX Module v5.0.1",
6+
MODULE_VERSION = "NGINX Module v5.1.0",
77
RISK_PATH = "/api/v3/risk",
88
CAPTCHA_PATH = "/api/v2/risk/captcha",
99
ACTIVITIES_PATH = "/api/v1/collector/s2s",

lib/px/utils/pxpayload.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ end
4040

4141
function PXPayload:get_payload()
4242
ngx.ctx.px_cookie_origin = "cookie"
43+
ngx.ctx.px_is_mobile = false;
4344
local px_header = self.px_headers.get_header('X-PX-AUTHORIZATION')
4445

4546
if (px_header) then
@@ -48,6 +49,8 @@ function PXPayload:get_payload()
4849
ngx.ctx.px_orig_cookie = cookie
4950
ngx.ctx.px_header = px_header
5051
ngx.ctx.px_cookie_origin = "header"
52+
ngx.ctx.px_is_mobile = true;
53+
5154
if version == "3" then
5255
ngx.ctx.px_cookie_version = "v3";
5356
self.px_logger.debug("Token V3 found - Evaluating")
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package = "perimeterx-nginx-plugin"
2-
version = "5.0-1"
2+
version = "5.1-0"
33
source = {
44
url = "git://github.com/PerimeterX/perimeterx-nginx-plugin.git",
5-
tag = "v5.0.1",
5+
tag = "v5.1.0",
66
}
77
description = {
88
summary = "PerimeterX NGINX Lua Middleware.",

0 commit comments

Comments
 (0)