cheq-rti-wsgi-middleware

cheq middlewares for wsgi application


License
MIT
Install
pip install cheq-rti-wsgi-middleware==0.0.3

Documentation

Cheq-Python-Middlewares

Cheq-RTI-WSGI-Middleware

CHEQ Real Time Interception middleware for Python 3 wsgi application

Features

Installation

$ pip install cheq-rti-wsgi-middleware

Real time interception

Real-Time Interception (RTI) supports API calls to provide detection of invalid traffic (IVT) to your site, in absolute real-time. RTI will intercept IVT to prevent invalid visitors from harming your conversion efforts.

Configuration

Required configuration

API key

Available on the Paradome platform under “Management -> RTI”

options = {
    ...
    'api_key': '11abc111-aa11-11aa-1111-11a11a11111'
    ...
}
Tag hash

Appears in your CHEQ tag.

options = {
    ...
    'tag_hash': 'c99651e7936e27743ce51c728492aac9'
    ...
}
API endpoint

The nearest API endpoint to your server. Must be the same region as your tag domain.
Select the appropriate endpoint:

options = {
    ...
    'api_endpoint': 'https://rti-eu-west1.cheqzone.com'
    ...
}

Optional configuration

Mode
  • monitoring - Will not perform any action

  • blocking - Will block Invalid traffic or redirect them to a different url (defind in Redirect URL).

The default value will be monitoring.

options = {
    ...
    'mode': 'blocking'
    ...
}
Event type
  • route_to_event_type - A dictionary of routes as keys and cheq event type as value.
    Default page_load will be used as event type
options = {
    ...
    'route_to_event_type': {
        '/': 'page_load',
        '/subscribe': 'subscribe',
        .....
        .....
    }
    ...
}
Threat type codes

Threat types are devided to two groups:

  1. Block/Redirect - traffic detected as threat types in this group would be blocked or redirected to a different page (defind in Redirect URL.
    Default threat type codes for this group: 2,3,6,7,10,11,16,18.

  2. Captcha - threat type codes in this group would be reffered to Callback function.
    Default threat type codes for this group: 4,5,13,14,15,17. Threat type must be unique for each list.

options = {
    ...
    'invalid_block_redirect_codes': [2, 3, 6, 7, 10, 11, 16, 18],
    'invalid_captcha_codes': [4, 5, 13, 14, 15, 17]
    ...
};
Redirect URL

A URL you would like to redirect invalid users to.

If it is empty the response will be status code 403 and the user will be blocked.

options = {
    ...
     'redirect_url': 'https://invalid-user.com'
    ...
}
Callback function

A custom callback option, for instance to redirect to captcha page. If it is empty, will use start_response to route.

def callback(app, environ, start_response):
     #do somthing or call app(environ, start_response)
     
options = {
    ...
     'callback': callback 
    ...
}
Ja3

Recommended - A function that extracts ja3 fingerprint from the request.
SSL/TLS client fingerprints

from urllib.parse import urlparse
from urllib.parse import parse_qs

def get_ja3(request):
        parsed_url = urlparse(reuest.url)
        captured_value = parse_qs(parsed_url.query)['ja3'][0] 
options = {
    ... 
    'get_ja3': get_ja3
    ...
}
Resource type

A function to get the response content-type header.

This is recommended to improve detection.

def get_resource_type(request):
    if request.headers.environ['REQUEST_METHOD'] == 'POST'):
        return 'application/json'
    elif request.pth == '/':
        return 'text/html'

options = {
  ...
  'get_resource_type': get_resource_type
  ...
}
IP header

Specify a trusted IP header to be used as client IP

options = {
  ...
  'trusted_ip_header': 'client-ip'
  ...
};
URI Exclusion

An array of regular expressions or path that will be excluded

options = {
  ...
  'uri_exclusion': ['/about', '/careers']
  ...
};
Timeout

Optional timeout in milliseconds, if absent value will be set to 100 milliseconds.

options = {
    ...
     'timeout': 1000 // one second
    ...
}
Custom event name

In case a custom event name is used, this function extracts the name of the custom event.

from urllib.parse import urlparse
from urllib.parse import parse_qs

def get_channel(request):
        parsed_url = urlparse(reuest.url)
        captured_value = parse_qs(parsed_url.query)['channel'][0] 
options = {
    ...
     'get_channel': get_channel
    ...
}

Usage example

Flask
from flask import Flask
from cheq_wsgi_middlewares.RtiWsgiMiddleware import RtiMiddleware

api_key = "62fdc812-be58-492f-9417-66a1f22b4da1"
tag_hash = "5f863bea211c957865e067b148f2471b"
app = Flask(__name__)


options = {
    'app': app.wsgi_app,
    'api_key': "62fdc812-be58-492f-9417-66a1f22b4da1",
    'tag_hash': "5f863bea211c957865e067b148f2471b",
    'api_endpoint': 'https://rti-us-east-1.cheqzone.com',
    'route_to_event_type': dict(),
    'mode': 'blocking',
    'uri_exclusion': [],
    'invalid_block_redirect_codes': [],
    'invalid_captcha_codes': [],
    'trusted_ip_header': 'Client-Ip'

}


app.wsgi_app = RtiMiddleware(options)


@app.route("/")
def index():
    return "Hello World"


if __name__ == '__main__':
    app.run('0.0.0.0', 8080)
Django
from django.core.wsgi import get_wsgi_application
from cheq_wsgi_middlewares.RtiWsgiMiddleware import RtiMiddleware
import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hellodjango.settings")
application = get_wsgi_application()

options = {
    'app': application,
    'api_key': "62fdc812-be58-492f-9417-66a1f22b4da1",
    'tag_hash': "5f863bea211c957865e067b148f2471b",
    'api_endpoint': 'https://rti-us-east-1.cheqzone.com',
    'route_to_event_type': dict(),
    'mode': 'blocking',
    'uri_exclusion': [],
    'invalid_block_redirect_codes': [],
    'invalid_captcha_codes': [],
    'trusted_ip_header': 'Client-Ip'

}


application = RtiMiddleware(options)