GithubHelp home page GithubHelp logo

isabella232 / perimeterx-kong-plugin Goto Github PK

View Code? Open in Web Editor NEW

This project forked from perimeterx/perimeterx-kong-plugin

0.0 0.0 0.0 50 KB

PerimeterX Kong plugin

License: MIT License

Shell 12.29% Lua 75.57% Dockerfile 12.14%

perimeterx-kong-plugin's Introduction

image

PerimeterX Kong Plugin

Table of Contents

Getting Started

Dependencies

To install package dependecies on Ubuntu run:

sudo apt-get update && sudo apt-get install lua-cjson libnettle6 nettle-dev luarocks luajit libluajit-5.1-dev ca-certificates

All Lua dependecies are automatically fulfilled with Luarocks.

Installation

Installation can be done using luarocks.

$ luarocks install kong-plugin-perimeterx

Manual installation can accomplished by downoading the sources for this repository and running sudo make install.

Additional steps for installing on Amazon Linux


For Nginx+:

Install the lua modules provided by the Nginx team via yum as shown below as well as the CA certificates bundle which will be required when you configure Nginx.

yum -y install nginx-plus-module-lua ca-certificates.noarch

Download and compile nettle.

Side note: Use the version neccessary for your environment.

yum -y install m4 # prerequisite for nettle
cd /tmp/
wget https://ftp.gnu.org/gnu/nettle/nettle-3.3.tar.gz
tar -xzf nettle-3.3.tar.gz
cd nettle-3.3
./configure
make clean && make install
cd /usr/lib64 && ln -s /usr/local/lib64/libnettle.so .

Make sure to change the path shown below in the "Lua CA Certificates" section as Amazon Linux stores the CA required in a different location than shown.

If running Amazon Linux this is the trusted certificate path please use:

lua_ssl_trusted_certificate "/etc/pki/tls/certs/ca-bundle.crt";

NGINX Configuration File Requirements

Resolver

Add the directive resolver A.B.C.D; in the HTTP section of your configuration. This is required so NGINX can resolve the PerimeterX API DNS name. A.B.C.D is the IP address of your DNS resolver.

Lua CA Certificates

To support TLS to PerimeterX servers, you must point Lua to the trusted certificate location (actual location may differ between Linux distributions).

lua_ssl_trusted_certificate "/etc/ssl/certs/ca-certificates.crt";
lua_ssl_verify_depth 3;

In CentOS/RHEL systems, the CA bundle location may be located at /etc/pki/tls/certs/ca-bundle.crt.

Basic Usage Example

Ensure that you followed the NGINX Configuration Requirements section before proceeding.

Load the plugin by adding perimeterx to the custom_plugins list in your Kong configuration (on each Kong node):

custom_plugins = perimeterx

Note: you can also set this property via its environment variable equivalent: KONG_CUSTOM_PLUGINS.

To apply PerimeterX enforcement, add the perimeterx plugin to your API(s):

curl -i -X POST \
      --url http://localhost:8001/apis/<api-name>/plugins/ \
      --data 'name=perimeterx' \
      --data 'config.px_appId=PX_APP_ID' \
      --data 'config.auth_token=AUTH_TOKEN' \
      --data 'config.cookie_secret=COOKIE_KEY'

You can find your app ID, authentication token, and cookie key under your account's admin section in PerimeterX Portal

Demonstration Docker

To run the demonstration Docker image:

  1. Update the configuration in config/kong.yaml with your PerimeterX app id, cookie secret and auth token.

  2. From the root folder execute ./run-kong.sh.

  3. Navigate to http://127.0.0.1:8000.

  4. You can find the PerimeterX module output in your terminal.

Upgrading

To upgrade to the latest Enforcer version run the following command in luarocks:

luarocks install perimeterx-kong-plugin

Your Enforcer version is now upgraded to the latest enforcer version.

For more information, contact PerimeterX Support.

Configuration Options

Configuring Required Parameters

Configuration options are set via Kong's admin API, as config parameter.

Required parameters:

  • px_appId
  • cookie_secret
  • auth_token

First-Party Configuration

First-Party Mode

First-Party Mode enables the module to send/receive data to/from the sensor, acting as a reverse-proxy for client requests and sensor activities.

First-Party Mode may require additional changes on the JS Sensor Snippet. For more information, refer to the PerimeterX Portal.

--data 'config.first_party_enabled=true'

The following routes must be enabled for First-Party Mode for the PerimeterX Kong plugin:

  • /<PX_APP_ID without PX prefix>/xhr/*

  • /<PX_APP_ID without PX prefix>/init.js

  • /<PX_APP_ID without PX prefix>/captcha/*

  • If the PerimeterX Kong module is enabled on location /, the routes are already open and no action is necessary.

NOTE: The PerimeterX Kong Plugin Configuration Requirements must be completed before proceeding to the next stage of installation.

First-Party JS Snippet

Ensure the PerimeterX Kong Plugin is configured before deploying the PerimeterX First-Party JS Snippet across your site. (Detailed instructions for deploying the PerimeterX First-Party JS Snippet can be found here.)

To deploy the PerimeterX First-Party JS Snippet:

1. Generate the First-Party Snippet
  • Go to Applications >> Snippet.
  • Select First-Party.
  • Select Use Default Routes.
  • Click Copy Snippet to generate the JS Snippet.
2. Deploy the First-Party Snippet
  • Copy the JS Snippet and deploy using a tag manager, or by embedding it globally into your web template for which websites you want PerimeterX to run.

Changing the Minimum Score for Blocking

Default blocking value: 100

--data 'config.blocking_score=60'

Blocking Mode

Default: false

--data 'config.block_enabled=true'

The PerimeterX plugin is enabled in monitor only mode by default.

Setting the blockenabled flag to _true will activate the module to enforce the blocking score. The PerimeterX module will block users crossing the block score threshold that you define. If a user crosses the minimum block score then the user will receive the block page.

Enabled Routes

The enabled routes variable allows you to implicitly define a set of routes which the plugin will be active on. Supplying an empty list will set all application routes as active.

Default: Empty list (all routes)

--data 'config.enabled_routes=/blockhere'

Sensitive Routes

Lists of route prefixes and suffixes. The PerimeterX module will always match the request URI with these lists, and if a match is found will create a server-to-server call, even if the cookie is valid and its score is low.

Default: Empty list

--data 'config.sensitive_routes_prefix=/login,/user/profile'
--data 'config.sensitive_routes_suffix=/download'

Filter sensitive headers

A list of sensitive headers can be configured to prevent specific headers from being sent to PerimeterX servers (lower case header names). Filtering cookie headers for privacy is set by default, and can be overridden on the pxConfig variable.

Default: cookie, cookies

--data 'config.sensitive_headers=cookie,cookies,secret-header'

API Timeout Milliseconds

Note: Controls the timeouts for PerimeterX requests. The API is called when a Risk Cookie does not exist, or is expired or invalid.

API Timeout in milliseconds (float) to wait for the PerimeterX server API response.

Default: 1000

--data 'config.s2s_timeout=250'

Debug Mode

Enables debug logging mode.

Default: false

--data 'config.px_debug=true'

Extracting the real IP address from a request

Note: It is important that the real connection IP is properly extracted when your NGINX server sits behind a load balancer or CDN. The PerimeterX module requires the user's real IP address.

For the PerimeterX NGINX module to see the real user's IP address, you need to set ip_headers, a list of headers to extract the real IP from, ordered by priority.

Default with no predefined header: ngx.var.remote_addr

Example:

--data 'config.ip_headers=X-TRUE-IP,X-Forwarded-For'

Custom Block Page

Customizing block page can be done by 2 methods:

Modifying default block pages

PerimeterX default block page can be modified by injecting custom css, javascript and logo to page

default values: nil

Example:

--data 'config.custom_logo= http://www.example.com/logo.png'
--data 'config.css_ref=http://www.example.com/style.css'
--data 'config.js_ref=http://www.example.com/script.js'
Redirect to a custom block page url

Users can customize the blocking page to meet their branding and message requirements by specifying the URL to a blocking page HTML file. The page can also implement reCaptcha. See NGINX plugin docs for examples of a customized Captcha page.

default: nil

--data 'config.custom_block_url=http://www.example.com/block.html'

Note: This URI MUST be whitelisted under config.whitelist.uri_full to avoid infinite redirects to the block page.

API Protection Mode

For the case where kong is used for API calls and not serving HTML pages, users can set the plugin into API protection mode.

In this mode, when the system decides to block a request, instead of rendering an HTML block/captcha page, it will return a JSON object that contains a URL for optional redirect on the user's client side.

The end user can be redirected this way to a custom captcha page, and after solving the captcha challenge, will be redirected back to the page they came from or to a default location.

Note

When setting the configuration of api_protection_mode to true, users must also set api_protection_block_url which is the address of the custom block page, and api_protection_default_redirect_url which is the default location for redirect after solving captcha.

Example:

--data 'config.api_protection_mode=true'
--data 'config.api_protection_block_url=http://www.example.com/block.html'
--data 'config.api_protection_default_redirect_url=http://www.example.com/home.html'

Response may look like:

{
    "reason": "blocked",
    "redirect_to": "http://www.example.com/block.html?url=aHR0cDovL2xvY2FsaG9zdDo4MDAwLz9nZmQ9ZmdkZmc=&uuid=11a12b80-b40c-11e7-8050-eb8403f523e5&vid=ef77a690-9bc8-11e7-9c31-970ffdcc0e6d"
}

Redirect on Custom URL

The _M.redirect_on_custom_url flag provides 2 options for redirecting users to a block page.

default: false

--data 'config.redirect_on_custom_url=false'

By default, when a user crosses the blocking threshold and blocking is enabled, the user will be redirected to the block page defined by the _M.custom_block_url variable, responding with a 307 (Temporary Redirect) HTTP Response Code.

Setting the flag to flase will consume the page and serve it under the current URL, responding with a 403 (Unauthorized) HTTP Response Code.

Setting the flag to false does not require the block page to include any of the coming examples, as they are injected into the blocking page via the PerimeterX Nginx Enforcer.

Setting the flag to true (enabling redirects) will result with the following URL upon blocking:

http://www.example.com/block.html?url=L3NvbWVwYWdlP2ZvbyUzRGJhcg==&uuid=e8e6efb0-8a59-11e6-815c-3bdad80c1d39&vid=08320300-6516-11e6-9308-b9c827550d47

Note: the url variable is comprised of URL Encoded query parameters (of the originating request) and then both the original path and variables are Base64 Encoded (to avoid collisions with block page query params).

Custom blockpage requirements:

When captcha is enabled, and _M.redirect_on_custom_url is set to true, the block page must include the following:

  • The <body> section must include:
<div id="px-captcha"></div>
<script>
    window._pxAppId = '<APP_ID>';
    window._pxJsClientSrc = 'https://client.perimeterx.net/<APP_ID>/main.min.js';
    window._pxHostUrl = 'https://collector-<APP_ID>.perimeterx.net';
</script>
<script src="https://captcha.px-cdn.net/<APP_ID>/captcha.js?a=c&m=0"></script>

#### Configuration example: ```bash --data 'config.custom_block_url=/block.html' --data 'config.redirect_on_custom_url=true'

Block page implementation full example:

<html>
    <head> </head>
    <body>
        <h1>You are Blocked</h1>
        <p>Try and solve the captcha</p>
        <div id="px-captcha"></div>
        <script>
            window._pxAppId = '<APP_ID>';
            window._pxJsClientSrc = 'https://client.perimeterx.net/<APP_ID>/main.min.js';
            window._pxHostUrl = 'https://collector-<APP_ID>.perimeterx.net';
        </script>
        <script src="https://captcha.px-cdn.net/<APP_ID>/captcha.js?a=c&m=0"></script>
    </body>
    <html></html>
</html>

Multiple App Support

The PerimeterX Enforcer allows for multiple configurations for different apps.

If your PerimeterX account contains several Applications (as defined via the portal), follow these steps to create different configurations for each Application.

Since Kong supports multiple APIs, you can also use the same PerimeterX Application with different configuration for different APIs, but for best results in our detection, it is best to use different Applications and policies for different APIs.

Additional Activity Handler

Adding an additional activity handler is done by setting 'additional_activity_handler' with a user defined function on the 'pxconfig.lua' file. The 'additional_activity_handler' function will be executed before sending the data to the PerimeterX portal.
Because of technical limitations of the Kong platform, you can't set this function using the admin API. Instead, you need to edit the PerimeterX plugin's handler.lua file, and add the function directly to the configuration.

Default: Only send activity to PerimeterX.

function additional_activity_handler(event_type, ctx, details)
	local cjson = require "cjson"
	if (event_type == 'block') then
		logger.warning("PerimeterX " + event_type + " blocked with score: " + ctx.score + "details " + cjson.encode(details))
	else
		logger.info("PerimeterX " + event_type + " details " +  cjson.encode(details))
	end
end

function PXHandler:init_worker(config)
    PXHandler.super.init_worker(self)
    ...
    --add function to pxconfig here
    config.additional_activity_handler = additional_activity_handler
end

Custom Cookie Header

When set, this property specifies a header name which will be used to extract the PerimeterX cookie from, instead of the Cookie header.

NOTE: Using a custom cookie header requires client side integration to be done as well. Please refer to the relevant docs for details.

Default: nil

Example:

--data 'config.config.custom_cookie_header=x-px-cookies'

Whitelisting

Whitelisting (bypassing enforcement) is configured under in the whitelist table.

There are several different types of filters that can be configured.

whitelist_uri_full = { _M.custom_block_url },
whitelist_uri_prefixes = {},
whitelist_uri_suffixes = {'.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'},
whitelist_ip_addresses = {},
whitelist_ua_full = {},
whitelist_ua_sub = {}
  • whitelist_uri_full : for value {'/api_server_full'} - will filter requests to /api_server_full?data=1 but not to /api_server?data=1
  • whitelist_uri_prefixes : for value {'/api_server'} - will filter requests to /api_server_full?data=1 but not to /full_api_server?data=1
  • whitelist_uri_suffixes : for value {'.css'} - will filter requests to /style.css but not to /style.js
  • whitelist_ip_addresses : for value {'192.168.99.1'} - will filter requests coming from any of the listed ips.
  • whitelist_ua_full : for value {'Mozilla/5.0 (compatible; pingbot/2.0; http://www.pingdom.com/)'} - will filter all requests matching this exact UA.
  • whitelist_ua_sub : for value {'GoogleCloudMonitoring'} - will filter requests containing the provided string in their UA.

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

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.

Contributing

The following steps are welcome when contributing to our project.

Fork/Clone

Create a fork of the repository, and clone it locally. Create a branch on your fork, preferably using a descriptive branch name.

Pull Request

After you have completed the process, create a pull request. Please provide a complete and thorough description explaining the changes. Remember, this code has to be read by our maintainers, so keep it simple, smart and accurate.

Thanks

After all, you are helping us by contributing to this project, and we want to thank you for it. We highly appreciate your time invested in contributing to our project, and are glad to have people like you - kind helpers.

perimeterx-kong-plugin's People

Contributors

bendpx avatar ori-gold-px avatar saralumelsky avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.