Configuration (v5 and Below)

The HUMAN Enforcer is configured using a set of properties specified in the custom/pxConfig.json` file. A minimal valid configuration file looks as follows:

//pxConfig.json
{
    px_app_id: 'APP_ID',
    px_auth_token: 'AUTH_TOKEN',
    px_cookie_secret: 'COOKIE_SECRET',
};
//pxConfig.json
{
    appId: 'APP_ID',
    authToken: 'AUTH_TOKEN',
    cookieKey: 'COOKIE_SECRET',
};

In addition, the following set of properties is available:

Is Bot Enforcer

A boolean flag to configure the enforcer as Bot Defender enforcer

Default: true

const pxConfig = {
 ...
 px_bot_enforcer: true
 ...
};
const pxConfig = {
 ...
 isBotEnforcer: true
 ...
};

Is Code Enforcer

A boolean flag to configure the enforcer as Code Defender enforcer

Default: false

const pxConfig = {
 ...
 px_code_enforcer: false
 ...
};
const pxConfig = {
 ...
 isCodeEnforcer: false
 ...
};

Module Enabled

A boolean flag to enable/disable the HUMAN Enforcer.

Default: true

const pxConfig = {
 ...
 px_module_enabled: true
 ...
};
const pxConfig = {
 ...
 moduleEnabled: true
 ...
};

Module Mode

Sets the working mode of the worker.

Possible values:

  • monitor - Monitor Mode
  • active_blocking - Blocking Mode

From v4.0.0 - A string that sets the working mode of the worker.
Default: monitor (from v4.0.0)

Up to v3.3.0 - 0/1 numeric value which sets the working mode of the worker (0 - monitor mode, 1 - active blocking mode)
Default: 0 (up to v3.3.0)

const pxConfig = {
 ...
 px_module_mode: 'monitor'
 ...
};
const pxConfig = {
 ...
 moduleMode: 0
 ...
};

Blocking ScoreSets the minimum blocking score of a request.

Possible values:

  • Any integer between 0 and 100.

Default: 100

const pxConfig = {
 ...
 px_blocking_score: 100
 ...
};
const pxConfig = {
 ...
 blockingScore: 100
 ...
};

Cross-Origin Resource Sharing (CORS) Support

For security reasons, browsers can block cross-origin requests, if they are not allowed by a third-party origin.

CORS is a mechanism that lets the server indicate, if a request contains cross-origin resources. It does so by adding special HTTP headers to the request, which allows the browser to load such resources.

In most cases, CORS employs a two-stage procedure with a preliminary request, called preflight, followed by the actual request. The preflight request checks if the actual request will be responded to. To learn more about different request types, see these examples.

The CORS behavior must be configured to address both simple requests (without preflight) and more complex ones (with preflight).

Use the following Enforcer functions to configure CORS:

FunctionDefault ValueDescription
px_cors_support_enabledfalseSet to true to enable CORS support.
px_cors_create_custom_block_response_headersnullDefine here custom headers to be added to the block response. Required for simple request. If not configured, default settings will be applied.
px_cors_preflight_request_filter_enabledfalseSet to true to let the Enforcer pass preflight requests to the origin.
px_cors_custom_preflight_handlernullDefine here a custom handler that will allow the Enforcer to respond to preflight requests immediately without passing them to the origin.

Default block response headers settings:

return [{ name: 'Access-Control-Allow-Origin', value: request.headers.get('Origin')},
        { name: 'Access-Control-Allow-Credentials', value: 'true' }
}

Here’s an example of how to configure your Enforcer using these functions:

const pxConfig = {
  ...
  px_cors_support_enabled: true
  ...
};
px_cors_create_custom_block_response_headers: (request) => {
   return [{ name: 'Access-Control-Allow-Origin', value: request.headers.get('Origin')},
           { name: 'Access-Control-Allow-Credentials', value: 'true' },
           { name: 'Access-Control-Allow-Methods', value: 'GET, POST, OPTIONS' },
           { name: 'Access-Control-Allow-Headers', value: 'Content-Type, Authorization' }];
}

const pxConfig = {
  ...
  px_cors_preflight_request_filter_enabled: true
  ...
};
px_cors_custom_preflight_handler: (request) => {
   const responseHeaders = {
      'Access-Control-Allow-Origin': request.headers.get('Origin'),
      'Access-Control-Allow-Methods': request.headers.get('Access-Control-Request-Method'),
      'Access-Control-Allow-Headers': request.headers.get('Access-Control-Request-Headers'),
      'Access-Control-Allow-Credentials': 'true',
      'Access-Control-Max-Age': '86400',
   };
   return new Response(null, { headers: responseHeaders, status: 204 });
}

Debug Mode

From v4.0.0
Sets the logging mode of the worker.

Possible values:

  • none - HUMAN logger will not output any logs
  • error - HUMAN logger will log errors only and fatal events (e.g., exceptions)
  • debug - HUMAN logger will output detailed logs for debugging purposes

Be aware that log messages are present in your worker's logs tab in Cloudflare's dashboard
Default: error

Up to v3.3.0
A flag that configures the enforcer in debug mode, so that the logger will output detailed logs for debugging purposes.

Default: false

const pxConfig = {
 ...
 px_logger_severity: `error`
 ...
};
const pxConfig = {
 ...
 debugMode: false
 ...
};

Send Async Activities

A boolean flag to enable or disable sending of activities and metrics to HUMAN on each request. Enabling this feature will provide data that populates the HUMAN 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
 ...
};
const pxConfig = {
 ...
 sendPageActivities: true
 ...
};

S2S Timeout

The maximum amount of time, in milliseconds, to wait when performing a Risk API request. If this timeout is reached before a score is obtained, the request will pass with pass_reason: s2s_timeout.

Default: 1000

const pxConfig = {
 ...
 px_s2s_timeout: 2000,
 ...
};

Sensitive Routes

An array of route prefixes and/or regular expressions that trigger a server call to HUMAN servers every time the page is viewed, regardless of viewing history.

Default: Empty array

const pxConfig = {
 ...
 px_sensitive_routes: ['/login', /\/user\/.*\/checkout/]
 ...
};
const pxConfig = {
 ...
 sensitiveRoutes: ['/login', '/user/checkout']
 ...
};

Sensitive Headers

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

Default: ['cookie', 'cookies']

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

IP Headers

An array of trusted headers that specify an IP to be extracted. If the array is empty, the default IP header cf-connecting-ip is used.

Default: Empty array

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

First Party Enabled

A boolean flag to enable or disable first-party mode.

Default: true

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

Filter By Extension

An array of extensions that are always filtered and not validated by the HUMAN Enforcer. Requests with path extensions matching these configured patterns will always be allowed to pass the HUMAN Enforcer. Extensions written with or without periods (e.g., .css or css) are equivalent.

Default: ['.css', '.bmp', '.tif', '.ttf', '.docx', '.woff2', '.js', '.pict', '.tiff', '.eot', '.xlsx', '.jpg', '.csv', '.eps', '.woff', '.xls', '.jpeg', '.doc', '.ejs', '.otf', '.pptx', '.gif', '.pdf', '.swf', '.svg', '.ps', '.ico', '.pls', '.midi', '.svgz', '.class', '.png', '.ppt', '.mid', '.webp', '.jar', '.json', '.xml']

const pxConfig = {
  ...
  px_filter_by_extension: ['html', 'css', 'js', 'jpg'],
  ...
};

Filter By HTTP Method

An array of strings that represent HTTP methods that are always filtered and not validated by the HUMAN Enforcer.
Requests with HTTP methods matching these will always be allowed to pass the HUMAN Enforcer.

Default: []

const pxConfig = {
  ...
  px_filter_by_extension: ['DELETE'],
  ...
};

Filter By Route

An array of route prefixes and/or regular expressions that are always filtered out and not validated by the HUMAN Enforcer. Requests with paths matching these configured patterns will always be allowed to pass the HUMAN Enforcer.

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.

📘

Note

This feature was called "whitelisted URIs" in previous versions.

Default: Empty

const pxConfig = {
  ...
  px_filter_by_route: ['/contant-us', /\/user\/.*\/show/]
  ...
};
const pxConfig = {
  ...
  px_whitelist_uri_full: ['/contant-us', /\/user\/.*\/show/]
  ...
};

Enforced Specific Routes

Use this feature to define an array of route prefixes/regular expressions to be enforced in the Monitor mode.

You may want certain requests to be enforced by HUMAN, even when the Enforcer is in the Monitor mode. Requests for predefined route prefixes (example: /profile/user/test) and/or regular expressions (example: /profile.*) will go through the full enforcement workflow, and may be blocked based on their score.

Default: Empty array

const pxConfig = {
  ...
  px_enforced_routes: ['/home',/^\/$/

                      ]
  ...
};
const pxConfig = {
  ...
  enforcedSpecificRoutes: ['/home',/^\/$/]
  ...
};

Monitored Specific Routes

An array of route prefixes and/or regular expressions that are always set to be in the 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 array

const pxConfig = {
  ...
  px_monitored_routes: ['/home', /^\/$/]
  ...
};
const pxConfig = {
  ...
  monitoredSpecificRoutes: ['/home', /^\/$/]
  ...
};

Custom Verification Handler

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

Default: null

module.exports = {
  ...
    px_custom_verification_handler: (pxCtx, request) => {
      ...
      return {body: result, status: 200, statusDescription: "OK", header: {key: 'Content-Type', value:'application/json'}};
    },
  ...
};
module.exports = {
  ...
    customVerificationHandler: (pxCtx, request) => {
      ...
      return {body: result, status: 200, statusDescription: "OK", header: {key: 'Content-Type', value:'application/json'}};
    },
  ...
};

PX Context Object (pxCtx)

pxCtx is an internal object within the Enforcer, which is created per request and holds the entire state regarding the specific request. The customer who integrates the Enforcer in his environment controls the Enforcer behavior using different configuration values, a few of them are custom functions the customer can implement as necessary.
One of the parameters for those custom functions is the pxCtx, which can be used to access fields and values that the Enforcer has inferred from the request as part of its detection process, and can be used by the customer to perform his own logic based on our detections.
A simple use case for example is to examine the px score that the request gets and add a header to the request to the origin with the given score.

The functions that has access to the pxCtx are:

  • Additional Activity Handler
  • Enrich Custom Parameters
  • Custom Verification Handler (only exists in Cloudflare) - A function that adds a custom
    response handler to the request, in case you want to respond differently on some requests.

pxCtx useful fields:

  • score - the PX score this request received.
  • riskRtt - risk round trip time, the time it took for the risk request from when it was sent util the response was received.
  • pxde - PX data enrichment, the data enrichment cookie is attached to S2S calls as a way to transfer additional data between the Enforcer and HUMAN collector. The data it contains is set by the collector according to the setting in the portal and is available on the cookie as a JSON object. While this functionality is mostly controlled by the collector, you may want access to the PXDE values after activities have been sent, in the additional activity handler.
  • passReason- the reason PX decided to pass the request, can be one of:
    • s2s
    • cookie
    • s2s_timeout
    • s2s_error
  • isMobile - whether this is a mobile or web request.
  • httpMethod - the request’s http method.
  • ip - the ip of the request as the Enforcer concluded.
  • additionalFields - holds login credentials (hashed) and graphQL related information

Additional Activity Handler

A JavaScript function that allows interaction with the request data collected by HUMAN before the data is returned to the HUMAN servers. This function must be set in the custom/pxCustomFunctionsConfig.js file.

Default: null

module.exports = {
  ...
    px_additional_activity_handler: (pxCtx, config) => {
      const dataEnrichmentObject = pxCtx.pxde;
      const isDataEnrichmentVerified = pxCtx.pxdeVerified;
      ...
    },
  ...
};
module.exports = {
  ...
    additionalActivityHandler: (pxCtx, config) => {
      const dataEnrichmentObject = pxCtx.pxde;
      const isDataEnrichmentVerified = pxCtx.pxdeVerified;
      ...
    },
  ...
};

Enrich Custom Parameters

With the px_enrich_custom_parameters function you can add up to 10 custom parameters to be sent back to HUMAN servers. When set, the function is called before setting the payload on every request to HUMAN servers. The parameters should be passed according to the correct order (1-10) and their format must align as following: custom_param1, custom_param2, ... , custom_param10. The parameters passed along with the px_enrich_custom_parameters function are request which is the Cloudflare request object, and pxCtx which is a HUMAN object.

Default: Empty

module.exports = {
  ...
    px_enrich_custom_parameters: async (pxCtx, request) => {
      let customParams = {};
      customParams["custom_param1"] = "yay, test value";
      // ...
      return customParams;
    },
  ...
};
module.exports = {
  ...
    enrichCustomParameters: async (pxCtx, request) => {
      let customParams = {};
      customParams["custom_param1"] = "yay, test value";
      // ...
      return customParams;
    },
  ...
};

Hype Sale Challenge

The enforcer will serve a hype sale challenge for any request that is marked as a hype sale. To mark a request as hype sale add a custom parameter with the key is_hype_sale and a boolean value of true. Since marking the request is in the enrich custom param method, the mark can be upon request parameters, context parameters, or any other logic or global variables (environment variables or KV)

for example, the following snippet will initiate hype sale challenge for a request which contains query param 'id' with the value 111:

module.exports = {
  ...
    px_enrich_custom_parameters: async (pxCtx, request) => {
      const { searchParams } = new URL(request.url);
            if (searchParams.has("id")){
                let id = searchParams.get('id');
                return {
                    "is_hype_sale" : id === '111'
                    }
            }
            return {};
    },
  ...
};
module.exports = {
  ...
    enrichCustomParameters: async (pxCtx, request) => {
      const { searchParams } = new URL(request.url);
            if (searchParams.has("id")){
                let id = searchParams.get('id');
                return {
                    "is_hype_sale" : id === '111'
                    }
            }
            return {};
    },
  ...
};

CSS Ref

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

Default: Empty

const pxConfig = {
  ...
  cssRef: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'
  ...
};
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 px_js_ref 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'
 ...
};
const pxConfig = {
 ...
 jsRef: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'
 ...
};

Custom Logo

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

Default: Empty

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

Filter Traffic by User Agent

An array of user agents that are always filtered and not validated by the HUMAN Enforcer.

Default: Empty

const pxConfig = {
 ...
 px_filter_by_user_agent: ['testUserAgent/v1.0']
 ...
};
const pxConfig = {
 ...
 filterByUserAgent: ['testUserAgent/v1.0']
 ...
};

Filter Traffic by IP

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

Default: Empty array

const pxConfig = {
 ...
 px_filter_by_ip: ['192.168.10.0/24', '192.168.2.2']
 ...
};
const pxConfig = {
 ...
 filterByIP: ['192.168.10.0/24', '192.168.2.2']
 ...
};

Filter Traffic by header

An object consists of headerName: headerValue pairs that are always filtered and not validated by the HUMAN Enforcer.

Default: Empty

From v4.0.3

const pxConfig = {
 ...
 px_filter_by_header: {
    test_header: "true",
    goodBot: "abc"
 }
 ...
};

Custom Cookie Header

Allows to set a header name which is used to extract theHUMAN cookies (processed in addition to the Cookie header).

Default: "x-px-cookies"

const pxConfig = {
 ...
 px_custom_cookie_header: "x-px-cookies"
 ...
};
const pxConfig = {
 ...
 customCookieHeader: "x-px-cookies"
 ...
};

Upstream Score Header

When set, this property specifies a header name that will contain the HUMAN score to be sent to the origin.

Default: Empty

const pxConfig = {
 ...
 px_score_header_name: "x-px-score"
 ...
};
const pxConfig = {
 ...
 scoreHeaderName: "x-px-score"
 ...
};

Upstream Identifier Header

When set, this property specifies a header name that will contain the HUMAN unique identifier (UUID) to be sent to the origin.

Default: Empty

const pxConfig = {
 ...
     px_identifier_header_name: "x-px-uuid"
 ...
};
const pxConfig = {
 ...
     identifierHeaderName: "x-px-uuid"
 ...
};

Login Credentials Extraction

This feature extracts credentials (hashed username and password) from requests and sends them to HUMAN 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. The settings are adjusted by modifying the custom/pxConfig JSON object.
If credentials are found to be compromised, the header px-compromised-credentials will be added to the origin request with the value 1. You may configure the name of this header with the px_compromised_credentials_header configuration.

Default Values

  • px_compromised_credentials_header: "px-compromised-credentials"
  • px_login_credentials_extraction_enabled: false
  • px_login_credentials_extraction: []

From v4.0.0

const pxConfig = {
  ...
  px_compromised_credentials_header: "x-px-comp-creds",
  px_login_credentials_extraction_enabled: true,
  px_login_credentials_extraction: [
    {
      path_type: "exact" or "regex" // default: exact
      path: "/login", // support regular expressions and exact path configuration
      method: "post", // supports all http methods
      sent_through: "body", // supported sent_throughs: body, header, query-param
      pass_field: "password", // name (or array of names) of the password field in the request (can also be nested field using dots i.e details.password)
      user_field: ["username", "email"] // name (or array of names) of the username field in the request (can also be nested field using dots i.e details.username)
    },
    ...
  ],
  ...
};

📘

Important Notice

Define regular expression "path": When using path_type "regex" the path attribute should contain regular expression as a string pattern without slashes and without flags (i.e, instead of /ab+c/i configure "ab+c"). Regular expressions are treated as case-insensitive by the enforcer by default.

Configure user_field or pass_field as an array when the same login endpoint can have two or more different field names as input.

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.

From v4.0.0

const pxConfig = {
    ...
    px_login_credentials_extraction_enabled: true,
    px_login_credentials_extraction: [{
        path: "/login",
        method: "post",
        callback: (req) => {
            // custom implementation extracting the username and password, e.g.:
            const { username, password } = await req.pxCtx.getRequestBody(req);
            if (username && password) {
                return { user: username, pass: password };
            } else {
                return null;
            }
        }
    }]
};

📘

Note

Reading the request body in Cloudflare may increase the request handling time. Since the HUMAN Enforcer may need to read the request body for various operations, we recommend that custom functions retrieve the request body using await request.pxCtx.getRequestBody(request). If the body has already been read and parsed, it will return immediately without needing to clone the request and parse the body a second time. If the body has not already been read, it will save the parsed body in the pxCtx object so that subsequent invocations will not need to clone or parse the body.

Multistep Login

In some site architectures, the username and password are sent on different HTTP requests. In this case, all relevant paths should be configured as credentials extraction endpoints, and the configuration value px_credentials_intelligence_version should be set as multistep_sso. (There is no other need to change this configuration value.)

Default: v2

From v4.4.0

const pxConfig = {
    ...
  px_credentials_intelligence_version: "multistep_sso",
  px_login_credentials_extraction: [
    {
      path: "/login/username",
      method: "post",
      sent_through: "body",
      pass_field: "none",
      user_field: "username"
    },
    {
      path: "/login/password",
      method: "post",
      sent_through: "body",
      pass_field: "password",
      user_field: "none"
    },
  ],
  ...
}

Additional S2S Activity

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

  • Response Code - The numerical HTTP status code of the response.
  • 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.

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

From v4.4.0

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

From v4.4.0

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

From v4.2.0

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

From v4.2.0

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

From v4.2.0

const pxConfig = {
    ...
    px_login_successful_reporting_method: 'custom',
    px_login_successful_custom_callback: (response) => {
        // custom implementation resulting in boolean isLoginSuccessful
        return isLoginSuccessful;
    }
    ...
}

Additional S2S Activity Headers

Available from v4.4.0.

Rather than sending the additional_s2s activity automatically, it is instead possible to generate the base additional_s2s activity along with the URL endpoint, and pass them to the origin server as headers on the original HTTP request. When enabled, the module will add two new headers to the original request and send them to the origin:

  • px-additional-activity, a stringified JSON activity that should be sent.
  • px-additional-activity-url, the complete URL endpoint to which the JSON object should be sent.

Note: Enabling this feature will disable the automatic sending of the additional_s2s activity.

Default Values

px_additional_s2s_activity_header_enabled: false

From v4.2.0

const pxConfig = {
  // ...
  px_additional_s2s_activity_header_enabled: true,
  //...
};

The px-additional-activity header value is a stringified JSON object that looks like this. Only the fields indicated with // MODIFY should be changed prior to sending. Other fields should not be altered in any way.

{
  "type": "additional_s2s",
  "timestamp": 1637000000,
  "socket_ip": "1.1.1.1",
  "px_app_id": "PX_APP_ID",
  "url": "https://www.example.com/the-target-url",
  "vid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "details": {
    "client_uuid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "request_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "ci_version": "v1",
    "http_status_code": null, // MODIFY, number (e.g., 200, 401, 404, etc.)
    "login_successful": null, // MODIFY, boolean (e.g., true, false)
    "raw_username": null // MODIFY, string (e.g., "[email protected]")
  }
}

After parsing the object and adding the appropriate http_status_code and login_successful fields in the origin server, send the JSON object as an HTTP POST request to the URL provided in the px-additional-activity-url header.

Note: The POST request should be sent with the Content-Type: application/json and Authorization: Bearer <PX_AUTH_TOKEN> headers.

Example Origin Server Behavior

This code provides an example of code at the origin server that handles these headers and performs the API call. The example is in JavaScript, but the process of extracting the px-additional-activity and px-additional-activity-url headers, modifying the necessary activity fields, and executing the additional_s2s XHR request to the HUMAN servers is applicable to all servers for which this feature is enabled, regardless of language.

app.post('/login', (req, res) => {
    // complete login flow, resulting in boolean variable isLoginSuccessful
    const responseStatusCode = isLoginSuccessful ? 200 : 401;
    res.sendStatus(responseStatusCode);

    if (req.headers['px-additional-activity'] && req.headers['px-additional-activity-url']) {
        handlePxAdditionalActivity(req, responseStatusCode, isLoginSuccessful);
    }
});

function handlePxAdditionalActivity(req, statusCode, isLoginSuccessful) {
    try {
        // extract url and activity from the request headers
        const url = req.headers['px-additional-activity-url'];
        const activity = JSON.parse(req.headers['px-additional-activity']);

        // change the modifiable values
        activity.details['http_status_code'] = statusCode;
        activity.details['login_successful'] = isLoginSuccessful;

        if (activity.details['credentials_compromised'] && isLoginSuccessful) {
            // add raw username if credentials are compromised and login is successful
            activity.details['raw_username'] = req.body.username;
        } else {
            // remove raw username if login is not successful or credentials are not compromised
            delete activity.details['raw_username'];
        }

        // send the POST request
        axios.post(url, activity, {
            headers: {
                'Authorization': `Bearer ${env.PX_AUTH_TOKEN}`,
                'Content-Type': 'application/json'
            }
        });
    } catch (err) {
        console.error(`Error: ${err}`);
    }
}

Raw Username

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

Default: false

From v4.2.0

const pxConfig = {
    ...
    px_send_raw_username_on_additional_s2s_activity: true
    ...
}

Sensitive GraphQL Operations

For those using GraphQL endpoints, it is possible to trigger server-to-server risk calls on particular operation types or names. Like the sensitive routes feature, a request that contains an operation of the configured type or name will trigger a server call to HUMAN servers every time that operation is performed.

If an operation type (e.g., query, mutation) is configured in px_sensitive_graphql_operation_types, all GraphQL operations of that type will be treated as sensitive. If an operation name is configured in px_sensitive_graphql_operation_names, all GraphQL operations with that name will be treated as sensitive.

Note: This feature only applies to requests that contain the string graphql somewhere in the path name.

Default Values:

px_graphql_enabled: true

px_graphql_routes: ['/graphql']

px_sensitive_graphql_operation_types: Empty

px_sensitive_graphql_operation_names: Empty

From v4.2.0

const pxConfig = {
    ...
    px_graphql_routes: ['/graphql', /^\/(graphql|apiendpoint)$/],
    px_sensitive_graphql_operation_types: ["mutation"],
    px_sensitive_graphql_operation_names: ["LoginOperation", "AccountInfoQuery"]
    ...
};

CSP Support

Add CSP policy header to the response returned to the client (only if active CSP policy exists in HUMAN for the specific appId) - px_csp_enabled.

Default: false

Invalidates active CSP policy after specified time in minutes where no updates were received from HUMAN - px_csp_no_updates_max_interval_minutes.

Default: 60

const pxConfig = {
  ...
  px_csp_enabled: true,
  px_csp_no_updates_max_interval_minutes: 60
  ...
};
const pxConfig = {
  ...
  cspEnabled: true,
  cspNoUpdatesMaxIntervalMinutes: 60
  ...
};

User Identifiers

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

Configuration NameDefault ValueDescription
px_jwt_cookie_nameEmpty StringThe cookie name that should contain the JWT token.
px_jwt_cookie_user_id_field_nameEmpty StringThe field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted. This field name can include a path for a nested object.
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. These fields' names can include paths for nested objects.
px_jwt_header_nameEmpty StringThe header name that should contain the JWT token.
px_jwt_header_user_id_field_nameEmpty StringThe field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted. This field name can include a path for a nested object.
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. These fields' names can include paths for nested objects.

const pxConfig = {
  ...
    "px_jwt_cookie_name":  "auth",
    "px_jwt_cookie_user_id_field_name": "nameid",
    "px_jwt_cookie_additional_field_names": ["exp", "iss", "user_info.userid"],
    "px_jwt_header_name":  "authorization",
    "px_jwt_header_user_id_field_name": "sub",
    "px_jwt_header_additional_field_names": ["jti, additional.fieldname"]
  ...
};

Pre Enforce Handler

preEnforcerHandler is a function supplied by the customer (supports both synchronous and asynchronous functions) which gets the original request and the request context constructed by HUMAN (pxCtx) and returns an integer value (or a Promise resolved with an integer value) representing one of the following enum values:

  • 0 - continue with the request to the regular enforcer flow
  • 1 - drop the request and respond with block/captcha page (based on the customer’s policy)

Default: null

module.exports = {
  ...
    px_pre_enforce_handler: (pxCtx, request) => {
      if (request.something) {
          return 1;
      } else {
          return 0;
      }
    },
  ...
};
module.exports = {
  ...
    preEnforceHandler: (pxCtx, request) => {
      if (request.something) {
          return 1;
      } else {
          return 0;
      }
    },
  ...
};

Deferred Activities

A boolean flag to enable/disable sending HUMAN page_requested activity after getting the response from the origin.

Default: true

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

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(e.g., 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"
  ...
};
const pxConfig = {
  ...
  bypassMonitorHeader: "x-px-block"
  ...
};

Snippet Injection

A boolean flag to enable/disable injection of the JavaScript sensors snippet into site pages. The snippet will be added to the end of the <head> element.

Default: false

const pxConfig = {
 ...
 px_snippet_provider_enabled: true
 ...
};
const pxConfig = {
 ...
 px_sensor_inject_enabled: true
 ...
};

px_snippet_provider_cache_ttl_seconds determines how long will the snippet retrieved from HUMAN servers will be held in the cache. After the specified time period the enforcer will attempt to retrieve the snippet again from the HUMAN servers.

Default: 600

From v4.1.0

const pxConfig = {
 ...
 px_snippet_provider_cache_ttl_seconds: 600
 ...
};

📘

Important Notice

When enabling the Snippet injection feature, do not forget to address the First Party Enabled configuration.

Defining the content of the snippet to be injected to the HTML response is done internally via HUMAN operations team. To do so please get in touch with your HUMAN contact person or contact support here.

Custom 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`. Implementing this configuration does not override other `sensitive` configurations, like `sensitive_routes`.

Example:

px_custom_is_sensitive_request = async (request) => {
   const url = new URL(request.url);
   if (request.method === 'POST' && url.pathname === '/test') {
         const req = request.clone();
         let body = await req.json();
         if (body && body.specificField) {
            return true;
          }
   }
   return false;
}

📘

Note for reading the request body:

For reading the request body, it's mandatory to create a copy of the request object (by using the `clone()` function and read the body from the cloned request.

Enforcer Timeout

By default, the Enforcer is set to timeout after 1000 ms. If you wish to change the value of the timeout, set the desired value of the ENFORCE_TIMEOUT property in your workerBundle.js file.

...
ENFORCE_TIMEOUT = 2000 // sets the timeout to 2000ms
...

Sign Cookie with IP

By default, cookies are signed with user agent only; however, it is possible to sign cookies with the socket IP as well. In order to enable cookie signing with the socket IP, ensure that the socket IP is extracted properly using the px_ip_headers configuration and reach out to your HUMAN representative.