This repository was archived by the owner on Oct 29, 2025. It is now read-only.

Repository files navigation

DEPRECATED

This repository is no longer maintained. Please refer to @humansecurity/node-express-enforcer instead.

Build StatusKnown Vulnerabilities

image

PerimeterX Express.js Middleware

Latest stable version: v7.9.0

Table of Contents

Installation

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.

Upgrading

To upgrade to the latest Enforcer version, run:

npm install -s perimeterx-node-express

For more information, contact PerimeterX Support.

Configuration

Required Configuration

To use PerimeterX middleware on a specific route follow this example:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* px-module and cookie parser need to be initiated before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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');});

Upgrading

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.

Optional Configuration

In addition to the basic installation configuration above, the following configurations options are available:

Module Enabled

A boolean flag to enable/disable the PerimeterX Enforcer.

Default: true

constpxConfig={
...
px_module_enabled: false...};

Module Mode

Sets the working mode of the Enforcer.

Possible values:

  • monitor - Monitor Mode
  • active_blocking - Blocking Mode

Default:monitor

constpxConfig={
...
px_module_mode: "monitor"...};

Blocking Score

Sets the minimum blocking score of a request.

Possible values:

  • Any integer between 0 and 100.

Default: 100

constpxConfig={
...
px_blocking_score: 100...};

Send Page Activities

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

constpxConfig={
...
px_send_async_activities_enabled: true...};

Logger Severity

Sets the logging verbosity level. The available options are:

  • none - no logs will be generated
  • error - logs only when severe errors occur, best for production environments
  • debug - logs more descriptive messages, helpful for analyzing and debugging the enforcer flow

Default: error

constpxConfig={
...
px_logger_severity: 'debug'...};

Sensitive Routes

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

constpxConfig={
...
px_sensitive_routes: ['/login','/user/checkout']...};

Enforced Specific Routes

An array of route prefixes and/or regular expressions that are always validated by the PerimeterX Worker (as opposed to filtered 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

constpxConfig={
...
px_enforced_routes: ['/home',/^\/$/]...};

Monitored Specific Routes

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

constpxConfig={
...
px_monitored_routes: ['/home',newRegExp(/^\/$/)]...};

Filter By Route

An array of route prefixes and/or regular expressions that are always allowed 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

constpxConfig={
...
px_filter_by_route: ['/contact-us',/\/user\/.*\/show/]...};

Sensitive Headers

An array of headers that are not sent to PerimeterX servers on API calls.

Default: ['cookie', 'cookies']

constpxConfig={
...
px_sensitive_headers: ['cookie','cookies','x-sensitive-header']...};

IP Headers

An array of trusted headers that specify an IP to be extracted.

Default: Empty

constpxConfig={
...
px_ip_headers: ['x-user-real-ip']...};

First Party Enabled

A boolean flag to enable/disable first party mode.

Default: true

constpxConfig={
...
px_first_party_enabled: false...};

CD First Party Enabled

A boolean flag to enable/disable Code Defender first party mode.

Default: false

constpxConfig={
...
px_cd_first_party_enabled: false...};

Custom Request Handler

A JavaScript function that adds a custom response handler to the request.

Default: Empty

constpxConfig={
...
px_custom_request_handler: function(pxCtx,pxconfig,req,cb){
...
cb({body: result,status: 200,statusDescription: "OK",header: {key: 'Content-Type',value:'application/json'}})}...};

Additional Activity Handler

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

constpxConfig={
...
px_additional_activity_handler: function(pxCtx,request){
...
}...};

Enrich Custom Parameters

With the px_enrich_custom_parameters 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

constpxConfig={
...
px_enrich_custom_parameters: function(customParams,originalRequest){customParams["custom_param1"]="yay, test value";returncustomParams;}...};

CSS Ref

Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.

Default: Empty

constpxConfig={
...
px_css_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'...};

JS Ref

Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.

Default: Empty

constpxConfig={
...
px_js_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'...};

Custom Logo

The logo is displayed at the top of the the block page. Max-height = 150px, Width = auto.

Default: Empty

constpxConfig={
...
px_custom_logo: 'https://s.perimeterx.net/logo.png',
...
};

Secured PXHD cookie

A boolean flag to enable/disable the Secure flag when baking a PXHD cookie.

Default: false

constpxConfig={
...
px_pxhd_secure: true...};

Proxy Support

Allows traffic to pass through a http proxy server.

Default: Empty

constpxConfig={
...
px_proxy_url: 'https://localhost:8008',
...
};

Custom Cookie Header

When set, instead of extrating the PerimeterX Cookie from the Cookie header, this property specifies a header name that will contain the PerimeterX Cookie.

Default: Empty

constpxConfig={
...
px_custom_cookie_header: "x-px-cookies"...};

Filter Traffic by User Agent

An array of user agent constants and/or regular expressions that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_user_agent: ['testUserAgent/v1.0',/test/]...};

Filter Traffic by IP

An array of IP ranges / IP addresses that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_ip: ['192.168.10.0/24','192.168.2.2']...};

Filter Traffic by HTTP Method

An array of HTTP methods that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_http_method: ['options']...};

Test Block Flow on Monitoring Mode

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 px_bypass_monitor_header property.

Default: Empty

constpxConfig={
...
px_bypass_monitor_header: "x-px-block"...};

CSP Enabled

Used in cdMiddleware - Code Defender's middleware. Enable enforcement of CSP header policy on responses retured to the client (only if active CSP policy exists in PerimeterX for the specific appId).

Default: false

constpxConfig={
...
px_csp_enabled: false...};

CSP Policy Refresh Interval

Used by cdMiddleware - Code Defender's middleware. Sets the interval, in minutes, to fetch and update the active CSP policy for the specific appId from PerimeterX.

Default: 5

constpxConfig={
...
px_csp_policy_refresh_interval_minutes: 5...};

CSP Invalidate Policy Interval

Used by cdMiddleware - Code Defender's middleware. Invalidates active CSP policy after specified number of minutes with no updates received from PerimeterX.

Default: 60

constpxConfig={
...
px_csp_no_updates_max_interval_minutes: 60...};

Login Credentials Extraction

This feature extracts credentials (hashed username and password) from requests and sends them to PerimeterX as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths.

If credentials are found to be compromised, the header px-compromised-credentials will be added to the request with the value 1. You may configure the name of this header with the px_compromised_credentials_header configuration.

Note: This feature requires access to the request body as a either an object or a string type.

Default Values

px_compromised_credentials_header: "px-compromised-credentials"

px_login_credentials_extraction_enabled: false

px_login_credentials_extraction: Empty

constpxConfig={
...
px_compromised_credentials_header: "x-px-comp-creds",px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login pathmethod: "post",// supported values: postsent_through: "body",// supported values: body, header, query-parampass_field: "password",// name of the password field in the requestuser_field: "username"// name of the username field in the request},
...
],
...
};

It is also possible to define a custom callback to extract the username and password. The function should accept the request object as a parameter and return an object with the keys user and pass. If extraction is unsuccessful, the function should return null.

