npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

perimeterx-nextjs

v0.2.1

Published

PerimeterX enforcer built to support NextJS applications

Downloads

1,666

Readme

PerimeterX NextJS Enforcer

Install

npm install perimeterx-nextjs

Usage

perimeterx(pxConfig)

Example

  1. Assuming you already have NextJS application, if not create a new one
  2. Edit middleware.js (or middleware.ts)
    const {perimeterx} = require("perimeterx-nextjs")
      
    const pxConfig = {
        px_app_id: "<APP_ID>",
        px_cookie_secret: "<COOKIE_SECRET>",
        px_auth_token: "<AUTH_TOKEN>",
        px_module_mode: "active_blocking",
    }
    export default perimeterx(pxConfig)

Middleware

Add custom code after the enforcer

const {perimeterx} = require("perimeterx-nextjs")

const pxConfig = {
    onPass: (request) => {
        // This request was verified by PerimeterX
    },
    onResponse: (request, response) => {
        // Instead of returning the block page / first party / etc... 
        // write a custom logic here 
    },

    px_app_id: "<APP_ID>",
    px_cookie_secret: "<COOKIE_SECRET>",
    px_auth_token: "<AUTH_TOKEN>",
    px_module_mode: "active_blocking",
    // Additional configurations
}

export default perimeterx(pxConfig) 

PerimeterXConfigurations

Required values:

px_app_id

The application ID. Required to initialize the Enforcer.

const config: PerimeterXConfigurations = {
  // ...
  px_app_id: '<APP_ID>',
  // ...
}

px_auth_token

The token used for authorization with the Human/PerimeterX backend. Required to initialize the Enforcer.

const config: PerimeterXConfigurations = {
  // ...
  px_auth_token: '<AUTH_TOKEN>',
  // ...
}

px_cookie_secret

The secret used to encrypt and decrypt the risk cookie. Required to initialize the Enforcer.

const config: PerimeterXConfigurations = {
  // ...
  px_cookie_secret: '<COOKIE_SECRET>',
  // ...
}

px_module_enabled

This boolean serves as an on/off switch for the entire module, providing a way to enable and disable all Enforcer capabilities quickly and easily.

Default: true

const config: PerimeterXConfigurations = {
  // ...
  px_module_enabled: false,
  // ...
}

px_module_mode

This feature controls the behavior of the enforcer by changing how it executes certain parts of the workflow. Most notably, different modes allow for analysis and fine-tuning of the enforcer behavior without serving block pages that affect end users.

Possible values:

  • monitor - the enforcer will perform all functions without returning block responses
  • active_blocking - the enforcer will return block responses when needed

Default: monitor

const config: PerimeterXConfigurations = {
  // ...
  px_module_mode: 'active_blocking',
  // ...
}

px_logger_severity

The verbosity of the logs generated by the enforcer. The enforcer will always use the console.log() function regardless of the configured logger severity.

Possible values:

  • none - No logs will be generated
  • error - Sparse logs will be generated only when errors occur
  • debug - Detailed logs will always be generated (not advisable for production environments)

Default: error

const config: PerimeterXConfigurations = {
  // ...
  px_logger_severity: 'debug',
  // ...
}

px_s2s_timeout

The maximum time in milliseconds to wait for the risk API request. If this timeout is reached, the original request will be allowed to pass (fail open).

Default: 1000

const config: PerimeterXConfigurations = {
  // ...
  px_s2s_timeout: 2000,
  // ...
}

px_ip_headers

By default, the IP is taken from request.ip However, if this is inaccurate, the enforcer can extract the IP from the headers configured here. The headers are traversed in the order they are listed. The first header value that exists will be used as the client IP.

Default: []

const config: PerimeterXConfigurations = {
  // ...
  px_ip_headers: ['true-ip', 'true-client-ip'],
  // ...
}

px_advanced_blocking_response_enabled

In specific cases (e.g., XHR post requests), a full captcha page render might not be an option. In such cases the advanced blocking response returns a JSON object containing all the information needed to render a customized captcha challenge implementation - be it a popup modal, a section on the page, etc. This allows for flexibility and customizability in terms of how the captcha pages are displayed.

Default: true

const config: PerimeterXConfigurations = {
  // ...
  px_advanced_blocking_response_enabled: false,
  // ...
}

px_first_party_enabled

To prevent suspicious or unwanted behavior on the client side, some browsers or extensions (e.g., adblockers) may deny the frontend JavaScript code from making requests to other domains. This prevents the PerimeterX sensor from making requests to the PerimeterX backends, which greatly limits PerimeterX's detection capabilities. To avoid this problem, first_party enables the enforcer to be used as a proxy for PerimeterX servers, and to serve content to the browser from a first party endpoint (i.e., an endpoint on the customer’s domain).

Default: true

const config: PerimeterXConfigurations = {
  // ...
  px_first_party_enabled: false,
  // ...
}

px_bypass_monitor_header

When enabling the enforcer for the first time, it is recommended to do so in monitor mode to collect data before actually starting to block user requests. Prior to switching the module mode to active_blocking entirely, it's also crucial to verify that the full blocking flow works as expected. This feature activates the full blocking flow even while in monitor mode if a particular header is present on the request.

Default: Empty

const config: PerimeterXConfigurations = {
  // ...
  px_bypass_monitor_header: 'x-px-block',
  // ...
}

px_enforced_routes

Customers may want certain, but not all, endpoints to be enforced by PerimeterX, even when the Enforcer is in Monitor Mode. These routes will go through the full enforcer workflow, including blocking requests when necessary. That is, even when the enforcer is in Monitor Mode, these defined routes will behave as if in Blocking Mode.

Default: []

const config: PerimeterXConfigurations = {
  // ...
  px_enforced_routes: ['/enforced_route'],
  // ...
}

px_monitored_routes

Enables certain endpoints to be monitored rather than enforced by PerimeterX, even when the enforcer is in active blocking mode.

Default: []

const config: PerimeterXConfigurations = {
  // ...
  px_monitored_routes: ['/monitored_route'],
  // ...
}

px_sensitive_headers

The PerimeterX detector requires information about the HTTP request as part of its bot detections. Certain headers may contain information that should not be forwarded to other servers, including the PerimeterX backend. Configuring these header names as sensitive headers will remove these headers from requests sent to other backends by PerimeterX.

Default: ['cookie', 'cookies']

const config: PerimeterXConfigurations = {
  // ...
  px_sensitive_headers: ['x-sensitive-token'],
  // ...
}

px_sensitive_routes

Certain endpoints may require more stringent protection from bot attacks (e.g., endpoints that execute payments or handle personal information). In these cases, routes can be configured as sensitive routes, meaning risk API calls will be made even if the request contains a valid, unexpired cookie.

Default: []

const config: PerimeterXConfigurations = {
  // ...
  px_sensitive_routes: ['/login', '/checkout'],
  // ...
}

px_filter_by_extension

PerimeterX does not enforce static assets such as images and documents. To prevent unnecessary API calls to PerimeterX servers and needless computation, the enforcer filters all requests with a valid static file extension. Filtering by extension only applies to HTTP requests with methods GET and HEAD.

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 config: PerimeterXConfigurations = {
  // ...
  px_filter_by_extension: ['.css', '.js', '.png'],
  // ...
}

px_filter_by_http_method

PerimeterX does not enforce static assets such as images and documents. To prevent unnecessary API calls to PerimeterX servers and needless computation, the enforcer filters all requests with a valid static file extension.

Default: []

const config: PerimeterXConfigurations = {
  // ...
  px_filter_by_http_method: ['OPTIONS'],
  // ...
}

px_filter_by_ip

Filters out requests according to their IP address, avoiding unnecessary traffic in the enforcer verification flow and reducing operation costs.

Default: []

const config: PerimeterXConfigurations = {
  // ...
  px_filter_by_ip: ['1.1.1.1', '2.2.2.2/8'],
  // ...
}

px_filter_by_route

Routes (endpoints) specified here will not be blocked, regardless of the score they receive. A client request to an allowed route will not generate any risk or async activities.

Default: []

const config: PerimeterXConfigurations = {
  // ...
  px_filter_by_route: ['/filtered_route'],
  // ...
}

px_filter_by_user_agent

Filters out requests according to their user agent value, avoiding unnecessary traffic in the enforcer verification flow and reducing operation costs.

Default: []

const config: PerimeterXConfigurations = {
  // ...
  px_filter_by_user_agent: ['filtered_UA'],
  // ...
}

px_css_ref

Provides a way to include an additional custom .css file to add to the block page.

Default: Empty

const config: PerimeterXConfigurations = {
  // ...
  px_css_ref: 'https://www.example.com/custom_style.css',
  // ...
}

px_js_ref

Provides a way to include a custom JS script to add to the block page. This script will run after the default JS scripts.

Default: Empty

const config: PerimeterXConfigurations = {
  // ...
  px_js_ref: 'https://www.example.com/custom_script.js',
  // ...
}

px_custom_logo

Adds a custom logo to the block page that will be shown to users. This aligns the block page with the customer's brand.

Default: Empty

const config: PerimeterXConfigurations = {
  // ...
  px_custom_logo: 'https://www.example.com/custom_logo.png',
  // ...
}

px_custom_cookie_header

The Enforcer attempts to extract the PerimeterX cookies from the 'Cookie' header. If the PerimeterX cookies are transferred on a header other than 'Cookies', the header name should be configured here.

Default: "x-px-cookies"

const config: PerimeterXConfigurations = {
  // ...
  px_custom_cookie_header: 'x-px-cookie',
  // ...
}

px_user_agent_max_length

The maximum length of the User-Agent header. If the user agent header value exceeds this length, it will be truncated to this length prior to processing.

Default: 8528

const config: PerimeterXConfigurations = {
  // ...
  px_user_agent_max_length: 2048,
  // ...
}

px_additional_activity_handler

The additional activity handler is a custom function passed to the enforcer. The enforcer runs this callback after sending page_requested or block activity to the collector, and before forwarding the request to the next step in the pipeline. A common use case of the additional activity handler is to set the score as a variable or header. Then the application can read the score and do what is defined within the application's logic.

  • Parameters
    • config: PerimeterXConfigurations
    • context: IContext
  • Returns void | Promise

Default: null

const config: PerimeterXConfigurations = {
  // ...
  px_additional_activity_handler: (
      config: PerimeterXConfigurations,
      context: IContext,
  ): void => {
      context.requestData.request.headers.set('x-px-score', `${context.score}`);
      context.requestData.request.headers.set('x-px-rtt', `${context.riskApiData.riskRtt}`);
  },
  // ...
}

px_enrich_custom_parameters

This custom function enriches activities sent from the enforcer to PerimeterX with additional custom data. This data can include user information, session IDs, or other data that PerimeterX should have access to. These custom parameters are defined by a configurable function that must return an object that contains these custom parameters. There is a limit of 10 custom parameters.

  • Parameters
    • config: PerimeterXConfigurations
    • httpRequest: IIncomingRequest
  • Returns CustomParameters | Promise

Default: null

import {IIncomingRequest} from "perimeterx-js-core";

const config: PerimeterXConfigurations = {
   // ...
   px_enrich_custom_parameters: async (
           config: PerimeterXConfigurations,
           httpRequest: IIncomingRequest,
   ): CustomParameters | Promise<CustomParameters> => {
       try {
           const body = httpRequest.method === 'POST' ? await httpRequest.json() : null;
           return {
               custom_param1: 'hardcoded value',
               custom_param2: httpRequest.headers.get('header-name'),
               custom_param3: body?.['body_property']
           };
       } catch (e) {
           return null;
       }
   },
   // ...
}