Negligible Psychological Misery

    perimeterx-node-express

    7.0.3 • Public • Published

    Build Status Known Vulnerabilities

    image

    PerimeterX Express.js Middleware

    Latest stable version: v7.0.3

    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';
    
    const express = require('express');
    const perimeterx = require('perimeterx-node-express');
    
    const server = express();
    
    /* px-module and cookie parser need to be initiated before any route usage */
    const pxConfig = {
        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';
    
    const express = require('express');
    const perimeterx = require('perimeterx-node-express');
    
    const server = express();
    
    /* the px-module and parser need to be initialized before any route usage */
    const pxConfig = {
        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

    const pxConfig = {
      ...
      px_module_enabled: false
      ...
    };

    Module Mode

    Sets the working mode of the Enforcer.

    Possible values:

    • monitor - Monitor Mode
    • active_blocking - Blocking Mode

    Default: monitor

    const pxConfig = {
      ...
      px_module_mode: "monitor"
      ...
    };

    Blocking Score

    Sets the minimum blocking score of a request.

    Possible values:

    • Any integer between 0 and 100.

    Default: 100

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      px_monitored_routes: ['/home', new RegExp(/^\/$/)]
      ...
    };

    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

    const pxConfig = {
      ...
      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']

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

    IP Headers

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

    Default: Empty

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

    First Party Enabled

    A boolean flag to enable/disable first party mode.

    Default: true

    const pxConfig = {
      ...
      px_first_party_enabled: false
      ...
    };

    CD First Party Enabled

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

    Default: false

    const pxConfig = {
      ...
      px_cd_first_party_enabled: false
      ...
    };

    Custom Request Handler

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

    Default: Empty

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

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

    CSS Ref

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

    Default: Empty

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      px_pxhd_secure: true
      ...
    };

    Proxy Support

    Allows traffic to pass through a http proxy server.

    Default: Empty

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      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

    const pxConfig = {
      ...
      px_compromised_credentials_header: "x-px-comp-creds",
      px_login_credentials_extraction_enabled: true,
      px_login_credentials_extraction: [
        {
          path: "/login", // login path
          method: "post", // supported methods: post
          sentThrough: "body", // supported sentThroughs: body, header, query-param
          contentType: "json", // supported contentTypes: json, form
          encoding: "clear-text", // supported encodings: clear-text, url-encode
          passField: "password", // name of the password field in the request
          userField: "username" // name of the username field in the request
        },
        ...
      ],
      ...
    };

    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 maintain 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 PerimetrX Node Core module to enforce the actual functionality adding the necessary CSP header to the response object.

    usage example:

    const perimeterx = require('perimeterx-node-express');
    ...
    const pxInstance = 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.

    const perimeterx = 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:

    const pxConfig = {
      ...
      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';
    
    const express = require('express');
    const perimeterx = require('perimeterx-node-express');
    
    const server = express();
    
    /* the px-module and parser need to be initialized before any route usage */
    const pxConfig1 = {
        px_app_id: 'PX_APP_ID_1',
        px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',
        px_auth_token: 'PX_TOKEN_1',
    };
    const middlewareApp1 = perimeterx.new(pxConfig1).middleware;
    const app1Router = express.Router();
    app1Router.use(middlewareApp1);
    app1Router.get('/hello', (req, res) => {
        res.send('Hello from App1');
    });
    server.use('/app1', app1Router);
    
    const pxConfig2 = {
        px_app_id: 'PX_APP_ID_2',
        px_cookie_secret: 'PX_COOKIE_ENCRYPTION_KEY',
        px_auth_token: 'PX_TOKEN_2',
    };
    const middlewareApp2 = perimeterx.new(pxConfig2).middleware;
    const app2Router = express.Router();
    app2Router.use(middlewareApp2);
    app2Router.get('/app2', (req, res) => {
        res.send('Hello from App2');
    });
    server.use('/app2', app1Router);
    
    server.listen(8081, () => {
        console.log('server started');
    });

    Additional Information

    URI Delimiters

    PerimeterX processes URI paths with general- and sub-delimiters according to RFC 3986. General delimiters (e.g., ?, #) are used to separate parts of the URI. Sub-delimiters (e.g., $, &) are not used to split the URI as they are considered valid characters in the URI path.

    Thanks

    Install

    npm i perimeterx-node-express

    DownloadsWeekly Downloads

    16,483

    Version

    7.0.3

    License

    ISC

    Unpacked Size

    50.4 kB

    Total Files

    15

    Last publish

    Collaborators

    • bendpx
    • yaronpx
    • nlevi1984
    • pxjohnny
    • ilaipx
    • ori.gold
    • shaulpx
    • omerbacharpx
    • asafpx
    • chennakarpx