constpxConfig={
...
px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login path, automatically added to sensitive routesmethod: "post",// supported values: postcallback: (req)=>{// custom implementation resulting in variables username and passwordif(username&&password){return{"user": username,"pass": password};}else{returnnull;}}}]};

JWT

Enable the extraction of JWT fields from requests and adding them to the risk, page requested and block activities.

px_jwt_cookie_name

The cookie name that should contain the JWT token.

Default: ""

px_jwt_cookie_user_id_field_name

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted

Default: ""

px_jwt_cookie_additional_field_names

The field names in the JWT object, extracted from the JWT cookie, that should be extracted in addition to the user ID.

Default: []

px_jwt_header_name

The header name that should contain the JWT token.

Default: ""

px_jwt_header_user_id_field_name

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted

Default: ""

px_jwt_header_additional_field_names

The field names in the JWT object, extracted from the JWT header, that should be extracted in addition to the user ID.

Default: []

constpxConfig={
...
"px_jwt_cookie_name": "auth","px_jwt_cookie_user_id_field_name": "nameID","px_jwt_cookie_additional_field_names": ["exp","iss"],"px_jwt_header_name": "authorization","px_jwt_header_user_id_field_name": "sub","px_jwt_header_additional_field_names": ["jti"]...};

Additional S2S Activity

To enhance detection on login credentials extraction endpoints, the following additional information is sent to PerimeterX via an additional_s2s activity:

  • Response Code - The numerical HTTP status code of the response. This is sent automatically.
  • Login Success - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
  • Raw Username - The original username used for the login attempt. In order to report this information, make sure the configuration px_send_raw_username_on_additional_s2s_activity is set to true.

By default, this additional_s2s activity is sent automatically. If it is preferable to send this activity manually, it's possible to disable automatic sending by configuring the value of px_automatic_additional_s2s_activity_enabled to false.

*Default Value: true

constpxConfig={
...
px_automatic_additional_s2s_activity_enabled: false...}

The activity can then be sent manually by invoking the function sendAdditionalS2SActivity(). The function accepts three arguments: the original HTTP request, the status code, and a boolean indicating the login successful status.

constperimeterx=require('perimeterx-node-express');constpxConfig={px_app_id: '<APP_ID>',// ...};pxInstance=perimeterx.new(pxConfig);app.use(pxInstance.middleware);app.post('/login',(req,res)=>{// login flow resulting in boolean isLoginSuccessfulres.status(200).json({successful: isLoginSuccessful});pxInstance.sendAdditionalS2SActivity(req,res.statusCode,isLoginSuccessful);});

Login Success Reporting

There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as false.

Default: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'status'// supported values: status, header, body, custom...}

Status

Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to true. Otherwise, it's set to false.

Note: To define a range of statuses, use the custom reporting method.

Default Values

px_login_successful_status: 200

constpxConfig={
...
px_login_successful_reporting_method: 'status',px_login_successful_status: [200,202]// number or array of numbers...}

Header

Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to true. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to false.

Default Values

px_login_successful_header_name: x-px-login-successful

px_login_successful_header_value: 1

constpxConfig={
...
px_login_successful_reporting_method: 'header',px_login_successful_header_name: 'login-successful',px_login_successful_header_value: 'true'...}

Body

Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set to true. If no match is found, the login successful status is set to false.

Default Values

px_login_successful_body_regex: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'body',px_login_successful_body_regex: 'You logged in successfully!'// string or RegExp...}

Custom

Provide a custom callback that returns a boolean indicating if the login was successful.

Default Values px_login_successful_custom_callback: null

constpxConfig={
...
px_login_successful_reporting_method: 'custom',px_login_successful_custom_callback: (response)=>{returnresponse&&response.locals&&response.locals.isLoginSuccessful;}...}

Raw Username

When enabled, the raw username used for logins on login credentials extraction endpoints will be reported to PerimeterX if (1) the credentials were identified as compromised, and (2) the login was successful as reported via the property above.

Default: false

constpxConfig={
...
px_send_raw_username_on_additional_s2s_activity: true...}

CORS Support

Enable CORS support for the enforcer. This will allow the enforcer to filter out preflight requests and to add CORS headers to block responses. This will ensure responses are not blocked by the browser. CORS support is enabled by default.

px_cors_support_enabled - Enable CORS support for the enforcer.

Default:false

px_cors_custom_preflight_handler - Custom preflight handler. This function will be called for preflight requests and returns response that will return to the client.

// ExampleconstpxConfig={ ...
px_cors_custom_preflight_handler: function(request){constresponse={status: '204',};response.headers={'Access-Control-Allow-Origin': request.headers['origin']||'*','Access-Control-Allow-Methods': request.method,'Access-Control-Allow-Headers': request.headers['access-control-request-headers'],'Access-Control-Allow-Credentials': 'true','Access-Control-Max-Age': '86400',};returnresponse;};}

px_cors_preflight_request_filter_enabled - Filter out preflight requests from validation flow.

Default: false

Enable CORS support for the enforcer:

constpxConfig={
...
px_cors_support_enabled: true,px_cors_preflight_request_filter_enabled: true,
...
};

The default CORS policy when blocking a request is as follows:

Access-Control-Allow-Origin: requestoriginAccess-Control-Allow-Credentials: true

The default CORS policy can be overridden by setting the following properties:

px_cors_create_custom_block_response_headers

Synchronous function supplied by the customer which gets the original request and returns an array of custom headers to be added to the block response. Return type should be an array of objects as follows:

// ExampleconstpxConfig={
...
px_cors_create_custom_block_response_headers: function(request){return{'Access-Control-Allow-Origin': request.headers['origin'],'Access-Control-Allow-Methods': 'GET, POST, OPTIONS','Access-Control-Allow-Headers': 'Content-Type, Authorization','Access-Control-Allow-Credentials': 'true'}};
...
};

Custom Is Sensitive Request

Allows writing your own logic to decide whether the request is sensitive. The custom sensitive request function gets the request object as a parameter and should return true, otherwise, return false. Throwing an exception is equivalent to false.

Default: Empty

constpxConfig={
...
px_custom_is_sensitive_request: function(req){returnreq.method==='POST'&&req.body&&req.body.test;}...

Default:null

Code Defender Middleware - cdMiddleware

Code Defender's middleware to handle the enforcement of CSP headers on responses returned to the client. The express module is in charge of communicating with PerimeterX to receive and maintain the latest CSP policy for the given appId. It also maintains the policy state and invalidates the policy when communication with PerimeterX's Enforcer Data Provider is lost, base on the configuration values (px_csp_no_updates_max_interval_minutes, px_csp_policy_refresh_interval_minutes).

It then uses PerimeterX Node Core module to enforce the actual functionality adding the necessary CSP header to the response object.

usage example:

constperimeterx=require('perimeterx-node-express');
...
constpxInstance=perimeterx.new(pxConfig);app.use(pxInstance.cdMiddleware);
...

Adding Nonce value to CSP header

The PerimeterX Express module allows adding a Nonce value to the CSP header. To do this, use the module's static function addNonce. After PerimeterX cdMiddleware has added the CSP header to the response, call the addNonce function, passing in the response object and a nonce value (string consisting of alphanumeric characters). If a CSP header exists on the response object, the function will alter the header by adding the nonce value in the correct place. The function does not return a value, but rather changes the original response.

constperimeterx=require('perimeterx-node-express');
...
perimeterx.addNonce(response,'rAnd0mNon6e');
...

Please note: the nonce value must be unique for each HTTP response. For further explanation, refer to the official documentation of CSP nonce.

Advanced Blocking Response

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:

constpxConfig={
...
px_advanced_blocking_response_enabled: false...};

Multiple App Support

If you use two different apps on the same node runtime, you can create two instances and use them on two routes:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig1={px_app_id: 'PX_APP_ID_1',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_1',};constmiddlewareApp1=perimeterx.new(pxConfig1).middleware;constapp1Router=express.Router();app1Router.use(middlewareApp1);app1Router.get('/hello',(req,res)=>{res.send('Hello from App1');});server.use('/app1',app1Router);constpxConfig2={px_app_id: 'PX_APP_ID_2',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_2',};constmiddlewareApp2=perimeterx.new(pxConfig2).middleware;constapp2Router=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');});``
## <aname=“additionalInformation”></a>AdditionalInformation
### URIDelimitersPerimeterXprocessesURIpathswithgeneral-andsub-delimitersaccordingtoRFC3986.Generaldelimiters(e.g.,`?`,`#`)areusedtoseparatepartsoftheURI.Sub-delimiters(e.g.,`$`,`&`)arenotusedtosplittheURIastheyareconsideredvalidcharactersintheURIpath.
## Thanks

About

PerimeterX Express.js middleware to monitor and block traffic according to PerimeterX risk score

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Oct 29, 2025. It is now read-only.

Repository files navigation

DEPRECATED

This repository is no longer maintained. Please refer to @humansecurity/node-express-enforcer instead.

Build StatusKnown Vulnerabilities

image

PerimeterX Express.js Middleware

Latest stable version: v7.9.0

Table of Contents

Installation

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.

Upgrading

To upgrade to the latest Enforcer version, run:

npm install -s perimeterx-node-express

For more information, contact PerimeterX Support.

Configuration

Required Configuration

To use PerimeterX middleware on a specific route follow this example:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* px-module and cookie parser need to be initiated before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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');});

Upgrading

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.

Optional Configuration

In addition to the basic installation configuration above, the following configurations options are available:

Module Enabled

A boolean flag to enable/disable the PerimeterX Enforcer.

Default: true

constpxConfig={
...
px_module_enabled: false...};

Module Mode

Sets the working mode of the Enforcer.

Possible values:

  • monitor - Monitor Mode
  • active_blocking - Blocking Mode

Default:monitor

constpxConfig={
...
px_module_mode: "monitor"...};

Blocking Score

Sets the minimum blocking score of a request.

Possible values:

  • Any integer between 0 and 100.

Default: 100

constpxConfig={
...
px_blocking_score: 100...};

Send Page Activities

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

constpxConfig={
...
px_send_async_activities_enabled: true...};

Logger Severity

Sets the logging verbosity level. The available options are:

  • none - no logs will be generated
  • error - logs only when severe errors occur, best for production environments
  • debug - logs more descriptive messages, helpful for analyzing and debugging the enforcer flow

Default: error

constpxConfig={
...
px_logger_severity: 'debug'...};

Sensitive Routes

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

constpxConfig={
...
px_sensitive_routes: ['/login','/user/checkout']...};

Enforced Specific Routes

An array of route prefixes and/or regular expressions that are always validated by the PerimeterX Worker (as opposed to filtered 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

constpxConfig={
...
px_enforced_routes: ['/home',/^\/$/]...};

Monitored Specific Routes

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

constpxConfig={
...
px_monitored_routes: ['/home',newRegExp(/^\/$/)]...};

Filter By Route

An array of route prefixes and/or regular expressions that are always allowed 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

constpxConfig={
...
px_filter_by_route: ['/contact-us',/\/user\/.*\/show/]...};

Sensitive Headers

An array of headers that are not sent to PerimeterX servers on API calls.

Default: ['cookie', 'cookies']

constpxConfig={
...
px_sensitive_headers: ['cookie','cookies','x-sensitive-header']...};

IP Headers

An array of trusted headers that specify an IP to be extracted.

Default: Empty

constpxConfig={
...
px_ip_headers: ['x-user-real-ip']...};

First Party Enabled

A boolean flag to enable/disable first party mode.

Default: true

constpxConfig={
...
px_first_party_enabled: false...};

CD First Party Enabled

A boolean flag to enable/disable Code Defender first party mode.

Default: false

constpxConfig={
...
px_cd_first_party_enabled: false...};

Custom Request Handler

A JavaScript function that adds a custom response handler to the request.

Default: Empty

constpxConfig={
...
px_custom_request_handler: function(pxCtx,pxconfig,req,cb){
...
cb({body: result,status: 200,statusDescription: "OK",header: {key: 'Content-Type',value:'application/json'}})}...};

Additional Activity Handler

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

constpxConfig={
...
px_additional_activity_handler: function(pxCtx,request){
...
}...};

Enrich Custom Parameters

With the px_enrich_custom_parameters 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

constpxConfig={
...
px_enrich_custom_parameters: function(customParams,originalRequest){customParams["custom_param1"]="yay, test value";returncustomParams;}...};

CSS Ref

Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.

Default: Empty

constpxConfig={
...
px_css_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'...};

JS Ref

Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.

Default: Empty

constpxConfig={
...
px_js_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'...};

Custom Logo

The logo is displayed at the top of the the block page. Max-height = 150px, Width = auto.

Default: Empty

constpxConfig={
...
px_custom_logo: 'https://s.perimeterx.net/logo.png',
...
};

Secured PXHD cookie

A boolean flag to enable/disable the Secure flag when baking a PXHD cookie.

Default: false

constpxConfig={
...
px_pxhd_secure: true...};

Proxy Support

Allows traffic to pass through a http proxy server.

Default: Empty

constpxConfig={
...
px_proxy_url: 'https://localhost:8008',
...
};

Custom Cookie Header

When set, instead of extrating the PerimeterX Cookie from the Cookie header, this property specifies a header name that will contain the PerimeterX Cookie.

Default: Empty

constpxConfig={
...
px_custom_cookie_header: "x-px-cookies"...};

Filter Traffic by User Agent

An array of user agent constants and/or regular expressions that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_user_agent: ['testUserAgent/v1.0',/test/]...};

Filter Traffic by IP

An array of IP ranges / IP addresses that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_ip: ['192.168.10.0/24','192.168.2.2']...};

Filter Traffic by HTTP Method

An array of HTTP methods that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_http_method: ['options']...};

Test Block Flow on Monitoring Mode

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 px_bypass_monitor_header property.

Default: Empty

constpxConfig={
...
px_bypass_monitor_header: "x-px-block"...};

CSP Enabled

Used in cdMiddleware - Code Defender's middleware. Enable enforcement of CSP header policy on responses retured to the client (only if active CSP policy exists in PerimeterX for the specific appId).

Default: false

constpxConfig={
...
px_csp_enabled: false...};

CSP Policy Refresh Interval

Used by cdMiddleware - Code Defender's middleware. Sets the interval, in minutes, to fetch and update the active CSP policy for the specific appId from PerimeterX.

Default: 5

constpxConfig={
...
px_csp_policy_refresh_interval_minutes: 5...};

CSP Invalidate Policy Interval

Used by cdMiddleware - Code Defender's middleware. Invalidates active CSP policy after specified number of minutes with no updates received from PerimeterX.

Default: 60

constpxConfig={
...
px_csp_no_updates_max_interval_minutes: 60...};

Login Credentials Extraction

This feature extracts credentials (hashed username and password) from requests and sends them to PerimeterX as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths.

If credentials are found to be compromised, the header px-compromised-credentials will be added to the request with the value 1. You may configure the name of this header with the px_compromised_credentials_header configuration.

Note: This feature requires access to the request body as a either an object or a string type.

Default Values

px_compromised_credentials_header: "px-compromised-credentials"

px_login_credentials_extraction_enabled: false

px_login_credentials_extraction: Empty

constpxConfig={
...
px_compromised_credentials_header: "x-px-comp-creds",px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login pathmethod: "post",// supported values: postsent_through: "body",// supported values: body, header, query-parampass_field: "password",// name of the password field in the requestuser_field: "username"// name of the username field in the request},
...
],
...
};

It is also possible to define a custom callback to extract the username and password. The function should accept the request object as a parameter and return an object with the keys user and pass. If extraction is unsuccessful, the function should return null.

constpxConfig={
...
px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login path, automatically added to sensitive routesmethod: "post",// supported values: postcallback: (req)=>{// custom implementation resulting in variables username and passwordif(username&&password){return{"user": username,"pass": password};}else{returnnull;}}}]};

JWT

Enable the extraction of JWT fields from requests and adding them to the risk, page requested and block activities.

px_jwt_cookie_name

The cookie name that should contain the JWT token.

Default: ""

px_jwt_cookie_user_id_field_name

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted

Default: ""

px_jwt_cookie_additional_field_names

The field names in the JWT object, extracted from the JWT cookie, that should be extracted in addition to the user ID.

Default: []

px_jwt_header_name

The header name that should contain the JWT token.

Default: ""

px_jwt_header_user_id_field_name

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted

Default: ""

px_jwt_header_additional_field_names

The field names in the JWT object, extracted from the JWT header, that should be extracted in addition to the user ID.

Default: []

constpxConfig={
...
"px_jwt_cookie_name": "auth","px_jwt_cookie_user_id_field_name": "nameID","px_jwt_cookie_additional_field_names": ["exp","iss"],"px_jwt_header_name": "authorization","px_jwt_header_user_id_field_name": "sub","px_jwt_header_additional_field_names": ["jti"]...};

Additional S2S Activity

To enhance detection on login credentials extraction endpoints, the following additional information is sent to PerimeterX via an additional_s2s activity:

  • Response Code - The numerical HTTP status code of the response. This is sent automatically.
  • Login Success - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
  • Raw Username - The original username used for the login attempt. In order to report this information, make sure the configuration px_send_raw_username_on_additional_s2s_activity is set to true.

By default, this additional_s2s activity is sent automatically. If it is preferable to send this activity manually, it's possible to disable automatic sending by configuring the value of px_automatic_additional_s2s_activity_enabled to false.

*Default Value: true

constpxConfig={
...
px_automatic_additional_s2s_activity_enabled: false...}

The activity can then be sent manually by invoking the function sendAdditionalS2SActivity(). The function accepts three arguments: the original HTTP request, the status code, and a boolean indicating the login successful status.

constperimeterx=require('perimeterx-node-express');constpxConfig={px_app_id: '<APP_ID>',// ...};pxInstance=perimeterx.new(pxConfig);app.use(pxInstance.middleware);app.post('/login',(req,res)=>{// login flow resulting in boolean isLoginSuccessfulres.status(200).json({successful: isLoginSuccessful});pxInstance.sendAdditionalS2SActivity(req,res.statusCode,isLoginSuccessful);});

Login Success Reporting

There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as false.

Default: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'status'// supported values: status, header, body, custom...}

Status

Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to true. Otherwise, it's set to false.

Note: To define a range of statuses, use the custom reporting method.

Default Values

px_login_successful_status: 200

constpxConfig={
...
px_login_successful_reporting_method: 'status',px_login_successful_status: [200,202]// number or array of numbers...}

Header

Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to true. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to false.

Default Values

px_login_successful_header_name: x-px-login-successful

px_login_successful_header_value: 1

constpxConfig={
...
px_login_successful_reporting_method: 'header',px_login_successful_header_name: 'login-successful',px_login_successful_header_value: 'true'...}

Body

Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set to true. If no match is found, the login successful status is set to false.

Default Values

px_login_successful_body_regex: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'body',px_login_successful_body_regex: 'You logged in successfully!'// string or RegExp...}

Custom

Provide a custom callback that returns a boolean indicating if the login was successful.

Default Values px_login_successful_custom_callback: null

constpxConfig={
...
px_login_successful_reporting_method: 'custom',px_login_successful_custom_callback: (response)=>{returnresponse&&response.locals&&response.locals.isLoginSuccessful;}...}

Raw Username

When enabled, the raw username used for logins on login credentials extraction endpoints will be reported to PerimeterX if (1) the credentials were identified as compromised, and (2) the login was successful as reported via the property above.

Default: false

constpxConfig={
...
px_send_raw_username_on_additional_s2s_activity: true...}

CORS Support

Enable CORS support for the enforcer. This will allow the enforcer to filter out preflight requests and to add CORS headers to block responses. This will ensure responses are not blocked by the browser. CORS support is enabled by default.

px_cors_support_enabled - Enable CORS support for the enforcer.

Default:false

px_cors_custom_preflight_handler - Custom preflight handler. This function will be called for preflight requests and returns response that will return to the client.

// ExampleconstpxConfig={ ...
px_cors_custom_preflight_handler: function(request){constresponse={status: '204',};response.headers={'Access-Control-Allow-Origin': request.headers['origin']||'*','Access-Control-Allow-Methods': request.method,'Access-Control-Allow-Headers': request.headers['access-control-request-headers'],'Access-Control-Allow-Credentials': 'true','Access-Control-Max-Age': '86400',};returnresponse;};}

px_cors_preflight_request_filter_enabled - Filter out preflight requests from validation flow.

Default: false

Enable CORS support for the enforcer:

constpxConfig={
...
px_cors_support_enabled: true,px_cors_preflight_request_filter_enabled: true,
...
};

The default CORS policy when blocking a request is as follows:

Access-Control-Allow-Origin: requestoriginAccess-Control-Allow-Credentials: true

The default CORS policy can be overridden by setting the following properties:

px_cors_create_custom_block_response_headers

Synchronous function supplied by the customer which gets the original request and returns an array of custom headers to be added to the block response. Return type should be an array of objects as follows:

// ExampleconstpxConfig={
...
px_cors_create_custom_block_response_headers: function(request){return{'Access-Control-Allow-Origin': request.headers['origin'],'Access-Control-Allow-Methods': 'GET, POST, OPTIONS','Access-Control-Allow-Headers': 'Content-Type, Authorization','Access-Control-Allow-Credentials': 'true'}};
...
};

Custom Is Sensitive Request

Allows writing your own logic to decide whether the request is sensitive. The custom sensitive request function gets the request object as a parameter and should return true, otherwise, return false. Throwing an exception is equivalent to false.

Default: Empty

constpxConfig={
...
px_custom_is_sensitive_request: function(req){returnreq.method==='POST'&&req.body&&req.body.test;}...

Default:null

Code Defender Middleware - cdMiddleware

Code Defender's middleware to handle the enforcement of CSP headers on responses returned to the client. The express module is in charge of communicating with PerimeterX to receive and maintain the latest CSP policy for the given appId. It also maintains the policy state and invalidates the policy when communication with PerimeterX's Enforcer Data Provider is lost, base on the configuration values (px_csp_no_updates_max_interval_minutes, px_csp_policy_refresh_interval_minutes).

It then uses PerimeterX Node Core module to enforce the actual functionality adding the necessary CSP header to the response object.

usage example:

constperimeterx=require('perimeterx-node-express');
...
constpxInstance=perimeterx.new(pxConfig);app.use(pxInstance.cdMiddleware);
...

Adding Nonce value to CSP header

The PerimeterX Express module allows adding a Nonce value to the CSP header. To do this, use the module's static function addNonce. After PerimeterX cdMiddleware has added the CSP header to the response, call the addNonce function, passing in the response object and a nonce value (string consisting of alphanumeric characters). If a CSP header exists on the response object, the function will alter the header by adding the nonce value in the correct place. The function does not return a value, but rather changes the original response.

constperimeterx=require('perimeterx-node-express');
...
perimeterx.addNonce(response,'rAnd0mNon6e');
...

Please note: the nonce value must be unique for each HTTP response. For further explanation, refer to the official documentation of CSP nonce.

Advanced Blocking Response

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:

constpxConfig={
...
px_advanced_blocking_response_enabled: false...};

Multiple App Support

If you use two different apps on the same node runtime, you can create two instances and use them on two routes:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig1={px_app_id: 'PX_APP_ID_1',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_1',};constmiddlewareApp1=perimeterx.new(pxConfig1).middleware;constapp1Router=express.Router();app1Router.use(middlewareApp1);app1Router.get('/hello',(req,res)=>{res.send('Hello from App1');});server.use('/app1',app1Router);constpxConfig2={px_app_id: 'PX_APP_ID_2',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_2',};constmiddlewareApp2=perimeterx.new(pxConfig2).middleware;constapp2Router=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');});``
## <aname=“additionalInformation”></a>AdditionalInformation
### URIDelimitersPerimeterXprocessesURIpathswithgeneral-andsub-delimitersaccordingtoRFC3986.Generaldelimiters(e.g.,`?`,`#`)areusedtoseparatepartsoftheURI.Sub-delimiters(e.g.,`$`,`&`)arenotusedtosplittheURIastheyareconsideredvalidcharactersintheURIpath.
## Thanks

About

PerimeterX Express.js middleware to monitor and block traffic according to PerimeterX risk score

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Oct 29, 2025. It is now read-only.

Repository files navigation

DEPRECATED

This repository is no longer maintained. Please refer to @humansecurity/node-express-enforcer instead.

Build StatusKnown Vulnerabilities

image

PerimeterX Express.js Middleware

Latest stable version: v7.9.0

Table of Contents

Installation

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.

Upgrading

To upgrade to the latest Enforcer version, run:

npm install -s perimeterx-node-express

For more information, contact PerimeterX Support.

Configuration

Required Configuration

To use PerimeterX middleware on a specific route follow this example:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* px-module and cookie parser need to be initiated before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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');});

Upgrading

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.

Optional Configuration

In addition to the basic installation configuration above, the following configurations options are available:

Module Enabled

A boolean flag to enable/disable the PerimeterX Enforcer.

Default: true

constpxConfig={
...
px_module_enabled: false...};

Module Mode

Sets the working mode of the Enforcer.

Possible values:

  • monitor - Monitor Mode
  • active_blocking - Blocking Mode

Default:monitor

constpxConfig={
...
px_module_mode: "monitor"...};

Blocking Score

Sets the minimum blocking score of a request.

Possible values:

  • Any integer between 0 and 100.

Default: 100

constpxConfig={
...
px_blocking_score: 100...};

Send Page Activities

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

constpxConfig={
...
px_send_async_activities_enabled: true...};

Logger Severity

Sets the logging verbosity level. The available options are:

  • none - no logs will be generated
  • error - logs only when severe errors occur, best for production environments
  • debug - logs more descriptive messages, helpful for analyzing and debugging the enforcer flow

Default: error

constpxConfig={
...
px_logger_severity: 'debug'...};

Sensitive Routes

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

constpxConfig={
...
px_sensitive_routes: ['/login','/user/checkout']...};

Enforced Specific Routes

An array of route prefixes and/or regular expressions that are always validated by the PerimeterX Worker (as opposed to filtered 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

constpxConfig={
...
px_enforced_routes: ['/home',/^\/$/]...};

Monitored Specific Routes

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

constpxConfig={
...
px_monitored_routes: ['/home',newRegExp(/^\/$/)]...};

Filter By Route

An array of route prefixes and/or regular expressions that are always allowed 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

constpxConfig={
...
px_filter_by_route: ['/contact-us',/\/user\/.*\/show/]...};

Sensitive Headers

An array of headers that are not sent to PerimeterX servers on API calls.

Default: ['cookie', 'cookies']

constpxConfig={
...
px_sensitive_headers: ['cookie','cookies','x-sensitive-header']...};

IP Headers

An array of trusted headers that specify an IP to be extracted.

Default: Empty

constpxConfig={
...
px_ip_headers: ['x-user-real-ip']...};

First Party Enabled

A boolean flag to enable/disable first party mode.

Default: true

constpxConfig={
...
px_first_party_enabled: false...};

CD First Party Enabled

A boolean flag to enable/disable Code Defender first party mode.

Default: false

constpxConfig={
...
px_cd_first_party_enabled: false...};

Custom Request Handler

A JavaScript function that adds a custom response handler to the request.

Default: Empty

constpxConfig={
...
px_custom_request_handler: function(pxCtx,pxconfig,req,cb){
...
cb({body: result,status: 200,statusDescription: "OK",header: {key: 'Content-Type',value:'application/json'}})}...};

Additional Activity Handler

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

constpxConfig={
...
px_additional_activity_handler: function(pxCtx,request){
...
}...};

Enrich Custom Parameters

With the px_enrich_custom_parameters 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

constpxConfig={
...
px_enrich_custom_parameters: function(customParams,originalRequest){customParams["custom_param1"]="yay, test value";returncustomParams;}...};

CSS Ref

Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.

Default: Empty

constpxConfig={
...
px_css_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'...};

JS Ref

Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.

Default: Empty

constpxConfig={
...
px_js_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'...};

Custom Logo

The logo is displayed at the top of the the block page. Max-height = 150px, Width = auto.

Default: Empty

constpxConfig={
...
px_custom_logo: 'https://s.perimeterx.net/logo.png',
...
};

Secured PXHD cookie

A boolean flag to enable/disable the Secure flag when baking a PXHD cookie.

Default: false

constpxConfig={
...
px_pxhd_secure: true...};

Proxy Support

Allows traffic to pass through a http proxy server.

Default: Empty

constpxConfig={
...
px_proxy_url: 'https://localhost:8008',
...
};

Custom Cookie Header

When set, instead of extrating the PerimeterX Cookie from the Cookie header, this property specifies a header name that will contain the PerimeterX Cookie.

Default: Empty

constpxConfig={
...
px_custom_cookie_header: "x-px-cookies"...};

Filter Traffic by User Agent

An array of user agent constants and/or regular expressions that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_user_agent: ['testUserAgent/v1.0',/test/]...};

Filter Traffic by IP

An array of IP ranges / IP addresses that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_ip: ['192.168.10.0/24','192.168.2.2']...};

Filter Traffic by HTTP Method

An array of HTTP methods that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_http_method: ['options']...};

Test Block Flow on Monitoring Mode

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 px_bypass_monitor_header property.

Default: Empty

constpxConfig={
...
px_bypass_monitor_header: "x-px-block"...};

CSP Enabled

Used in cdMiddleware - Code Defender's middleware. Enable enforcement of CSP header policy on responses retured to the client (only if active CSP policy exists in PerimeterX for the specific appId).

Default: false

constpxConfig={
...
px_csp_enabled: false...};

CSP Policy Refresh Interval

Used by cdMiddleware - Code Defender's middleware. Sets the interval, in minutes, to fetch and update the active CSP policy for the specific appId from PerimeterX.

Default: 5

constpxConfig={
...
px_csp_policy_refresh_interval_minutes: 5...};

CSP Invalidate Policy Interval

Used by cdMiddleware - Code Defender's middleware. Invalidates active CSP policy after specified number of minutes with no updates received from PerimeterX.

Default: 60

constpxConfig={
...
px_csp_no_updates_max_interval_minutes: 60...};

Login Credentials Extraction

This feature extracts credentials (hashed username and password) from requests and sends them to PerimeterX as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths.

If credentials are found to be compromised, the header px-compromised-credentials will be added to the request with the value 1. You may configure the name of this header with the px_compromised_credentials_header configuration.

Note: This feature requires access to the request body as a either an object or a string type.

Default Values

px_compromised_credentials_header: "px-compromised-credentials"

px_login_credentials_extraction_enabled: false

px_login_credentials_extraction: Empty

constpxConfig={
...
px_compromised_credentials_header: "x-px-comp-creds",px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login pathmethod: "post",// supported values: postsent_through: "body",// supported values: body, header, query-parampass_field: "password",// name of the password field in the requestuser_field: "username"// name of the username field in the request},
...
],
...
};

It is also possible to define a custom callback to extract the username and password. The function should accept the request object as a parameter and return an object with the keys user and pass. If extraction is unsuccessful, the function should return null.

constpxConfig={
...
px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login path, automatically added to sensitive routesmethod: "post",// supported values: postcallback: (req)=>{// custom implementation resulting in variables username and passwordif(username&&password){return{"user": username,"pass": password};}else{returnnull;}}}]};

JWT

Enable the extraction of JWT fields from requests and adding them to the risk, page requested and block activities.

px_jwt_cookie_name

The cookie name that should contain the JWT token.

Default: ""

px_jwt_cookie_user_id_field_name

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted

Default: ""

px_jwt_cookie_additional_field_names

The field names in the JWT object, extracted from the JWT cookie, that should be extracted in addition to the user ID.

Default: []

px_jwt_header_name

The header name that should contain the JWT token.

Default: ""

px_jwt_header_user_id_field_name

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted

Default: ""

px_jwt_header_additional_field_names

The field names in the JWT object, extracted from the JWT header, that should be extracted in addition to the user ID.

Default: []

constpxConfig={
...
"px_jwt_cookie_name": "auth","px_jwt_cookie_user_id_field_name": "nameID","px_jwt_cookie_additional_field_names": ["exp","iss"],"px_jwt_header_name": "authorization","px_jwt_header_user_id_field_name": "sub","px_jwt_header_additional_field_names": ["jti"]...};

Additional S2S Activity

To enhance detection on login credentials extraction endpoints, the following additional information is sent to PerimeterX via an additional_s2s activity:

  • Response Code - The numerical HTTP status code of the response. This is sent automatically.
  • Login Success - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
  • Raw Username - The original username used for the login attempt. In order to report this information, make sure the configuration px_send_raw_username_on_additional_s2s_activity is set to true.

By default, this additional_s2s activity is sent automatically. If it is preferable to send this activity manually, it's possible to disable automatic sending by configuring the value of px_automatic_additional_s2s_activity_enabled to false.

*Default Value: true

constpxConfig={
...
px_automatic_additional_s2s_activity_enabled: false...}

The activity can then be sent manually by invoking the function sendAdditionalS2SActivity(). The function accepts three arguments: the original HTTP request, the status code, and a boolean indicating the login successful status.

constperimeterx=require('perimeterx-node-express');constpxConfig={px_app_id: '<APP_ID>',// ...};pxInstance=perimeterx.new(pxConfig);app.use(pxInstance.middleware);app.post('/login',(req,res)=>{// login flow resulting in boolean isLoginSuccessfulres.status(200).json({successful: isLoginSuccessful});pxInstance.sendAdditionalS2SActivity(req,res.statusCode,isLoginSuccessful);});

Login Success Reporting

There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as false.

Default: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'status'// supported values: status, header, body, custom...}

Status

Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to true. Otherwise, it's set to false.

Note: To define a range of statuses, use the custom reporting method.

Default Values

px_login_successful_status: 200

constpxConfig={
...
px_login_successful_reporting_method: 'status',px_login_successful_status: [200,202]// number or array of numbers...}

Header

Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to true. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to false.

Default Values

px_login_successful_header_name: x-px-login-successful

px_login_successful_header_value: 1

constpxConfig={
...
px_login_successful_reporting_method: 'header',px_login_successful_header_name: 'login-successful',px_login_successful_header_value: 'true'...}

Body

Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set to true. If no match is found, the login successful status is set to false.

Default Values

px_login_successful_body_regex: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'body',px_login_successful_body_regex: 'You logged in successfully!'// string or RegExp...}

Custom

Provide a custom callback that returns a boolean indicating if the login was successful.

Default Values px_login_successful_custom_callback: null

constpxConfig={
...
px_login_successful_reporting_method: 'custom',px_login_successful_custom_callback: (response)=>{returnresponse&&response.locals&&response.locals.isLoginSuccessful;}...}

Raw Username

When enabled, the raw username used for logins on login credentials extraction endpoints will be reported to PerimeterX if (1) the credentials were identified as compromised, and (2) the login was successful as reported via the property above.

Default: false

constpxConfig={
...
px_send_raw_username_on_additional_s2s_activity: true...}

CORS Support

Enable CORS support for the enforcer. This will allow the enforcer to filter out preflight requests and to add CORS headers to block responses. This will ensure responses are not blocked by the browser. CORS support is enabled by default.

px_cors_support_enabled - Enable CORS support for the enforcer.

Default:false

px_cors_custom_preflight_handler - Custom preflight handler. This function will be called for preflight requests and returns response that will return to the client.

// ExampleconstpxConfig={ ...
px_cors_custom_preflight_handler: function(request){constresponse={status: '204',};response.headers={'Access-Control-Allow-Origin': request.headers['origin']||'*','Access-Control-Allow-Methods': request.method,'Access-Control-Allow-Headers': request.headers['access-control-request-headers'],'Access-Control-Allow-Credentials': 'true','Access-Control-Max-Age': '86400',};returnresponse;};}

px_cors_preflight_request_filter_enabled - Filter out preflight requests from validation flow.

Default: false

Enable CORS support for the enforcer:

constpxConfig={
...
px_cors_support_enabled: true,px_cors_preflight_request_filter_enabled: true,
...
};

The default CORS policy when blocking a request is as follows:

Access-Control-Allow-Origin: requestoriginAccess-Control-Allow-Credentials: true

The default CORS policy can be overridden by setting the following properties:

px_cors_create_custom_block_response_headers

Synchronous function supplied by the customer which gets the original request and returns an array of custom headers to be added to the block response. Return type should be an array of objects as follows:

// ExampleconstpxConfig={
...
px_cors_create_custom_block_response_headers: function(request){return{'Access-Control-Allow-Origin': request.headers['origin'],'Access-Control-Allow-Methods': 'GET, POST, OPTIONS','Access-Control-Allow-Headers': 'Content-Type, Authorization','Access-Control-Allow-Credentials': 'true'}};
...
};

Custom Is Sensitive Request

Allows writing your own logic to decide whether the request is sensitive. The custom sensitive request function gets the request object as a parameter and should return true, otherwise, return false. Throwing an exception is equivalent to false.

Default: Empty

constpxConfig={
...
px_custom_is_sensitive_request: function(req){returnreq.method==='POST'&&req.body&&req.body.test;}...

Default:null

Code Defender Middleware - cdMiddleware

Code Defender's middleware to handle the enforcement of CSP headers on responses returned to the client. The express module is in charge of communicating with PerimeterX to receive and maintain the latest CSP policy for the given appId. It also maintains the policy state and invalidates the policy when communication with PerimeterX's Enforcer Data Provider is lost, base on the configuration values (px_csp_no_updates_max_interval_minutes, px_csp_policy_refresh_interval_minutes).

It then uses PerimeterX Node Core module to enforce the actual functionality adding the necessary CSP header to the response object.

usage example:

constperimeterx=require('perimeterx-node-express');
...
constpxInstance=perimeterx.new(pxConfig);app.use(pxInstance.cdMiddleware);
...

Adding Nonce value to CSP header

The PerimeterX Express module allows adding a Nonce value to the CSP header. To do this, use the module's static function addNonce. After PerimeterX cdMiddleware has added the CSP header to the response, call the addNonce function, passing in the response object and a nonce value (string consisting of alphanumeric characters). If a CSP header exists on the response object, the function will alter the header by adding the nonce value in the correct place. The function does not return a value, but rather changes the original response.

constperimeterx=require('perimeterx-node-express');
...
perimeterx.addNonce(response,'rAnd0mNon6e');
...

Please note: the nonce value must be unique for each HTTP response. For further explanation, refer to the official documentation of CSP nonce.

Advanced Blocking Response

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:

constpxConfig={
...
px_advanced_blocking_response_enabled: false...};

Multiple App Support

If you use two different apps on the same node runtime, you can create two instances and use them on two routes:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig1={px_app_id: 'PX_APP_ID_1',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_1',};constmiddlewareApp1=perimeterx.new(pxConfig1).middleware;constapp1Router=express.Router();app1Router.use(middlewareApp1);app1Router.get('/hello',(req,res)=>{res.send('Hello from App1');});server.use('/app1',app1Router);constpxConfig2={px_app_id: 'PX_APP_ID_2',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_2',};constmiddlewareApp2=perimeterx.new(pxConfig2).middleware;constapp2Router=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');});``
## <aname=“additionalInformation”></a>AdditionalInformation
### URIDelimitersPerimeterXprocessesURIpathswithgeneral-andsub-delimitersaccordingtoRFC3986.Generaldelimiters(e.g.,`?`,`#`)areusedtoseparatepartsoftheURI.Sub-delimiters(e.g.,`$`,`&`)arenotusedtosplittheURIastheyareconsideredvalidcharactersintheURIpath.
## Thanks

About

PerimeterX Express.js middleware to monitor and block traffic according to PerimeterX risk score

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Oct 29, 2025. It is now read-only.

Repository files navigation

DEPRECATED

This repository is no longer maintained. Please refer to @humansecurity/node-express-enforcer instead.

Build StatusKnown Vulnerabilities

image

PerimeterX Express.js Middleware

Latest stable version: v7.9.0

Table of Contents

Installation

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.

Upgrading

To upgrade to the latest Enforcer version, run:

npm install -s perimeterx-node-express

For more information, contact PerimeterX Support.

Configuration

Required Configuration

To use PerimeterX middleware on a specific route follow this example:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* px-module and cookie parser need to be initiated before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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');});

Upgrading

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.

Optional Configuration

In addition to the basic installation configuration above, the following configurations options are available:

Module Enabled

A boolean flag to enable/disable the PerimeterX Enforcer.

Default: true

constpxConfig={
...
px_module_enabled: false...};

Module Mode

Sets the working mode of the Enforcer.

Possible values:

  • monitor - Monitor Mode
  • active_blocking - Blocking Mode

Default:monitor

constpxConfig={
...
px_module_mode: "monitor"...};

Blocking Score

Sets the minimum blocking score of a request.

Possible values:

  • Any integer between 0 and 100.

Default: 100

constpxConfig={
...
px_blocking_score: 100...};

Send Page Activities

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

constpxConfig={
...
px_send_async_activities_enabled: true...};

Logger Severity

Sets the logging verbosity level. The available options are:

  • none - no logs will be generated
  • error - logs only when severe errors occur, best for production environments
  • debug - logs more descriptive messages, helpful for analyzing and debugging the enforcer flow

Default: error

constpxConfig={
...
px_logger_severity: 'debug'...};

Sensitive Routes

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

constpxConfig={
...
px_sensitive_routes: ['/login','/user/checkout']...};

Enforced Specific Routes

An array of route prefixes and/or regular expressions that are always validated by the PerimeterX Worker (as opposed to filtered 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

constpxConfig={
...
px_enforced_routes: ['/home',/^\/$/]...};

Monitored Specific Routes

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

constpxConfig={
...
px_monitored_routes: ['/home',newRegExp(/^\/$/)]...};

Filter By Route

An array of route prefixes and/or regular expressions that are always allowed 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

constpxConfig={
...
px_filter_by_route: ['/contact-us',/\/user\/.*\/show/]...};

Sensitive Headers

An array of headers that are not sent to PerimeterX servers on API calls.

Default: ['cookie', 'cookies']

constpxConfig={
...
px_sensitive_headers: ['cookie','cookies','x-sensitive-header']...};

IP Headers

An array of trusted headers that specify an IP to be extracted.

Default: Empty

constpxConfig={
...
px_ip_headers: ['x-user-real-ip']...};

First Party Enabled

A boolean flag to enable/disable first party mode.

Default: true

constpxConfig={
...
px_first_party_enabled: false...};

CD First Party Enabled

A boolean flag to enable/disable Code Defender first party mode.

Default: false

constpxConfig={
...
px_cd_first_party_enabled: false...};

Custom Request Handler

A JavaScript function that adds a custom response handler to the request.

Default: Empty

constpxConfig={
...
px_custom_request_handler: function(pxCtx,pxconfig,req,cb){
...
cb({body: result,status: 200,statusDescription: "OK",header: {key: 'Content-Type',value:'application/json'}})}...};

Additional Activity Handler

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

constpxConfig={
...
px_additional_activity_handler: function(pxCtx,request){
...
}...};

Enrich Custom Parameters

With the px_enrich_custom_parameters 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

constpxConfig={
...
px_enrich_custom_parameters: function(customParams,originalRequest){customParams["custom_param1"]="yay, test value";returncustomParams;}...};

CSS Ref

Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.

Default: Empty

constpxConfig={
...
px_css_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'...};

JS Ref

Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.

Default: Empty

constpxConfig={
...
px_js_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'...};

Custom Logo

The logo is displayed at the top of the the block page. Max-height = 150px, Width = auto.

Default: Empty

constpxConfig={
...
px_custom_logo: 'https://s.perimeterx.net/logo.png',
...
};

Secured PXHD cookie

A boolean flag to enable/disable the Secure flag when baking a PXHD cookie.

Default: false

constpxConfig={
...
px_pxhd_secure: true...};

Proxy Support

Allows traffic to pass through a http proxy server.

Default: Empty

constpxConfig={
...
px_proxy_url: 'https://localhost:8008',
...
};

Custom Cookie Header

When set, instead of extrating the PerimeterX Cookie from the Cookie header, this property specifies a header name that will contain the PerimeterX Cookie.

Default: Empty

constpxConfig={
...
px_custom_cookie_header: "x-px-cookies"...};

Filter Traffic by User Agent

An array of user agent constants and/or regular expressions that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_user_agent: ['testUserAgent/v1.0',/test/]...};

Filter Traffic by IP

An array of IP ranges / IP addresses that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_ip: ['192.168.10.0/24','192.168.2.2']...};

Filter Traffic by HTTP Method

An array of HTTP methods that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_http_method: ['options']...};

Test Block Flow on Monitoring Mode

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 px_bypass_monitor_header property.

Default: Empty

constpxConfig={
...
px_bypass_monitor_header: "x-px-block"...};

CSP Enabled

Used in cdMiddleware - Code Defender's middleware. Enable enforcement of CSP header policy on responses retured to the client (only if active CSP policy exists in PerimeterX for the specific appId).

Default: false

constpxConfig={
...
px_csp_enabled: false...};

CSP Policy Refresh Interval

Used by cdMiddleware - Code Defender's middleware. Sets the interval, in minutes, to fetch and update the active CSP policy for the specific appId from PerimeterX.

Default: 5

constpxConfig={
...
px_csp_policy_refresh_interval_minutes: 5...};

CSP Invalidate Policy Interval

Used by cdMiddleware - Code Defender's middleware. Invalidates active CSP policy after specified number of minutes with no updates received from PerimeterX.

Default: 60

constpxConfig={
...
px_csp_no_updates_max_interval_minutes: 60...};

Login Credentials Extraction

This feature extracts credentials (hashed username and password) from requests and sends them to PerimeterX as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths.

If credentials are found to be compromised, the header px-compromised-credentials will be added to the request with the value 1. You may configure the name of this header with the px_compromised_credentials_header configuration.

Note: This feature requires access to the request body as a either an object or a string type.

Default Values

px_compromised_credentials_header: "px-compromised-credentials"

px_login_credentials_extraction_enabled: false

px_login_credentials_extraction: Empty

constpxConfig={
...
px_compromised_credentials_header: "x-px-comp-creds",px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login pathmethod: "post",// supported values: postsent_through: "body",// supported values: body, header, query-parampass_field: "password",// name of the password field in the requestuser_field: "username"// name of the username field in the request},
...
],
...
};

It is also possible to define a custom callback to extract the username and password. The function should accept the request object as a parameter and return an object with the keys user and pass. If extraction is unsuccessful, the function should return null.

constpxConfig={
...
px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login path, automatically added to sensitive routesmethod: "post",// supported values: postcallback: (req)=>{// custom implementation resulting in variables username and passwordif(username&&password){return{"user": username,"pass": password};}else{returnnull;}}}]};

JWT

Enable the extraction of JWT fields from requests and adding them to the risk, page requested and block activities.

px_jwt_cookie_name

The cookie name that should contain the JWT token.

Default: ""

px_jwt_cookie_user_id_field_name

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted

Default: ""

px_jwt_cookie_additional_field_names

The field names in the JWT object, extracted from the JWT cookie, that should be extracted in addition to the user ID.

Default: []

px_jwt_header_name

The header name that should contain the JWT token.

Default: ""

px_jwt_header_user_id_field_name

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted

Default: ""

px_jwt_header_additional_field_names

The field names in the JWT object, extracted from the JWT header, that should be extracted in addition to the user ID.

Default: []

constpxConfig={
...
"px_jwt_cookie_name": "auth","px_jwt_cookie_user_id_field_name": "nameID","px_jwt_cookie_additional_field_names": ["exp","iss"],"px_jwt_header_name": "authorization","px_jwt_header_user_id_field_name": "sub","px_jwt_header_additional_field_names": ["jti"]...};

Additional S2S Activity

To enhance detection on login credentials extraction endpoints, the following additional information is sent to PerimeterX via an additional_s2s activity:

  • Response Code - The numerical HTTP status code of the response. This is sent automatically.
  • Login Success - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
  • Raw Username - The original username used for the login attempt. In order to report this information, make sure the configuration px_send_raw_username_on_additional_s2s_activity is set to true.

By default, this additional_s2s activity is sent automatically. If it is preferable to send this activity manually, it's possible to disable automatic sending by configuring the value of px_automatic_additional_s2s_activity_enabled to false.

*Default Value: true

constpxConfig={
...
px_automatic_additional_s2s_activity_enabled: false...}

The activity can then be sent manually by invoking the function sendAdditionalS2SActivity(). The function accepts three arguments: the original HTTP request, the status code, and a boolean indicating the login successful status.

constperimeterx=require('perimeterx-node-express');constpxConfig={px_app_id: '<APP_ID>',// ...};pxInstance=perimeterx.new(pxConfig);app.use(pxInstance.middleware);app.post('/login',(req,res)=>{// login flow resulting in boolean isLoginSuccessfulres.status(200).json({successful: isLoginSuccessful});pxInstance.sendAdditionalS2SActivity(req,res.statusCode,isLoginSuccessful);});

Login Success Reporting

There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as false.

Default: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'status'// supported values: status, header, body, custom...}

Status

Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to true. Otherwise, it's set to false.

Note: To define a range of statuses, use the custom reporting method.

Default Values

px_login_successful_status: 200

constpxConfig={
...
px_login_successful_reporting_method: 'status',px_login_successful_status: [200,202]// number or array of numbers...}

Header

Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to true. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to false.

Default Values

px_login_successful_header_name: x-px-login-successful

px_login_successful_header_value: 1

constpxConfig={
...
px_login_successful_reporting_method: 'header',px_login_successful_header_name: 'login-successful',px_login_successful_header_value: 'true'...}

Body

Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set to true. If no match is found, the login successful status is set to false.

Default Values

px_login_successful_body_regex: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'body',px_login_successful_body_regex: 'You logged in successfully!'// string or RegExp...}

Custom

Provide a custom callback that returns a boolean indicating if the login was successful.

Default Values px_login_successful_custom_callback: null

constpxConfig={
...
px_login_successful_reporting_method: 'custom',px_login_successful_custom_callback: (response)=>{returnresponse&&response.locals&&response.locals.isLoginSuccessful;}...}

Raw Username

When enabled, the raw username used for logins on login credentials extraction endpoints will be reported to PerimeterX if (1) the credentials were identified as compromised, and (2) the login was successful as reported via the property above.

Default: false

constpxConfig={
...
px_send_raw_username_on_additional_s2s_activity: true...}

CORS Support

Enable CORS support for the enforcer. This will allow the enforcer to filter out preflight requests and to add CORS headers to block responses. This will ensure responses are not blocked by the browser. CORS support is enabled by default.

px_cors_support_enabled - Enable CORS support for the enforcer.

Default:false

px_cors_custom_preflight_handler - Custom preflight handler. This function will be called for preflight requests and returns response that will return to the client.

// ExampleconstpxConfig={ ...
px_cors_custom_preflight_handler: function(request){constresponse={status: '204',};response.headers={'Access-Control-Allow-Origin': request.headers['origin']||'*','Access-Control-Allow-Methods': request.method,'Access-Control-Allow-Headers': request.headers['access-control-request-headers'],'Access-Control-Allow-Credentials': 'true','Access-Control-Max-Age': '86400',};returnresponse;};}

px_cors_preflight_request_filter_enabled - Filter out preflight requests from validation flow.

Default: false

Enable CORS support for the enforcer:

constpxConfig={
...
px_cors_support_enabled: true,px_cors_preflight_request_filter_enabled: true,
...
};

The default CORS policy when blocking a request is as follows:

Access-Control-Allow-Origin: requestoriginAccess-Control-Allow-Credentials: true

The default CORS policy can be overridden by setting the following properties:

px_cors_create_custom_block_response_headers

Synchronous function supplied by the customer which gets the original request and returns an array of custom headers to be added to the block response. Return type should be an array of objects as follows:

// ExampleconstpxConfig={
...
px_cors_create_custom_block_response_headers: function(request){return{'Access-Control-Allow-Origin': request.headers['origin'],'Access-Control-Allow-Methods': 'GET, POST, OPTIONS','Access-Control-Allow-Headers': 'Content-Type, Authorization','Access-Control-Allow-Credentials': 'true'}};
...
};

Custom Is Sensitive Request

Allows writing your own logic to decide whether the request is sensitive. The custom sensitive request function gets the request object as a parameter and should return true, otherwise, return false. Throwing an exception is equivalent to false.

Default: Empty

constpxConfig={
...
px_custom_is_sensitive_request: function(req){returnreq.method==='POST'&&req.body&&req.body.test;}...

Default:null

Code Defender Middleware - cdMiddleware

Code Defender's middleware to handle the enforcement of CSP headers on responses returned to the client. The express module is in charge of communicating with PerimeterX to receive and maintain the latest CSP policy for the given appId. It also maintains the policy state and invalidates the policy when communication with PerimeterX's Enforcer Data Provider is lost, base on the configuration values (px_csp_no_updates_max_interval_minutes, px_csp_policy_refresh_interval_minutes).

It then uses PerimeterX Node Core module to enforce the actual functionality adding the necessary CSP header to the response object.

usage example:

constperimeterx=require('perimeterx-node-express');
...
constpxInstance=perimeterx.new(pxConfig);app.use(pxInstance.cdMiddleware);
...

Adding Nonce value to CSP header

The PerimeterX Express module allows adding a Nonce value to the CSP header. To do this, use the module's static function addNonce. After PerimeterX cdMiddleware has added the CSP header to the response, call the addNonce function, passing in the response object and a nonce value (string consisting of alphanumeric characters). If a CSP header exists on the response object, the function will alter the header by adding the nonce value in the correct place. The function does not return a value, but rather changes the original response.

constperimeterx=require('perimeterx-node-express');
...
perimeterx.addNonce(response,'rAnd0mNon6e');
...

Please note: the nonce value must be unique for each HTTP response. For further explanation, refer to the official documentation of CSP nonce.

Advanced Blocking Response

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:

constpxConfig={
...
px_advanced_blocking_response_enabled: false...};

Multiple App Support

If you use two different apps on the same node runtime, you can create two instances and use them on two routes:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig1={px_app_id: 'PX_APP_ID_1',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_1',};constmiddlewareApp1=perimeterx.new(pxConfig1).middleware;constapp1Router=express.Router();app1Router.use(middlewareApp1);app1Router.get('/hello',(req,res)=>{res.send('Hello from App1');});server.use('/app1',app1Router);constpxConfig2={px_app_id: 'PX_APP_ID_2',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_2',};constmiddlewareApp2=perimeterx.new(pxConfig2).middleware;constapp2Router=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');});``
## <aname=“additionalInformation”></a>AdditionalInformation
### URIDelimitersPerimeterXprocessesURIpathswithgeneral-andsub-delimitersaccordingtoRFC3986.Generaldelimiters(e.g.,`?`,`#`)areusedtoseparatepartsoftheURI.Sub-delimiters(e.g.,`$`,`&`)arenotusedtosplittheURIastheyareconsideredvalidcharactersintheURIpath.
## Thanks

About

PerimeterX Express.js middleware to monitor and block traffic according to PerimeterX risk score

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Oct 29, 2025. It is now read-only.

Repository files navigation

DEPRECATED

This repository is no longer maintained. Please refer to @humansecurity/node-express-enforcer instead.

Build StatusKnown Vulnerabilities

image

PerimeterX Express.js Middleware

Latest stable version: v7.9.0

Table of Contents

Installation

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.

Upgrading

To upgrade to the latest Enforcer version, run:

npm install -s perimeterx-node-express

For more information, contact PerimeterX Support.

Configuration

Required Configuration

To use PerimeterX middleware on a specific route follow this example:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* px-module and cookie parser need to be initiated before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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');});

Upgrading

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.

Optional Configuration

In addition to the basic installation configuration above, the following configurations options are available:

Module Enabled

A boolean flag to enable/disable the PerimeterX Enforcer.

Default: true

constpxConfig={
...
px_module_enabled: false...};

Module Mode

Sets the working mode of the Enforcer.

Possible values:

  • monitor - Monitor Mode
  • active_blocking - Blocking Mode

Default:monitor

constpxConfig={
...
px_module_mode: "monitor"...};

Blocking Score

Sets the minimum blocking score of a request.

Possible values:

  • Any integer between 0 and 100.

Default: 100

constpxConfig={
...
px_blocking_score: 100...};

Send Page Activities

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

constpxConfig={
...
px_send_async_activities_enabled: true...};

Logger Severity

Sets the logging verbosity level. The available options are:

  • none - no logs will be generated
  • error - logs only when severe errors occur, best for production environments
  • debug - logs more descriptive messages, helpful for analyzing and debugging the enforcer flow

Default: error

constpxConfig={
...
px_logger_severity: 'debug'...};

Sensitive Routes

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

constpxConfig={
...
px_sensitive_routes: ['/login','/user/checkout']...};

Enforced Specific Routes

An array of route prefixes and/or regular expressions that are always validated by the PerimeterX Worker (as opposed to filtered 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

constpxConfig={
...
px_enforced_routes: ['/home',/^\/$/]...};

Monitored Specific Routes

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

constpxConfig={
...
px_monitored_routes: ['/home',newRegExp(/^\/$/)]...};

Filter By Route

An array of route prefixes and/or regular expressions that are always allowed 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

constpxConfig={
...
px_filter_by_route: ['/contact-us',/\/user\/.*\/show/]...};

Sensitive Headers

An array of headers that are not sent to PerimeterX servers on API calls.

Default: ['cookie', 'cookies']

constpxConfig={
...
px_sensitive_headers: ['cookie','cookies','x-sensitive-header']...};

IP Headers

An array of trusted headers that specify an IP to be extracted.

Default: Empty

constpxConfig={
...
px_ip_headers: ['x-user-real-ip']...};

First Party Enabled

A boolean flag to enable/disable first party mode.

Default: true

constpxConfig={
...
px_first_party_enabled: false...};

CD First Party Enabled

A boolean flag to enable/disable Code Defender first party mode.

Default: false

constpxConfig={
...
px_cd_first_party_enabled: false...};

Custom Request Handler

A JavaScript function that adds a custom response handler to the request.

Default: Empty

constpxConfig={
...
px_custom_request_handler: function(pxCtx,pxconfig,req,cb){
...
cb({body: result,status: 200,statusDescription: "OK",header: {key: 'Content-Type',value:'application/json'}})}...};

Additional Activity Handler

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

constpxConfig={
...
px_additional_activity_handler: function(pxCtx,request){
...
}...};

Enrich Custom Parameters

With the px_enrich_custom_parameters 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

constpxConfig={
...
px_enrich_custom_parameters: function(customParams,originalRequest){customParams["custom_param1"]="yay, test value";returncustomParams;}...};

CSS Ref

Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.

Default: Empty

constpxConfig={
...
px_css_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'...};

JS Ref

Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.

Default: Empty

constpxConfig={
...
px_js_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'...};

Custom Logo

The logo is displayed at the top of the the block page. Max-height = 150px, Width = auto.

Default: Empty

constpxConfig={
...
px_custom_logo: 'https://s.perimeterx.net/logo.png',
...
};

Secured PXHD cookie

A boolean flag to enable/disable the Secure flag when baking a PXHD cookie.

Default: false

constpxConfig={
...
px_pxhd_secure: true...};

Proxy Support

Allows traffic to pass through a http proxy server.

Default: Empty

constpxConfig={
...
px_proxy_url: 'https://localhost:8008',
...
};

Custom Cookie Header

When set, instead of extrating the PerimeterX Cookie from the Cookie header, this property specifies a header name that will contain the PerimeterX Cookie.

Default: Empty

constpxConfig={
...
px_custom_cookie_header: "x-px-cookies"...};

Filter Traffic by User Agent

An array of user agent constants and/or regular expressions that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_user_agent: ['testUserAgent/v1.0',/test/]...};

Filter Traffic by IP

An array of IP ranges / IP addresses that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_ip: ['192.168.10.0/24','192.168.2.2']...};

Filter Traffic by HTTP Method

An array of HTTP methods that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_http_method: ['options']...};

Test Block Flow on Monitoring Mode

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 px_bypass_monitor_header property.

Default: Empty

constpxConfig={
...
px_bypass_monitor_header: "x-px-block"...};

CSP Enabled

Used in cdMiddleware - Code Defender's middleware. Enable enforcement of CSP header policy on responses retured to the client (only if active CSP policy exists in PerimeterX for the specific appId).

Default: false

constpxConfig={
...
px_csp_enabled: false...};

CSP Policy Refresh Interval

Used by cdMiddleware - Code Defender's middleware. Sets the interval, in minutes, to fetch and update the active CSP policy for the specific appId from PerimeterX.

Default: 5

constpxConfig={
...
px_csp_policy_refresh_interval_minutes: 5...};

CSP Invalidate Policy Interval

Used by cdMiddleware - Code Defender's middleware. Invalidates active CSP policy after specified number of minutes with no updates received from PerimeterX.

Default: 60

constpxConfig={
...
px_csp_no_updates_max_interval_minutes: 60...};

Login Credentials Extraction

This feature extracts credentials (hashed username and password) from requests and sends them to PerimeterX as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths.

If credentials are found to be compromised, the header px-compromised-credentials will be added to the request with the value 1. You may configure the name of this header with the px_compromised_credentials_header configuration.

Note: This feature requires access to the request body as a either an object or a string type.

Default Values

px_compromised_credentials_header: "px-compromised-credentials"

px_login_credentials_extraction_enabled: false

px_login_credentials_extraction: Empty

constpxConfig={
...
px_compromised_credentials_header: "x-px-comp-creds",px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login pathmethod: "post",// supported values: postsent_through: "body",// supported values: body, header, query-parampass_field: "password",// name of the password field in the requestuser_field: "username"// name of the username field in the request},
...
],
...
};

It is also possible to define a custom callback to extract the username and password. The function should accept the request object as a parameter and return an object with the keys user and pass. If extraction is unsuccessful, the function should return null.

constpxConfig={
...
px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login path, automatically added to sensitive routesmethod: "post",// supported values: postcallback: (req)=>{// custom implementation resulting in variables username and passwordif(username&&password){return{"user": username,"pass": password};}else{returnnull;}}}]};

JWT

Enable the extraction of JWT fields from requests and adding them to the risk, page requested and block activities.

px_jwt_cookie_name

The cookie name that should contain the JWT token.

Default: ""

px_jwt_cookie_user_id_field_name

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted

Default: ""

px_jwt_cookie_additional_field_names

The field names in the JWT object, extracted from the JWT cookie, that should be extracted in addition to the user ID.

Default: []

px_jwt_header_name

The header name that should contain the JWT token.

Default: ""

px_jwt_header_user_id_field_name

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted

Default: ""

px_jwt_header_additional_field_names

The field names in the JWT object, extracted from the JWT header, that should be extracted in addition to the user ID.

Default: []

constpxConfig={
...
"px_jwt_cookie_name": "auth","px_jwt_cookie_user_id_field_name": "nameID","px_jwt_cookie_additional_field_names": ["exp","iss"],"px_jwt_header_name": "authorization","px_jwt_header_user_id_field_name": "sub","px_jwt_header_additional_field_names": ["jti"]...};

Additional S2S Activity

To enhance detection on login credentials extraction endpoints, the following additional information is sent to PerimeterX via an additional_s2s activity:

  • Response Code - The numerical HTTP status code of the response. This is sent automatically.
  • Login Success - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
  • Raw Username - The original username used for the login attempt. In order to report this information, make sure the configuration px_send_raw_username_on_additional_s2s_activity is set to true.

By default, this additional_s2s activity is sent automatically. If it is preferable to send this activity manually, it's possible to disable automatic sending by configuring the value of px_automatic_additional_s2s_activity_enabled to false.

*Default Value: true

constpxConfig={
...
px_automatic_additional_s2s_activity_enabled: false...}

The activity can then be sent manually by invoking the function sendAdditionalS2SActivity(). The function accepts three arguments: the original HTTP request, the status code, and a boolean indicating the login successful status.

constperimeterx=require('perimeterx-node-express');constpxConfig={px_app_id: '<APP_ID>',// ...};pxInstance=perimeterx.new(pxConfig);app.use(pxInstance.middleware);app.post('/login',(req,res)=>{// login flow resulting in boolean isLoginSuccessfulres.status(200).json({successful: isLoginSuccessful});pxInstance.sendAdditionalS2SActivity(req,res.statusCode,isLoginSuccessful);});

Login Success Reporting

There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as false.

Default: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'status'// supported values: status, header, body, custom...}

Status

Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to true. Otherwise, it's set to false.

Note: To define a range of statuses, use the custom reporting method.

Default Values

px_login_successful_status: 200

constpxConfig={
...
px_login_successful_reporting_method: 'status',px_login_successful_status: [200,202]// number or array of numbers...}

Header

Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to true. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to false.

Default Values

px_login_successful_header_name: x-px-login-successful

px_login_successful_header_value: 1

constpxConfig={
...
px_login_successful_reporting_method: 'header',px_login_successful_header_name: 'login-successful',px_login_successful_header_value: 'true'...}

Body

Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set to true. If no match is found, the login successful status is set to false.

Default Values

px_login_successful_body_regex: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'body',px_login_successful_body_regex: 'You logged in successfully!'// string or RegExp...}

Custom

Provide a custom callback that returns a boolean indicating if the login was successful.

Default Values px_login_successful_custom_callback: null

constpxConfig={
...
px_login_successful_reporting_method: 'custom',px_login_successful_custom_callback: (response)=>{returnresponse&&response.locals&&response.locals.isLoginSuccessful;}...}

Raw Username

When enabled, the raw username used for logins on login credentials extraction endpoints will be reported to PerimeterX if (1) the credentials were identified as compromised, and (2) the login was successful as reported via the property above.

Default: false

constpxConfig={
...
px_send_raw_username_on_additional_s2s_activity: true...}

CORS Support

Enable CORS support for the enforcer. This will allow the enforcer to filter out preflight requests and to add CORS headers to block responses. This will ensure responses are not blocked by the browser. CORS support is enabled by default.

px_cors_support_enabled - Enable CORS support for the enforcer.

Default:false

px_cors_custom_preflight_handler - Custom preflight handler. This function will be called for preflight requests and returns response that will return to the client.

// ExampleconstpxConfig={ ...
px_cors_custom_preflight_handler: function(request){constresponse={status: '204',};response.headers={'Access-Control-Allow-Origin': request.headers['origin']||'*','Access-Control-Allow-Methods': request.method,'Access-Control-Allow-Headers': request.headers['access-control-request-headers'],'Access-Control-Allow-Credentials': 'true','Access-Control-Max-Age': '86400',};returnresponse;};}

px_cors_preflight_request_filter_enabled - Filter out preflight requests from validation flow.

Default: false

Enable CORS support for the enforcer:

constpxConfig={
...
px_cors_support_enabled: true,px_cors_preflight_request_filter_enabled: true,
...
};

The default CORS policy when blocking a request is as follows:

Access-Control-Allow-Origin: requestoriginAccess-Control-Allow-Credentials: true

The default CORS policy can be overridden by setting the following properties:

px_cors_create_custom_block_response_headers

Synchronous function supplied by the customer which gets the original request and returns an array of custom headers to be added to the block response. Return type should be an array of objects as follows:

// ExampleconstpxConfig={
...
px_cors_create_custom_block_response_headers: function(request){return{'Access-Control-Allow-Origin': request.headers['origin'],'Access-Control-Allow-Methods': 'GET, POST, OPTIONS','Access-Control-Allow-Headers': 'Content-Type, Authorization','Access-Control-Allow-Credentials': 'true'}};
...
};

Custom Is Sensitive Request

Allows writing your own logic to decide whether the request is sensitive. The custom sensitive request function gets the request object as a parameter and should return true, otherwise, return false. Throwing an exception is equivalent to false.

Default: Empty

constpxConfig={
...
px_custom_is_sensitive_request: function(req){returnreq.method==='POST'&&req.body&&req.body.test;}...

Default:null

Code Defender Middleware - cdMiddleware

Code Defender's middleware to handle the enforcement of CSP headers on responses returned to the client. The express module is in charge of communicating with PerimeterX to receive and maintain the latest CSP policy for the given appId. It also maintains the policy state and invalidates the policy when communication with PerimeterX's Enforcer Data Provider is lost, base on the configuration values (px_csp_no_updates_max_interval_minutes, px_csp_policy_refresh_interval_minutes).

It then uses PerimeterX Node Core module to enforce the actual functionality adding the necessary CSP header to the response object.

usage example:

constperimeterx=require('perimeterx-node-express');
...
constpxInstance=perimeterx.new(pxConfig);app.use(pxInstance.cdMiddleware);
...

Adding Nonce value to CSP header

The PerimeterX Express module allows adding a Nonce value to the CSP header. To do this, use the module's static function addNonce. After PerimeterX cdMiddleware has added the CSP header to the response, call the addNonce function, passing in the response object and a nonce value (string consisting of alphanumeric characters). If a CSP header exists on the response object, the function will alter the header by adding the nonce value in the correct place. The function does not return a value, but rather changes the original response.

constperimeterx=require('perimeterx-node-express');
...
perimeterx.addNonce(response,'rAnd0mNon6e');
...

Please note: the nonce value must be unique for each HTTP response. For further explanation, refer to the official documentation of CSP nonce.

Advanced Blocking Response

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:

constpxConfig={
...
px_advanced_blocking_response_enabled: false...};

Multiple App Support

If you use two different apps on the same node runtime, you can create two instances and use them on two routes:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig1={px_app_id: 'PX_APP_ID_1',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_1',};constmiddlewareApp1=perimeterx.new(pxConfig1).middleware;constapp1Router=express.Router();app1Router.use(middlewareApp1);app1Router.get('/hello',(req,res)=>{res.send('Hello from App1');});server.use('/app1',app1Router);constpxConfig2={px_app_id: 'PX_APP_ID_2',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_2',};constmiddlewareApp2=perimeterx.new(pxConfig2).middleware;constapp2Router=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');});``
## <aname=“additionalInformation”></a>AdditionalInformation
### URIDelimitersPerimeterXprocessesURIpathswithgeneral-andsub-delimitersaccordingtoRFC3986.Generaldelimiters(e.g.,`?`,`#`)areusedtoseparatepartsoftheURI.Sub-delimiters(e.g.,`$`,`&`)arenotusedtosplittheURIastheyareconsideredvalidcharactersintheURIpath.
## Thanks

About

PerimeterX Express.js middleware to monitor and block traffic according to PerimeterX risk score

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Oct 29, 2025. It is now read-only.

Repository files navigation

DEPRECATED

This repository is no longer maintained. Please refer to @humansecurity/node-express-enforcer instead.

Build StatusKnown Vulnerabilities

image

PerimeterX Express.js Middleware

Latest stable version: v7.9.0

Table of Contents

Installation

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.

Upgrading

To upgrade to the latest Enforcer version, run:

npm install -s perimeterx-node-express

For more information, contact PerimeterX Support.

Configuration

Required Configuration

To use PerimeterX middleware on a specific route follow this example:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* px-module and cookie parser need to be initiated before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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');});

Upgrading

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.

Optional Configuration

In addition to the basic installation configuration above, the following configurations options are available:

Module Enabled

A boolean flag to enable/disable the PerimeterX Enforcer.

Default: true

constpxConfig={
...
px_module_enabled: false...};

Module Mode

Sets the working mode of the Enforcer.

Possible values:

  • monitor - Monitor Mode
  • active_blocking - Blocking Mode

Default:monitor

constpxConfig={
...
px_module_mode: "monitor"...};

Blocking Score

Sets the minimum blocking score of a request.

Possible values:

  • Any integer between 0 and 100.

Default: 100

constpxConfig={
...
px_blocking_score: 100...};

Send Page Activities

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

constpxConfig={
...
px_send_async_activities_enabled: true...};

Logger Severity

Sets the logging verbosity level. The available options are:

  • none - no logs will be generated
  • error - logs only when severe errors occur, best for production environments
  • debug - logs more descriptive messages, helpful for analyzing and debugging the enforcer flow

Default: error

constpxConfig={
...
px_logger_severity: 'debug'...};

Sensitive Routes

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

constpxConfig={
...
px_sensitive_routes: ['/login','/user/checkout']...};

Enforced Specific Routes

An array of route prefixes and/or regular expressions that are always validated by the PerimeterX Worker (as opposed to filtered 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

constpxConfig={
...
px_enforced_routes: ['/home',/^\/$/]...};

Monitored Specific Routes

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

constpxConfig={
...
px_monitored_routes: ['/home',newRegExp(/^\/$/)]...};

Filter By Route

An array of route prefixes and/or regular expressions that are always allowed 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

constpxConfig={
...
px_filter_by_route: ['/contact-us',/\/user\/.*\/show/]...};

Sensitive Headers

An array of headers that are not sent to PerimeterX servers on API calls.

Default: ['cookie', 'cookies']

constpxConfig={
...
px_sensitive_headers: ['cookie','cookies','x-sensitive-header']...};

IP Headers

An array of trusted headers that specify an IP to be extracted.

Default: Empty

constpxConfig={
...
px_ip_headers: ['x-user-real-ip']...};

First Party Enabled

A boolean flag to enable/disable first party mode.

Default: true

constpxConfig={
...
px_first_party_enabled: false...};

CD First Party Enabled

A boolean flag to enable/disable Code Defender first party mode.

Default: false

constpxConfig={
...
px_cd_first_party_enabled: false...};

Custom Request Handler

A JavaScript function that adds a custom response handler to the request.

Default: Empty

constpxConfig={
...
px_custom_request_handler: function(pxCtx,pxconfig,req,cb){
...
cb({body: result,status: 200,statusDescription: "OK",header: {key: 'Content-Type',value:'application/json'}})}...};

Additional Activity Handler

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

constpxConfig={
...
px_additional_activity_handler: function(pxCtx,request){
...
}...};

Enrich Custom Parameters

With the px_enrich_custom_parameters 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

constpxConfig={
...
px_enrich_custom_parameters: function(customParams,originalRequest){customParams["custom_param1"]="yay, test value";returncustomParams;}...};

CSS Ref

Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.

Default: Empty

constpxConfig={
...
px_css_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'...};

JS Ref

Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.

Default: Empty

constpxConfig={
...
px_js_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'...};

Custom Logo

The logo is displayed at the top of the the block page. Max-height = 150px, Width = auto.

Default: Empty

constpxConfig={
...
px_custom_logo: 'https://s.perimeterx.net/logo.png',
...
};

Secured PXHD cookie

A boolean flag to enable/disable the Secure flag when baking a PXHD cookie.

Default: false

constpxConfig={
...
px_pxhd_secure: true...};

Proxy Support

Allows traffic to pass through a http proxy server.

Default: Empty

constpxConfig={
...
px_proxy_url: 'https://localhost:8008',
...
};

Custom Cookie Header

When set, instead of extrating the PerimeterX Cookie from the Cookie header, this property specifies a header name that will contain the PerimeterX Cookie.

Default: Empty

constpxConfig={
...
px_custom_cookie_header: "x-px-cookies"...};

Filter Traffic by User Agent

An array of user agent constants and/or regular expressions that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_user_agent: ['testUserAgent/v1.0',/test/]...};

Filter Traffic by IP

An array of IP ranges / IP addresses that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_ip: ['192.168.10.0/24','192.168.2.2']...};

Filter Traffic by HTTP Method

An array of HTTP methods that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_http_method: ['options']...};

Test Block Flow on Monitoring Mode

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 px_bypass_monitor_header property.

Default: Empty

constpxConfig={
...
px_bypass_monitor_header: "x-px-block"...};

CSP Enabled

Used in cdMiddleware - Code Defender's middleware. Enable enforcement of CSP header policy on responses retured to the client (only if active CSP policy exists in PerimeterX for the specific appId).

Default: false

constpxConfig={
...
px_csp_enabled: false...};

CSP Policy Refresh Interval

Used by cdMiddleware - Code Defender's middleware. Sets the interval, in minutes, to fetch and update the active CSP policy for the specific appId from PerimeterX.

Default: 5

constpxConfig={
...
px_csp_policy_refresh_interval_minutes: 5...};

CSP Invalidate Policy Interval

Used by cdMiddleware - Code Defender's middleware. Invalidates active CSP policy after specified number of minutes with no updates received from PerimeterX.

Default: 60

constpxConfig={
...
px_csp_no_updates_max_interval_minutes: 60...};

Login Credentials Extraction

This feature extracts credentials (hashed username and password) from requests and sends them to PerimeterX as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths.

If credentials are found to be compromised, the header px-compromised-credentials will be added to the request with the value 1. You may configure the name of this header with the px_compromised_credentials_header configuration.

Note: This feature requires access to the request body as a either an object or a string type.

Default Values

px_compromised_credentials_header: "px-compromised-credentials"

px_login_credentials_extraction_enabled: false

px_login_credentials_extraction: Empty

constpxConfig={
...
px_compromised_credentials_header: "x-px-comp-creds",px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login pathmethod: "post",// supported values: postsent_through: "body",// supported values: body, header, query-parampass_field: "password",// name of the password field in the requestuser_field: "username"// name of the username field in the request},
...
],
...
};

It is also possible to define a custom callback to extract the username and password. The function should accept the request object as a parameter and return an object with the keys user and pass. If extraction is unsuccessful, the function should return null.

constpxConfig={
...
px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login path, automatically added to sensitive routesmethod: "post",// supported values: postcallback: (req)=>{// custom implementation resulting in variables username and passwordif(username&&password){return{"user": username,"pass": password};}else{returnnull;}}}]};

JWT

Enable the extraction of JWT fields from requests and adding them to the risk, page requested and block activities.

px_jwt_cookie_name

The cookie name that should contain the JWT token.

Default: ""

px_jwt_cookie_user_id_field_name

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted

Default: ""

px_jwt_cookie_additional_field_names

The field names in the JWT object, extracted from the JWT cookie, that should be extracted in addition to the user ID.

Default: []

px_jwt_header_name

The header name that should contain the JWT token.

Default: ""

px_jwt_header_user_id_field_name

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted

Default: ""

px_jwt_header_additional_field_names

The field names in the JWT object, extracted from the JWT header, that should be extracted in addition to the user ID.

Default: []

constpxConfig={
...
"px_jwt_cookie_name": "auth","px_jwt_cookie_user_id_field_name": "nameID","px_jwt_cookie_additional_field_names": ["exp","iss"],"px_jwt_header_name": "authorization","px_jwt_header_user_id_field_name": "sub","px_jwt_header_additional_field_names": ["jti"]...};

Additional S2S Activity

To enhance detection on login credentials extraction endpoints, the following additional information is sent to PerimeterX via an additional_s2s activity:

  • Response Code - The numerical HTTP status code of the response. This is sent automatically.
  • Login Success - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
  • Raw Username - The original username used for the login attempt. In order to report this information, make sure the configuration px_send_raw_username_on_additional_s2s_activity is set to true.

By default, this additional_s2s activity is sent automatically. If it is preferable to send this activity manually, it's possible to disable automatic sending by configuring the value of px_automatic_additional_s2s_activity_enabled to false.

*Default Value: true

constpxConfig={
...
px_automatic_additional_s2s_activity_enabled: false...}

The activity can then be sent manually by invoking the function sendAdditionalS2SActivity(). The function accepts three arguments: the original HTTP request, the status code, and a boolean indicating the login successful status.

constperimeterx=require('perimeterx-node-express');constpxConfig={px_app_id: '<APP_ID>',// ...};pxInstance=perimeterx.new(pxConfig);app.use(pxInstance.middleware);app.post('/login',(req,res)=>{// login flow resulting in boolean isLoginSuccessfulres.status(200).json({successful: isLoginSuccessful});pxInstance.sendAdditionalS2SActivity(req,res.statusCode,isLoginSuccessful);});

Login Success Reporting

There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as false.

Default: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'status'// supported values: status, header, body, custom...}

Status

Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to true. Otherwise, it's set to false.

Note: To define a range of statuses, use the custom reporting method.

Default Values

px_login_successful_status: 200

constpxConfig={
...
px_login_successful_reporting_method: 'status',px_login_successful_status: [200,202]// number or array of numbers...}

Header

Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to true. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to false.

Default Values

px_login_successful_header_name: x-px-login-successful

px_login_successful_header_value: 1

constpxConfig={
...
px_login_successful_reporting_method: 'header',px_login_successful_header_name: 'login-successful',px_login_successful_header_value: 'true'...}

Body

Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set to true. If no match is found, the login successful status is set to false.

Default Values

px_login_successful_body_regex: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'body',px_login_successful_body_regex: 'You logged in successfully!'// string or RegExp...}

Custom

Provide a custom callback that returns a boolean indicating if the login was successful.

Default Values px_login_successful_custom_callback: null

constpxConfig={
...
px_login_successful_reporting_method: 'custom',px_login_successful_custom_callback: (response)=>{returnresponse&&response.locals&&response.locals.isLoginSuccessful;}...}

Raw Username

When enabled, the raw username used for logins on login credentials extraction endpoints will be reported to PerimeterX if (1) the credentials were identified as compromised, and (2) the login was successful as reported via the property above.

Default: false

constpxConfig={
...
px_send_raw_username_on_additional_s2s_activity: true...}

CORS Support

Enable CORS support for the enforcer. This will allow the enforcer to filter out preflight requests and to add CORS headers to block responses. This will ensure responses are not blocked by the browser. CORS support is enabled by default.

px_cors_support_enabled - Enable CORS support for the enforcer.

Default:false

px_cors_custom_preflight_handler - Custom preflight handler. This function will be called for preflight requests and returns response that will return to the client.

// ExampleconstpxConfig={ ...
px_cors_custom_preflight_handler: function(request){constresponse={status: '204',};response.headers={'Access-Control-Allow-Origin': request.headers['origin']||'*','Access-Control-Allow-Methods': request.method,'Access-Control-Allow-Headers': request.headers['access-control-request-headers'],'Access-Control-Allow-Credentials': 'true','Access-Control-Max-Age': '86400',};returnresponse;};}

px_cors_preflight_request_filter_enabled - Filter out preflight requests from validation flow.

Default: false

Enable CORS support for the enforcer:

constpxConfig={
...
px_cors_support_enabled: true,px_cors_preflight_request_filter_enabled: true,
...
};

The default CORS policy when blocking a request is as follows:

Access-Control-Allow-Origin: requestoriginAccess-Control-Allow-Credentials: true

The default CORS policy can be overridden by setting the following properties:

px_cors_create_custom_block_response_headers

Synchronous function supplied by the customer which gets the original request and returns an array of custom headers to be added to the block response. Return type should be an array of objects as follows:

// ExampleconstpxConfig={
...
px_cors_create_custom_block_response_headers: function(request){return{'Access-Control-Allow-Origin': request.headers['origin'],'Access-Control-Allow-Methods': 'GET, POST, OPTIONS','Access-Control-Allow-Headers': 'Content-Type, Authorization','Access-Control-Allow-Credentials': 'true'}};
...
};

Custom Is Sensitive Request

Allows writing your own logic to decide whether the request is sensitive. The custom sensitive request function gets the request object as a parameter and should return true, otherwise, return false. Throwing an exception is equivalent to false.

Default: Empty

constpxConfig={
...
px_custom_is_sensitive_request: function(req){returnreq.method==='POST'&&req.body&&req.body.test;}...

Default:null

Code Defender Middleware - cdMiddleware

Code Defender's middleware to handle the enforcement of CSP headers on responses returned to the client. The express module is in charge of communicating with PerimeterX to receive and maintain the latest CSP policy for the given appId. It also maintains the policy state and invalidates the policy when communication with PerimeterX's Enforcer Data Provider is lost, base on the configuration values (px_csp_no_updates_max_interval_minutes, px_csp_policy_refresh_interval_minutes).

It then uses PerimeterX Node Core module to enforce the actual functionality adding the necessary CSP header to the response object.

usage example:

constperimeterx=require('perimeterx-node-express');
...
constpxInstance=perimeterx.new(pxConfig);app.use(pxInstance.cdMiddleware);
...

Adding Nonce value to CSP header

The PerimeterX Express module allows adding a Nonce value to the CSP header. To do this, use the module's static function addNonce. After PerimeterX cdMiddleware has added the CSP header to the response, call the addNonce function, passing in the response object and a nonce value (string consisting of alphanumeric characters). If a CSP header exists on the response object, the function will alter the header by adding the nonce value in the correct place. The function does not return a value, but rather changes the original response.

constperimeterx=require('perimeterx-node-express');
...
perimeterx.addNonce(response,'rAnd0mNon6e');
...

Please note: the nonce value must be unique for each HTTP response. For further explanation, refer to the official documentation of CSP nonce.

Advanced Blocking Response

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:

constpxConfig={
...
px_advanced_blocking_response_enabled: false...};

Multiple App Support

If you use two different apps on the same node runtime, you can create two instances and use them on two routes:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig1={px_app_id: 'PX_APP_ID_1',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_1',};constmiddlewareApp1=perimeterx.new(pxConfig1).middleware;constapp1Router=express.Router();app1Router.use(middlewareApp1);app1Router.get('/hello',(req,res)=>{res.send('Hello from App1');});server.use('/app1',app1Router);constpxConfig2={px_app_id: 'PX_APP_ID_2',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_2',};constmiddlewareApp2=perimeterx.new(pxConfig2).middleware;constapp2Router=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');});``
## <aname=“additionalInformation”></a>AdditionalInformation
### URIDelimitersPerimeterXprocessesURIpathswithgeneral-andsub-delimitersaccordingtoRFC3986.Generaldelimiters(e.g.,`?`,`#`)areusedtoseparatepartsoftheURI.Sub-delimiters(e.g.,`$`,`&`)arenotusedtosplittheURIastheyareconsideredvalidcharactersintheURIpath.
## Thanks

About

PerimeterX Express.js middleware to monitor and block traffic according to PerimeterX risk score

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Oct 29, 2025. It is now read-only.

Repository files navigation

DEPRECATED

This repository is no longer maintained. Please refer to @humansecurity/node-express-enforcer instead.

Build StatusKnown Vulnerabilities

image

PerimeterX Express.js Middleware

Latest stable version: v7.9.0

Table of Contents

Installation

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.

Upgrading

To upgrade to the latest Enforcer version, run:

npm install -s perimeterx-node-express

For more information, contact PerimeterX Support.

Configuration

Required Configuration

To use PerimeterX middleware on a specific route follow this example:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* px-module and cookie parser need to be initiated before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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');});

Upgrading

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.

Optional Configuration

In addition to the basic installation configuration above, the following configurations options are available:

Module Enabled

A boolean flag to enable/disable the PerimeterX Enforcer.

Default: true

constpxConfig={
...
px_module_enabled: false...};

Module Mode

Sets the working mode of the Enforcer.

Possible values:

  • monitor - Monitor Mode
  • active_blocking - Blocking Mode

Default:monitor

constpxConfig={
...
px_module_mode: "monitor"...};

Blocking Score

Sets the minimum blocking score of a request.

Possible values:

  • Any integer between 0 and 100.

Default: 100

constpxConfig={
...
px_blocking_score: 100...};

Send Page Activities

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

constpxConfig={
...
px_send_async_activities_enabled: true...};

Logger Severity

Sets the logging verbosity level. The available options are:

  • none - no logs will be generated
  • error - logs only when severe errors occur, best for production environments
  • debug - logs more descriptive messages, helpful for analyzing and debugging the enforcer flow

Default: error

constpxConfig={
...
px_logger_severity: 'debug'...};

Sensitive Routes

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

constpxConfig={
...
px_sensitive_routes: ['/login','/user/checkout']...};

Enforced Specific Routes

An array of route prefixes and/or regular expressions that are always validated by the PerimeterX Worker (as opposed to filtered 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

constpxConfig={
...
px_enforced_routes: ['/home',/^\/$/]...};

Monitored Specific Routes

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

constpxConfig={
...
px_monitored_routes: ['/home',newRegExp(/^\/$/)]...};

Filter By Route

An array of route prefixes and/or regular expressions that are always allowed 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

constpxConfig={
...
px_filter_by_route: ['/contact-us',/\/user\/.*\/show/]...};

Sensitive Headers

An array of headers that are not sent to PerimeterX servers on API calls.

Default: ['cookie', 'cookies']

constpxConfig={
...
px_sensitive_headers: ['cookie','cookies','x-sensitive-header']...};

IP Headers

An array of trusted headers that specify an IP to be extracted.

Default: Empty

constpxConfig={
...
px_ip_headers: ['x-user-real-ip']...};

First Party Enabled

A boolean flag to enable/disable first party mode.

Default: true

constpxConfig={
...
px_first_party_enabled: false...};

CD First Party Enabled

A boolean flag to enable/disable Code Defender first party mode.

Default: false

constpxConfig={
...
px_cd_first_party_enabled: false...};

Custom Request Handler

A JavaScript function that adds a custom response handler to the request.

Default: Empty

constpxConfig={
...
px_custom_request_handler: function(pxCtx,pxconfig,req,cb){
...
cb({body: result,status: 200,statusDescription: "OK",header: {key: 'Content-Type',value:'application/json'}})}...};

Additional Activity Handler

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

constpxConfig={
...
px_additional_activity_handler: function(pxCtx,request){
...
}...};

Enrich Custom Parameters

With the px_enrich_custom_parameters 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

constpxConfig={
...
px_enrich_custom_parameters: function(customParams,originalRequest){customParams["custom_param1"]="yay, test value";returncustomParams;}...};

CSS Ref

Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.

Default: Empty

constpxConfig={
...
px_css_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'...};

JS Ref

Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.

Default: Empty

constpxConfig={
...
px_js_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'...};

Custom Logo

The logo is displayed at the top of the the block page. Max-height = 150px, Width = auto.

Default: Empty

constpxConfig={
...
px_custom_logo: 'https://s.perimeterx.net/logo.png',
...
};

Secured PXHD cookie

A boolean flag to enable/disable the Secure flag when baking a PXHD cookie.

Default: false

constpxConfig={
...
px_pxhd_secure: true...};

Proxy Support

Allows traffic to pass through a http proxy server.

Default: Empty

constpxConfig={
...
px_proxy_url: 'https://localhost:8008',
...
};

Custom Cookie Header

When set, instead of extrating the PerimeterX Cookie from the Cookie header, this property specifies a header name that will contain the PerimeterX Cookie.

Default: Empty

constpxConfig={
...
px_custom_cookie_header: "x-px-cookies"...};

Filter Traffic by User Agent

An array of user agent constants and/or regular expressions that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_user_agent: ['testUserAgent/v1.0',/test/]...};

Filter Traffic by IP

An array of IP ranges / IP addresses that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_ip: ['192.168.10.0/24','192.168.2.2']...};

Filter Traffic by HTTP Method

An array of HTTP methods that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_http_method: ['options']...};

Test Block Flow on Monitoring Mode

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 px_bypass_monitor_header property.

Default: Empty

constpxConfig={
...
px_bypass_monitor_header: "x-px-block"...};

CSP Enabled

Used in cdMiddleware - Code Defender's middleware. Enable enforcement of CSP header policy on responses retured to the client (only if active CSP policy exists in PerimeterX for the specific appId).

Default: false

constpxConfig={
...
px_csp_enabled: false...};

CSP Policy Refresh Interval

Used by cdMiddleware - Code Defender's middleware. Sets the interval, in minutes, to fetch and update the active CSP policy for the specific appId from PerimeterX.

Default: 5

constpxConfig={
...
px_csp_policy_refresh_interval_minutes: 5...};

CSP Invalidate Policy Interval

Used by cdMiddleware - Code Defender's middleware. Invalidates active CSP policy after specified number of minutes with no updates received from PerimeterX.

Default: 60

constpxConfig={
...
px_csp_no_updates_max_interval_minutes: 60...};

Login Credentials Extraction

This feature extracts credentials (hashed username and password) from requests and sends them to PerimeterX as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths.

If credentials are found to be compromised, the header px-compromised-credentials will be added to the request with the value 1. You may configure the name of this header with the px_compromised_credentials_header configuration.

Note: This feature requires access to the request body as a either an object or a string type.

Default Values

px_compromised_credentials_header: "px-compromised-credentials"

px_login_credentials_extraction_enabled: false

px_login_credentials_extraction: Empty

constpxConfig={
...
px_compromised_credentials_header: "x-px-comp-creds",px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login pathmethod: "post",// supported values: postsent_through: "body",// supported values: body, header, query-parampass_field: "password",// name of the password field in the requestuser_field: "username"// name of the username field in the request},
...
],
...
};

It is also possible to define a custom callback to extract the username and password. The function should accept the request object as a parameter and return an object with the keys user and pass. If extraction is unsuccessful, the function should return null.

constpxConfig={
...
px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login path, automatically added to sensitive routesmethod: "post",// supported values: postcallback: (req)=>{// custom implementation resulting in variables username and passwordif(username&&password){return{"user": username,"pass": password};}else{returnnull;}}}]};

JWT

Enable the extraction of JWT fields from requests and adding them to the risk, page requested and block activities.

px_jwt_cookie_name

The cookie name that should contain the JWT token.

Default: ""

px_jwt_cookie_user_id_field_name

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted

Default: ""

px_jwt_cookie_additional_field_names

The field names in the JWT object, extracted from the JWT cookie, that should be extracted in addition to the user ID.

Default: []

px_jwt_header_name

The header name that should contain the JWT token.

Default: ""

px_jwt_header_user_id_field_name

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted

Default: ""

px_jwt_header_additional_field_names

The field names in the JWT object, extracted from the JWT header, that should be extracted in addition to the user ID.

Default: []

constpxConfig={
...
"px_jwt_cookie_name": "auth","px_jwt_cookie_user_id_field_name": "nameID","px_jwt_cookie_additional_field_names": ["exp","iss"],"px_jwt_header_name": "authorization","px_jwt_header_user_id_field_name": "sub","px_jwt_header_additional_field_names": ["jti"]...};

Additional S2S Activity

To enhance detection on login credentials extraction endpoints, the following additional information is sent to PerimeterX via an additional_s2s activity:

  • Response Code - The numerical HTTP status code of the response. This is sent automatically.
  • Login Success - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
  • Raw Username - The original username used for the login attempt. In order to report this information, make sure the configuration px_send_raw_username_on_additional_s2s_activity is set to true.

By default, this additional_s2s activity is sent automatically. If it is preferable to send this activity manually, it's possible to disable automatic sending by configuring the value of px_automatic_additional_s2s_activity_enabled to false.

*Default Value: true

constpxConfig={
...
px_automatic_additional_s2s_activity_enabled: false...}

The activity can then be sent manually by invoking the function sendAdditionalS2SActivity(). The function accepts three arguments: the original HTTP request, the status code, and a boolean indicating the login successful status.

constperimeterx=require('perimeterx-node-express');constpxConfig={px_app_id: '<APP_ID>',// ...};pxInstance=perimeterx.new(pxConfig);app.use(pxInstance.middleware);app.post('/login',(req,res)=>{// login flow resulting in boolean isLoginSuccessfulres.status(200).json({successful: isLoginSuccessful});pxInstance.sendAdditionalS2SActivity(req,res.statusCode,isLoginSuccessful);});

Login Success Reporting

There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as false.

Default: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'status'// supported values: status, header, body, custom...}

Status

Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to true. Otherwise, it's set to false.

Note: To define a range of statuses, use the custom reporting method.

Default Values

px_login_successful_status: 200

constpxConfig={
...
px_login_successful_reporting_method: 'status',px_login_successful_status: [200,202]// number or array of numbers...}

Header

Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to true. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to false.

Default Values

px_login_successful_header_name: x-px-login-successful

px_login_successful_header_value: 1

constpxConfig={
...
px_login_successful_reporting_method: 'header',px_login_successful_header_name: 'login-successful',px_login_successful_header_value: 'true'...}

Body

Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set to true. If no match is found, the login successful status is set to false.

Default Values

px_login_successful_body_regex: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'body',px_login_successful_body_regex: 'You logged in successfully!'// string or RegExp...}

Custom

Provide a custom callback that returns a boolean indicating if the login was successful.

Default Values px_login_successful_custom_callback: null

constpxConfig={
...
px_login_successful_reporting_method: 'custom',px_login_successful_custom_callback: (response)=>{returnresponse&&response.locals&&response.locals.isLoginSuccessful;}...}

Raw Username

When enabled, the raw username used for logins on login credentials extraction endpoints will be reported to PerimeterX if (1) the credentials were identified as compromised, and (2) the login was successful as reported via the property above.

Default: false

constpxConfig={
...
px_send_raw_username_on_additional_s2s_activity: true...}

CORS Support

Enable CORS support for the enforcer. This will allow the enforcer to filter out preflight requests and to add CORS headers to block responses. This will ensure responses are not blocked by the browser. CORS support is enabled by default.

px_cors_support_enabled - Enable CORS support for the enforcer.

Default:false

px_cors_custom_preflight_handler - Custom preflight handler. This function will be called for preflight requests and returns response that will return to the client.

// ExampleconstpxConfig={ ...
px_cors_custom_preflight_handler: function(request){constresponse={status: '204',};response.headers={'Access-Control-Allow-Origin': request.headers['origin']||'*','Access-Control-Allow-Methods': request.method,'Access-Control-Allow-Headers': request.headers['access-control-request-headers'],'Access-Control-Allow-Credentials': 'true','Access-Control-Max-Age': '86400',};returnresponse;};}

px_cors_preflight_request_filter_enabled - Filter out preflight requests from validation flow.

Default: false

Enable CORS support for the enforcer:

constpxConfig={
...
px_cors_support_enabled: true,px_cors_preflight_request_filter_enabled: true,
...
};

The default CORS policy when blocking a request is as follows:

Access-Control-Allow-Origin: requestoriginAccess-Control-Allow-Credentials: true

The default CORS policy can be overridden by setting the following properties:

px_cors_create_custom_block_response_headers

Synchronous function supplied by the customer which gets the original request and returns an array of custom headers to be added to the block response. Return type should be an array of objects as follows:

// ExampleconstpxConfig={
...
px_cors_create_custom_block_response_headers: function(request){return{'Access-Control-Allow-Origin': request.headers['origin'],'Access-Control-Allow-Methods': 'GET, POST, OPTIONS','Access-Control-Allow-Headers': 'Content-Type, Authorization','Access-Control-Allow-Credentials': 'true'}};
...
};

Custom Is Sensitive Request

Allows writing your own logic to decide whether the request is sensitive. The custom sensitive request function gets the request object as a parameter and should return true, otherwise, return false. Throwing an exception is equivalent to false.

Default: Empty

constpxConfig={
...
px_custom_is_sensitive_request: function(req){returnreq.method==='POST'&&req.body&&req.body.test;}...

Default:null

Code Defender Middleware - cdMiddleware

Code Defender's middleware to handle the enforcement of CSP headers on responses returned to the client. The express module is in charge of communicating with PerimeterX to receive and maintain the latest CSP policy for the given appId. It also maintains the policy state and invalidates the policy when communication with PerimeterX's Enforcer Data Provider is lost, base on the configuration values (px_csp_no_updates_max_interval_minutes, px_csp_policy_refresh_interval_minutes).

It then uses PerimeterX Node Core module to enforce the actual functionality adding the necessary CSP header to the response object.

usage example:

constperimeterx=require('perimeterx-node-express');
...
constpxInstance=perimeterx.new(pxConfig);app.use(pxInstance.cdMiddleware);
...

Adding Nonce value to CSP header

The PerimeterX Express module allows adding a Nonce value to the CSP header. To do this, use the module's static function addNonce. After PerimeterX cdMiddleware has added the CSP header to the response, call the addNonce function, passing in the response object and a nonce value (string consisting of alphanumeric characters). If a CSP header exists on the response object, the function will alter the header by adding the nonce value in the correct place. The function does not return a value, but rather changes the original response.

constperimeterx=require('perimeterx-node-express');
...
perimeterx.addNonce(response,'rAnd0mNon6e');
...

Please note: the nonce value must be unique for each HTTP response. For further explanation, refer to the official documentation of CSP nonce.

Advanced Blocking Response

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:

constpxConfig={
...
px_advanced_blocking_response_enabled: false...};

Multiple App Support

If you use two different apps on the same node runtime, you can create two instances and use them on two routes:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig1={px_app_id: 'PX_APP_ID_1',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_1',};constmiddlewareApp1=perimeterx.new(pxConfig1).middleware;constapp1Router=express.Router();app1Router.use(middlewareApp1);app1Router.get('/hello',(req,res)=>{res.send('Hello from App1');});server.use('/app1',app1Router);constpxConfig2={px_app_id: 'PX_APP_ID_2',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_2',};constmiddlewareApp2=perimeterx.new(pxConfig2).middleware;constapp2Router=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');});``
## <aname=“additionalInformation”></a>AdditionalInformation
### URIDelimitersPerimeterXprocessesURIpathswithgeneral-andsub-delimitersaccordingtoRFC3986.Generaldelimiters(e.g.,`?`,`#`)areusedtoseparatepartsoftheURI.Sub-delimiters(e.g.,`$`,`&`)arenotusedtosplittheURIastheyareconsideredvalidcharactersintheURIpath.
## Thanks

About

PerimeterX Express.js middleware to monitor and block traffic according to PerimeterX risk score

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Oct 29, 2025. It is now read-only.

Repository files navigation

DEPRECATED

This repository is no longer maintained. Please refer to @humansecurity/node-express-enforcer instead.

Build StatusKnown Vulnerabilities

image

PerimeterX Express.js Middleware

Latest stable version: v7.9.0

Table of Contents

Installation

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.

Upgrading

To upgrade to the latest Enforcer version, run:

npm install -s perimeterx-node-express

For more information, contact PerimeterX Support.

Configuration

Required Configuration

To use PerimeterX middleware on a specific route follow this example:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* px-module and cookie parser need to be initiated before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig={px_app_id: 'PX_APP_ID',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: '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');});

Upgrading

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.

Optional Configuration

In addition to the basic installation configuration above, the following configurations options are available:

Module Enabled

A boolean flag to enable/disable the PerimeterX Enforcer.

Default: true

constpxConfig={
...
px_module_enabled: false...};

Module Mode

Sets the working mode of the Enforcer.

Possible values:

  • monitor - Monitor Mode
  • active_blocking - Blocking Mode

Default:monitor

constpxConfig={
...
px_module_mode: "monitor"...};

Blocking Score

Sets the minimum blocking score of a request.

Possible values:

  • Any integer between 0 and 100.

Default: 100

constpxConfig={
...
px_blocking_score: 100...};

Send Page Activities

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

constpxConfig={
...
px_send_async_activities_enabled: true...};

Logger Severity

Sets the logging verbosity level. The available options are:

  • none - no logs will be generated
  • error - logs only when severe errors occur, best for production environments
  • debug - logs more descriptive messages, helpful for analyzing and debugging the enforcer flow

Default: error

constpxConfig={
...
px_logger_severity: 'debug'...};

Sensitive Routes

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

constpxConfig={
...
px_sensitive_routes: ['/login','/user/checkout']...};

Enforced Specific Routes

An array of route prefixes and/or regular expressions that are always validated by the PerimeterX Worker (as opposed to filtered 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

constpxConfig={
...
px_enforced_routes: ['/home',/^\/$/]...};

Monitored Specific Routes

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

constpxConfig={
...
px_monitored_routes: ['/home',newRegExp(/^\/$/)]...};

Filter By Route

An array of route prefixes and/or regular expressions that are always allowed 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

constpxConfig={
...
px_filter_by_route: ['/contact-us',/\/user\/.*\/show/]...};

Sensitive Headers

An array of headers that are not sent to PerimeterX servers on API calls.

Default: ['cookie', 'cookies']

constpxConfig={
...
px_sensitive_headers: ['cookie','cookies','x-sensitive-header']...};

IP Headers

An array of trusted headers that specify an IP to be extracted.

Default: Empty

constpxConfig={
...
px_ip_headers: ['x-user-real-ip']...};

First Party Enabled

A boolean flag to enable/disable first party mode.

Default: true

constpxConfig={
...
px_first_party_enabled: false...};

CD First Party Enabled

A boolean flag to enable/disable Code Defender first party mode.

Default: false

constpxConfig={
...
px_cd_first_party_enabled: false...};

Custom Request Handler

A JavaScript function that adds a custom response handler to the request.

Default: Empty

constpxConfig={
...
px_custom_request_handler: function(pxCtx,pxconfig,req,cb){
...
cb({body: result,status: 200,statusDescription: "OK",header: {key: 'Content-Type',value:'application/json'}})}...};

Additional Activity Handler

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

constpxConfig={
...
px_additional_activity_handler: function(pxCtx,request){
...
}...};

Enrich Custom Parameters

With the px_enrich_custom_parameters 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

constpxConfig={
...
px_enrich_custom_parameters: function(customParams,originalRequest){customParams["custom_param1"]="yay, test value";returncustomParams;}...};

CSS Ref

Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.

Default: Empty

constpxConfig={
...
px_css_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'...};

JS Ref

Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.

Default: Empty

constpxConfig={
...
px_js_ref: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'...};

Custom Logo

The logo is displayed at the top of the the block page. Max-height = 150px, Width = auto.

Default: Empty

constpxConfig={
...
px_custom_logo: 'https://s.perimeterx.net/logo.png',
...
};

Secured PXHD cookie

A boolean flag to enable/disable the Secure flag when baking a PXHD cookie.

Default: false

constpxConfig={
...
px_pxhd_secure: true...};

Proxy Support

Allows traffic to pass through a http proxy server.

Default: Empty

constpxConfig={
...
px_proxy_url: 'https://localhost:8008',
...
};

Custom Cookie Header

When set, instead of extrating the PerimeterX Cookie from the Cookie header, this property specifies a header name that will contain the PerimeterX Cookie.

Default: Empty

constpxConfig={
...
px_custom_cookie_header: "x-px-cookies"...};

Filter Traffic by User Agent

An array of user agent constants and/or regular expressions that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_user_agent: ['testUserAgent/v1.0',/test/]...};

Filter Traffic by IP

An array of IP ranges / IP addresses that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_ip: ['192.168.10.0/24','192.168.2.2']...};

Filter Traffic by HTTP Method

An array of HTTP methods that are always filtered and not validated by the PerimeterX middleware.

Default: Empty

constpxConfig={
...
px_filter_by_http_method: ['options']...};

Test Block Flow on Monitoring Mode

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 px_bypass_monitor_header property.

Default: Empty

constpxConfig={
...
px_bypass_monitor_header: "x-px-block"...};

CSP Enabled

Used in cdMiddleware - Code Defender's middleware. Enable enforcement of CSP header policy on responses retured to the client (only if active CSP policy exists in PerimeterX for the specific appId).

Default: false

constpxConfig={
...
px_csp_enabled: false...};

CSP Policy Refresh Interval

Used by cdMiddleware - Code Defender's middleware. Sets the interval, in minutes, to fetch and update the active CSP policy for the specific appId from PerimeterX.

Default: 5

constpxConfig={
...
px_csp_policy_refresh_interval_minutes: 5...};

CSP Invalidate Policy Interval

Used by cdMiddleware - Code Defender's middleware. Invalidates active CSP policy after specified number of minutes with no updates received from PerimeterX.

Default: 60

constpxConfig={
...
px_csp_no_updates_max_interval_minutes: 60...};

Login Credentials Extraction

This feature extracts credentials (hashed username and password) from requests and sends them to PerimeterX as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths.

If credentials are found to be compromised, the header px-compromised-credentials will be added to the request with the value 1. You may configure the name of this header with the px_compromised_credentials_header configuration.

Note: This feature requires access to the request body as a either an object or a string type.

Default Values

px_compromised_credentials_header: "px-compromised-credentials"

px_login_credentials_extraction_enabled: false

px_login_credentials_extraction: Empty

constpxConfig={
...
px_compromised_credentials_header: "x-px-comp-creds",px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login pathmethod: "post",// supported values: postsent_through: "body",// supported values: body, header, query-parampass_field: "password",// name of the password field in the requestuser_field: "username"// name of the username field in the request},
...
],
...
};

It is also possible to define a custom callback to extract the username and password. The function should accept the request object as a parameter and return an object with the keys user and pass. If extraction is unsuccessful, the function should return null.

constpxConfig={
...
px_login_credentials_extraction_enabled: true,px_login_credentials_extraction: [{path: "/login",// login path, automatically added to sensitive routesmethod: "post",// supported values: postcallback: (req)=>{// custom implementation resulting in variables username and passwordif(username&&password){return{"user": username,"pass": password};}else{returnnull;}}}]};

JWT

Enable the extraction of JWT fields from requests and adding them to the risk, page requested and block activities.

px_jwt_cookie_name

The cookie name that should contain the JWT token.

Default: ""

px_jwt_cookie_user_id_field_name

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted

Default: ""

px_jwt_cookie_additional_field_names

The field names in the JWT object, extracted from the JWT cookie, that should be extracted in addition to the user ID.

Default: []

px_jwt_header_name

The header name that should contain the JWT token.

Default: ""

px_jwt_header_user_id_field_name

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted

Default: ""

px_jwt_header_additional_field_names

The field names in the JWT object, extracted from the JWT header, that should be extracted in addition to the user ID.

Default: []

constpxConfig={
...
"px_jwt_cookie_name": "auth","px_jwt_cookie_user_id_field_name": "nameID","px_jwt_cookie_additional_field_names": ["exp","iss"],"px_jwt_header_name": "authorization","px_jwt_header_user_id_field_name": "sub","px_jwt_header_additional_field_names": ["jti"]...};

Additional S2S Activity

To enhance detection on login credentials extraction endpoints, the following additional information is sent to PerimeterX via an additional_s2s activity:

  • Response Code - The numerical HTTP status code of the response. This is sent automatically.
  • Login Success - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
  • Raw Username - The original username used for the login attempt. In order to report this information, make sure the configuration px_send_raw_username_on_additional_s2s_activity is set to true.

By default, this additional_s2s activity is sent automatically. If it is preferable to send this activity manually, it's possible to disable automatic sending by configuring the value of px_automatic_additional_s2s_activity_enabled to false.

*Default Value: true

constpxConfig={
...
px_automatic_additional_s2s_activity_enabled: false...}

The activity can then be sent manually by invoking the function sendAdditionalS2SActivity(). The function accepts three arguments: the original HTTP request, the status code, and a boolean indicating the login successful status.

constperimeterx=require('perimeterx-node-express');constpxConfig={px_app_id: '<APP_ID>',// ...};pxInstance=perimeterx.new(pxConfig);app.use(pxInstance.middleware);app.post('/login',(req,res)=>{// login flow resulting in boolean isLoginSuccessfulres.status(200).json({successful: isLoginSuccessful});pxInstance.sendAdditionalS2SActivity(req,res.statusCode,isLoginSuccessful);});

Login Success Reporting

There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as false.

Default: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'status'// supported values: status, header, body, custom...}

Status

Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to true. Otherwise, it's set to false.

Note: To define a range of statuses, use the custom reporting method.

Default Values

px_login_successful_status: 200

constpxConfig={
...
px_login_successful_reporting_method: 'status',px_login_successful_status: [200,202]// number or array of numbers...}

Header

Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to true. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to false.

Default Values

px_login_successful_header_name: x-px-login-successful

px_login_successful_header_value: 1

constpxConfig={
...
px_login_successful_reporting_method: 'header',px_login_successful_header_name: 'login-successful',px_login_successful_header_value: 'true'...}

Body

Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set to true. If no match is found, the login successful status is set to false.

Default Values

px_login_successful_body_regex: Empty

constpxConfig={
...
px_login_successful_reporting_method: 'body',px_login_successful_body_regex: 'You logged in successfully!'// string or RegExp...}

Custom

Provide a custom callback that returns a boolean indicating if the login was successful.

Default Values px_login_successful_custom_callback: null

constpxConfig={
...
px_login_successful_reporting_method: 'custom',px_login_successful_custom_callback: (response)=>{returnresponse&&response.locals&&response.locals.isLoginSuccessful;}...}

Raw Username

When enabled, the raw username used for logins on login credentials extraction endpoints will be reported to PerimeterX if (1) the credentials were identified as compromised, and (2) the login was successful as reported via the property above.

Default: false

constpxConfig={
...
px_send_raw_username_on_additional_s2s_activity: true...}

CORS Support

Enable CORS support for the enforcer. This will allow the enforcer to filter out preflight requests and to add CORS headers to block responses. This will ensure responses are not blocked by the browser. CORS support is enabled by default.

px_cors_support_enabled - Enable CORS support for the enforcer.

Default:false

px_cors_custom_preflight_handler - Custom preflight handler. This function will be called for preflight requests and returns response that will return to the client.

// ExampleconstpxConfig={ ...
px_cors_custom_preflight_handler: function(request){constresponse={status: '204',};response.headers={'Access-Control-Allow-Origin': request.headers['origin']||'*','Access-Control-Allow-Methods': request.method,'Access-Control-Allow-Headers': request.headers['access-control-request-headers'],'Access-Control-Allow-Credentials': 'true','Access-Control-Max-Age': '86400',};returnresponse;};}

px_cors_preflight_request_filter_enabled - Filter out preflight requests from validation flow.

Default: false

Enable CORS support for the enforcer:

constpxConfig={
...
px_cors_support_enabled: true,px_cors_preflight_request_filter_enabled: true,
...
};

The default CORS policy when blocking a request is as follows:

Access-Control-Allow-Origin: requestoriginAccess-Control-Allow-Credentials: true

The default CORS policy can be overridden by setting the following properties:

px_cors_create_custom_block_response_headers

Synchronous function supplied by the customer which gets the original request and returns an array of custom headers to be added to the block response. Return type should be an array of objects as follows:

// ExampleconstpxConfig={
...
px_cors_create_custom_block_response_headers: function(request){return{'Access-Control-Allow-Origin': request.headers['origin'],'Access-Control-Allow-Methods': 'GET, POST, OPTIONS','Access-Control-Allow-Headers': 'Content-Type, Authorization','Access-Control-Allow-Credentials': 'true'}};
...
};

Custom Is Sensitive Request

Allows writing your own logic to decide whether the request is sensitive. The custom sensitive request function gets the request object as a parameter and should return true, otherwise, return false. Throwing an exception is equivalent to false.

Default: Empty

constpxConfig={
...
px_custom_is_sensitive_request: function(req){returnreq.method==='POST'&&req.body&&req.body.test;}...

Default:null

Code Defender Middleware - cdMiddleware

Code Defender's middleware to handle the enforcement of CSP headers on responses returned to the client. The express module is in charge of communicating with PerimeterX to receive and maintain the latest CSP policy for the given appId. It also maintains the policy state and invalidates the policy when communication with PerimeterX's Enforcer Data Provider is lost, base on the configuration values (px_csp_no_updates_max_interval_minutes, px_csp_policy_refresh_interval_minutes).

It then uses PerimeterX Node Core module to enforce the actual functionality adding the necessary CSP header to the response object.

usage example:

constperimeterx=require('perimeterx-node-express');
...
constpxInstance=perimeterx.new(pxConfig);app.use(pxInstance.cdMiddleware);
...

Adding Nonce value to CSP header

The PerimeterX Express module allows adding a Nonce value to the CSP header. To do this, use the module's static function addNonce. After PerimeterX cdMiddleware has added the CSP header to the response, call the addNonce function, passing in the response object and a nonce value (string consisting of alphanumeric characters). If a CSP header exists on the response object, the function will alter the header by adding the nonce value in the correct place. The function does not return a value, but rather changes the original response.

constperimeterx=require('perimeterx-node-express');
...
perimeterx.addNonce(response,'rAnd0mNon6e');
...

Please note: the nonce value must be unique for each HTTP response. For further explanation, refer to the official documentation of CSP nonce.

Advanced Blocking Response

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:

constpxConfig={
...
px_advanced_blocking_response_enabled: false...};

Multiple App Support

If you use two different apps on the same node runtime, you can create two instances and use them on two routes:

'use strict';constexpress=require('express');constperimeterx=require('perimeterx-node-express');constserver=express();/* the px-module and parser need to be initialized before any route usage */constpxConfig1={px_app_id: 'PX_APP_ID_1',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_1',};constmiddlewareApp1=perimeterx.new(pxConfig1).middleware;constapp1Router=express.Router();app1Router.use(middlewareApp1);app1Router.get('/hello',(req,res)=>{res.send('Hello from App1');});server.use('/app1',app1Router);constpxConfig2={px_app_id: 'PX_APP_ID_2',px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',px_auth_token: 'PX_TOKEN_2',};constmiddlewareApp2=perimeterx.new(pxConfig2).middleware;constapp2Router=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');});``
## <aname=“additionalInformation”></a>AdditionalInformation
### URIDelimitersPerimeterXprocessesURIpathswithgeneral-andsub-delimitersaccordingtoRFC3986.Generaldelimiters(e.g.,`?`,`#`)areusedtoseparatepartsoftheURI.Sub-delimiters(e.g.,`$`,`&`)arenotusedtosplittheURIastheyareconsideredvalidcharactersintheURIpath.
## Thanks

About

PerimeterX Express.js middleware to monitor and block traffic according to PerimeterX risk score

Topics

Resources

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages