PerimeterX Express.js Middleware
Latest stable version: v6.5.1
- Installation
- Upgrading
- Configuration
- Required Configuration
- Optional Configuration
- Module Enabled
- Module Mode
- Blocking Score
- Send Page Activities
- Send Block Activities
- Debug Mode
- Sensitive Routes
- Whitelist Specific Routes
- Enforced Specific Routes
- Monitored Specific Routes
- Sensitive Headers
- IP Headers
- First Party Enabled
- Custom Request Handler
- Additional Activity Handler
- Enrich Custom Parameters
- CSS Ref
- JS Ref
- Custom Logo
- Proxy Support
- Filter Traffic by User Agent
- Filter Traffic by IP
- Filter Traffic by HTTP Method
- Test Block Flow on Monitoring Mode
- Advanced Blocking Response
- Multiple App Support
PerimeterX Express.js middleware is installed via NPM:
$ npm install --save perimeterx-node-express
Please note: As stated in NodeJS's release schedule, NodeJS 6.x is reaching EOL. Thus, support for it will be dropped starting with version 5.0.0.
To upgrade to the latest Enforcer version, run:
npm install -s perimeterx-node-express
For more information, contact PerimeterX Support.
To use PerimeterX middleware on a specific route follow this example:
"use strict";
const express = require('express');
const perimeterx = require('perimeterx-node-express');
const server = express();
/* px-module and cookie parser need to be initiated before any route usage */
const pxConfig = {
pxAppId: 'PX_APP_ID',
cookieSecretKey: 'PX_COOKIE_ENCRYPTION_KEY',
authToken: 'PX_TOKEN'
};
perimeterx.init(pxConfig);
/* block users with high bot scores using px-module for the route /helloWorld */
server.get('/helloWorld', perimeterx.middleware, (req, res) => {
res.send('Hello from PX');
});
server.listen(8081, () => {
console.log('server started');
});
-
The PerimeterX Application ID / AppId and PerimeterX Token / Auth Token can be found in the Portal, in Applications.
-
The PerimeterX Cookie Encryption Key can be found in the portal, in Policies.
The Policy from where the Cookie Encryption Key is taken must correspond with the Application from where the Application ID / AppId and PerimeterX Token / Auth Token
Setting the PerimeterX middleware on all server's routes:
When configuring the PerimeterX middleware on all the server's routes, you will have a score evaluation on each incoming request. The recommended pattern is to use on top of page views routes.
"use strict";
const express = require('express');
const perimeterx = require('perimeterx-node-express');
const server = express();
/* the px-module and parser need to be initialized before any route usage */
const pxConfig = {
pxAppId: 'PX_APP_ID',
cookieSecretKey: 'PX_COOKIE_ENCRYPTION_KEY',
authToken: 'PX_TOKEN'
};
perimeterx.init(pxConfig);
/* block high scored users using px-module for all routes */
server.use(perimeterx.middleware);
server.get('/helloWorld', (req, res) => {
res.send('Hello from PX');
});
server.listen(8081, () => {
console.log('server started');
});
To upgrade to the latest Enforcer version, run:
npm install -s perimeterx-node-express
Your Enforcer version is now upgraded to the latest enforcer version.
For more information,contact PerimeterX Support.
In addition to the basic installation configuration above, the following configurations options are available:
A boolean flag to enable/disable the PerimeterX Enforcer.
Default: true
const pxConfig = {
...
moduleEnabled: false
...
};
Sets the working mode of the Enforcer.
Possible values:
0
- Monitor Mode1
- Blocking Mode
Default: 0
- Monitor Mode
const pxConfig = {
...
moduleMode: 1
...
};
Sets the minimum blocking score of a request.
Possible values:
- Any integer between 0 and 100.
Default: 100
const pxConfig = {
...
blockingScore: 100
...
};
A boolean flag to enable/disable sending activities and metrics to PerimeterX with each request.
Enabling this feature allows data to populate the PerimeterX Portal with valuable information, such as the number of requests blocked and additional API usage statistics.
Default: true
const pxConfig = {
...
sendPageActivities: true
...
};
A boolean flag to enable/disable sending block activities to PerimeterX with each request.
Default: true
const pxConfig = {
...
sendBlockActivities: true
...
};
A boolean flag to enable/disable the debug log messages.
Default: false
const pxConfig = {
...
debugMode: true
...
};
An array of route prefixes that trigger a server call to PerimeterX servers every time the page is viewed, regardless of viewing history.
Default: Empty
const pxConfig = {
...
sensitiveRoutes: ['/login', '/user/checkout']
...
};
An array of route prefixes and/or regular expressions that are always whitelisted and not validated by the PerimeterX Worker.
A regular expression can be defined using new RegExp
or directly as an expression, and will be treated as is.
A string value of a path will be treated as a prefix.
Default: Empty
const pxConfig = {
...
whitelistRoutes: ['/contact-us', /\/user\/.*\/show/]
...
};
An array of route prefixes and/or regular expressions that are always validated by the PerimeterX Worker (as opposed to whitelisted routes).
A regular expression can be defined using new RegExp
or directly as an expression, and will be treated as is.
A string value of a path will be treated as a prefix.
Default: Empty
const pxConfig = {
...
enforcedRoutes: ['/home',/^\/$/]
...
};
An array of route prefixes and/or regular expressions that are always set to be in monitor mode. This only takes effect when the module is enabled and in blocking mode.
A regular expression can be defined using new RegExp
or directly as an expression, and will be treated as is.
A string value of a path will be treated as a prefix.
Default: Empty
const pxConfig = {
...
monitoredRoutes: ['/home', new RegExp(/^\/$/)]
...
};
An array of headers that are not sent to PerimeterX servers on API calls.
Default: ['cookie', 'cookies']
const pxConfig = {
...
sensitiveHeaders: ['cookie', 'cookies', 'x-sensitive-header']
...
};
An array of trusted headers that specify an IP to be extracted.
Default: Empty
const pxConfig = {
...
ipHeaders: ['x-user-real-ip']
...
};
A boolean flag to enable/disable first party mode.
Default: true
const pxConfig = {
...
firstPartyEnabled: false
...
};
A JavaScript function that adds a custom response handler to the request.
Default: Empty
const pxConfig = {
...
customRequestHandler: function(pxCtx, pxconfig, req, cb) {
...
cb({body: result, status: 200, statusDescription: "OK", header: {key: 'Content-Type', value:'application/json'}})
}
...
};
A JavaScript function that allows interaction with the request data collected by PerimeterX before the data is returned to the PerimeterX servers. Does not alter the response.
Default: Empty
const pxConfig = {
...
additionalActivityHandler: function(pxCtx, request) {
...
}
...
};
With the enrichCustomParameters
function you can add up to 10 custom parameters to be sent back to PerimeterX servers. When set, the function is called before seting the payload on every request to PerimetrX servers. The parameters should be passed according to the correct order (1-10).
Default: Empty
const pxConfig = {
...
enrichCustomParameters: function(customParams, originalRequest) {
customParams["custom_param1"] = "yay, test value";
return customParams;
}
...
};
Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.
Default: Empty
const pxConfig = {
...
cssRef: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'
...
};
Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.
Default: Empty
const pxConfig = {
...
jsRef: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'
...
};
The logo is displayed at the top of the the block page. Max-height = 150px, Width = auto.
Default: Empty
const pxConfig = {
...
customLogo: 'https://s.perimeterx.net/logo.png',
...
};
Allows traffic to pass through a http proxy server.
Default: Empty
const pxConfig = {
...
proxy: 'https://localhost:8008',
...
};
An array of user agents that are always filtered and not validated by the PerimeterX middleware.
Default: Empty
const pxConfig = {
...
filterByUserAgent: ['testUserAgent/v1.0']
...
};
An array of IP ranges / IP addresses that are always filtered and not validated by the PerimeterX middleware.
Default: Empty
const pxConfig = {
...
filterByIP: ['192.168.10.0/24', '192.168.2.2']
...
};
An array of HTTP methods that are always filtered and not validated by the PerimeterX middleware.
Default: Empty
const pxConfig = {
...
filterByMethod: ['options']
...
};
Allows you to test an enforcer’s blocking flow while you are still in Monitor Mode.
When the header name is set(eg. x-px-block
) and the value is set to 1
, when there is a block response (for example from using a User-Agent header with the value of PhantomJS/1.0
) the Monitor Mode is bypassed and full block mode is applied. If one of the conditions is missing you will stay in Monitor Mode. This is done per request.
To stay in Monitor Mode, set the header value to 0
.
The Header Name is configurable using the BypassMonitorHeader
property.
Default: Empty
const pxConfig = {
...
bypassMonitorHeader: "x-px-block"
...
};
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:
{
"appId": String,
"jsClientSrc": String,
"firstPartyEnabled": Boolean,
"vid": String,
"uuid": String,
"hostUrl": String,
"blockScript": String
}
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.
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.
An example of using the _pxOnCaptchaSuccess
callback is as follows:
window._pxOnCaptchaSuccess = function(isValid) {
if (isValid) {
alert('yay');
} else {
alert('nay');
}
}
For details on how to create a custom Captcha page, refer to the documentation
If you wish to disable this behavior when the Accept header has the value of
application/json
, set the following configuration:const pxConfig = { ... advancedBlockingResponse: false ... };
If you use two different apps on the same node runtime, you can create two instances and use them on two routes:
"use strict";
const express = require('express');
const perimeterx = require('perimeterx-node-express');
const server = express();
/* the px-module and parser need to be initialized before any route usage */
const pxConfig1 = {
pxAppId: 'PX_APP_ID_1',
cookieSecretKey: 'PX_COOKIE_ENCRYPTION_KEY',
authToken: 'PX_TOKEN_1'
};
const middlewareApp1 = perimeterx.new(pxConfig1).middleware;
const app1Router = express.Router();
app1Router.use(middlewareApp1);
app1Router.get('/hello', (req, res) => {
res.send('Hello from App1');
});
server.use('/app1', app1Router);
const pxConfig2 = {
pxAppId: 'PX_APP_ID_2',
cookieSecretKey: 'PX_COOKIE_ENCRYPTION_KEY',
authToken: 'PX_TOKEN_2'
};
const middlewareApp2 = perimeterx.new(pxConfig2).middleware;
const app2Router = express.Router();
app2Router.use(middlewareApp2);
app2Router.get('/app2', (req, res) => {
res.send('Hello from App2');
});
server.use('/app2', app1Router);
server.listen(8081, () => {
console.log('server started');
});