From 95283c1e7e1f99775aa676ded8a3d520deb2c940 Mon Sep 17 00:00:00 2001 From: Alex Bluvstein Date: Thu, 22 Nov 2018 17:17:01 +0200 Subject: [PATCH 1/6] Added monitor mode --- perimeterx/middleware.py | 7 ++++--- perimeterx/px_constants.py | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/perimeterx/middleware.py b/perimeterx/middleware.py index 84ead6c..bd795e5 100644 --- a/perimeterx/middleware.py +++ b/perimeterx/middleware.py @@ -6,7 +6,7 @@ import px_blocker import px_api import Cookie - +import px_constants class PerimeterX(object): def __init__(self, app, config=None): @@ -27,7 +27,8 @@ def __init__(self, app, config=None): 'custom_logo': None, 'css_ref': None, 'js_ref': None, - 'is_mobile': False + 'is_mobile': False, + 'monitor_mode': px_constants.MONITOR_MODE_BLOCKING } self.config = dict(self.config.items() + config.items()) @@ -92,7 +93,7 @@ def handle_verification(self, ctx, config, environ, start_response): if config.get('custom_block_handler', False): px_activities_client.send_block_activity(ctx, config) return config['custom_block_handler'](ctx, start_response) - elif config.get('module_mode', 'active_monitoring') == 'active_blocking': + elif config.get('module_mode', px_constants.MONITOR_MODE_MONITOR) == px_constants.MONITOR_MODE_BLOCKING: return self.PXBlocker.handle_blocking(ctx=ctx, config=config, start_response=start_response) else: return self.pass_traffic(environ, start_response, ctx) diff --git a/perimeterx/px_constants.py b/perimeterx/px_constants.py index 416b856..7c1feb0 100644 --- a/perimeterx/px_constants.py +++ b/perimeterx/px_constants.py @@ -16,4 +16,6 @@ CLIENT_FP_PATH = 'init.js' CAPTCHA_FP_PATH = 'captcha' XHR_FP_PATH = 'xhr' +MONITOR_MODE_BLOCKING = 'active_blocking' +MONITOR_MODE_MONITOR = 'monitor' From c13e72f9cabacd77b6e8e4c814a1b867d671f028 Mon Sep 17 00:00:00 2001 From: Alex Bluvstein Date: Sat, 24 Nov 2018 11:01:55 +0200 Subject: [PATCH 2/6] Added module mode, risk_rtt and simulated block --- perimeterx/middleware.py | 7 +++---- perimeterx/px_activities_client.py | 11 ++++++++++- perimeterx/px_api.py | 7 +++++++ perimeterx/px_constants.py | 2 ++ perimeterx/px_context.py | 3 ++- perimeterx/px_httpc.py | 6 ------ 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/perimeterx/middleware.py b/perimeterx/middleware.py index bd795e5..bd1e998 100644 --- a/perimeterx/middleware.py +++ b/perimeterx/middleware.py @@ -16,7 +16,7 @@ def __init__(self, app, config=None): 'blocking_score': 60, 'debug_mode': False, 'module_version': 'Python SDK v1.0.3', - 'module_mode': 'active_monitoring', + 'module_mode': 'monitor', 'perimeterx_server_host': 'sapi.perimeterx.net', 'captcha_enabled': True, 'server_calls_enabled': True, @@ -28,15 +28,14 @@ def __init__(self, app, config=None): 'css_ref': None, 'js_ref': None, 'is_mobile': False, - 'monitor_mode': px_constants.MONITOR_MODE_BLOCKING - } + 'monitor_mode': px_constants.MONITOR_MODE_MONITOR, + } self.config = dict(self.config.items() + config.items()) self.config['logger'] = logger = Logger(self.config['debug_mode']) if not config['app_id']: logger.error('PX App ID is missing') raise ValueError('PX App ID is missing') - # if APP_ID is not set, use the deafult perimeterx server - else, use the appid specific sapi. self.config['perimeterx_server_host'] = 'sapi.perimeterx.net' if self.config['app_id'] == 'PX_APP_ID' else 'sapi-' + self.config['app_id'].lower() + '.perimeterx.net' if not config['auth_token']: diff --git a/perimeterx/px_activities_client.py b/perimeterx/px_activities_client.py index 0c4556a..119e737 100644 --- a/perimeterx/px_activities_client.py +++ b/perimeterx/px_activities_client.py @@ -2,6 +2,7 @@ import px_httpc import threading import traceback, sys +import px_constants ACTIVITIES_BUFFER = [] CONFIG = {} @@ -66,5 +67,13 @@ def send_block_activity(ctx, config): send_to_perimeterx('block', ctx, config, { 'block_score': ctx.get('risk_score'), 'client_uuid': ctx.get('uuid'), - 'block_reason': ctx.get('block_reason') + 'block_reason': ctx.get('block_reason'), + 'http_method' : ctx.get('http_method'), + 'http_version': ctx.get('http_version'), + 'px_cookie': ctx.get('decoded_cookie'), + 'risk_rtt': ctx.get('risk_rtt'), + #'cookie_origin':, + 'module_version': px_constants.MODULE_VERSION, + 'simulated_block': config.get('monitor_mode') + }) diff --git a/perimeterx/px_api.py b/perimeterx/px_api.py index 8208f33..f19b8ef 100644 --- a/perimeterx/px_api.py +++ b/perimeterx/px_api.py @@ -1,5 +1,7 @@ import sys import px_httpc +import time + def send_risk_request(ctx, config): @@ -11,12 +13,17 @@ def verify(ctx, config): logger = config['logger'] logger.debug("PXVerify") try: + start = time.time() response = send_risk_request(ctx, config) + risk_rtt = time.time() - start + logger.debug('Risk call took ' + str(risk_rtt) + 'ms') + if response: score = response['score'] ctx['score'] = score ctx['uuid'] = response['uuid'] ctx['block_action'] = response['action'] + ctx['risk_rtt'] = risk_rtt if score >= config['blocking_score']: logger.debug("PXVerify block score threshold reached, will initiate blocking") ctx['block_reason'] = 's2s_high_score' diff --git a/perimeterx/px_constants.py b/perimeterx/px_constants.py index 7c1feb0..98cdfa4 100644 --- a/perimeterx/px_constants.py +++ b/perimeterx/px_constants.py @@ -19,3 +19,5 @@ MONITOR_MODE_BLOCKING = 'active_blocking' MONITOR_MODE_MONITOR = 'monitor' + +MODULE_VERSION = 'Python WSGI Module' diff --git a/perimeterx/px_context.py b/perimeterx/px_context.py index 21fad3f..7df1808 100644 --- a/perimeterx/px_context.py +++ b/perimeterx/px_context.py @@ -57,6 +57,7 @@ def build_context(environ, config): 'uri': uri, 'hostname': hostname, 'px_cookies': px_cookies, - 'cookie_names': request_cookie_names + 'cookie_names': request_cookie_names, + 'risk_rtt': 0 } return ctx diff --git a/perimeterx/px_httpc.py b/perimeterx/px_httpc.py index 33282ee..be6391c 100644 --- a/perimeterx/px_httpc.py +++ b/perimeterx/px_httpc.py @@ -1,6 +1,5 @@ import httplib import json -import time http_client = None @@ -17,17 +16,12 @@ def send(uri, body, config): 'Content-Type': 'application/json' } try: - start = time.time() http_client.request('POST', uri, body=json.dumps(body), headers=headers) r = http_client.getresponse() - if r.status != 200: logger.error('error posting server to server call ' + r.reason) return False - - logger.debug('Server call took ' + str(time.time() - start) + 'ms') response_body = r.read() - return json.loads(response_body) except httplib.HTTPException: init(config) From 0a738902c69fe90626e1e75bdda644f1a2caee0d Mon Sep 17 00:00:00 2001 From: Alex Bluvstein Date: Sat, 24 Nov 2018 12:31:42 +0200 Subject: [PATCH 3/6] Changed the name --- perimeterx/middleware.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/perimeterx/middleware.py b/perimeterx/middleware.py index bd1e998..9d76903 100644 --- a/perimeterx/middleware.py +++ b/perimeterx/middleware.py @@ -28,7 +28,7 @@ def __init__(self, app, config=None): 'css_ref': None, 'js_ref': None, 'is_mobile': False, - 'monitor_mode': px_constants.MONITOR_MODE_MONITOR, + 'monitor_mode': px_constants.MODULE_MODE_MONITOR, } self.config = dict(self.config.items() + config.items()) @@ -92,7 +92,7 @@ def handle_verification(self, ctx, config, environ, start_response): if config.get('custom_block_handler', False): px_activities_client.send_block_activity(ctx, config) return config['custom_block_handler'](ctx, start_response) - elif config.get('module_mode', px_constants.MONITOR_MODE_MONITOR) == px_constants.MONITOR_MODE_BLOCKING: + elif config.get('module_mode', px_constants.MODULE_MODE_MONITOR) == px_constants.MODULE_MODE_BLOCKING: return self.PXBlocker.handle_blocking(ctx=ctx, config=config, start_response=start_response) else: return self.pass_traffic(environ, start_response, ctx) From 094bfc20a2e744ce32807bdfe3147edfd5009eb3 Mon Sep 17 00:00:00 2001 From: Alex Bluvstein Date: Sat, 24 Nov 2018 12:32:24 +0200 Subject: [PATCH 4/6] Changed the name --- perimeterx/px_constants.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/perimeterx/px_constants.py b/perimeterx/px_constants.py index 98cdfa4..09a4d20 100644 --- a/perimeterx/px_constants.py +++ b/perimeterx/px_constants.py @@ -16,8 +16,7 @@ CLIENT_FP_PATH = 'init.js' CAPTCHA_FP_PATH = 'captcha' XHR_FP_PATH = 'xhr' -MONITOR_MODE_BLOCKING = 'active_blocking' -MONITOR_MODE_MONITOR = 'monitor' - +MODULE_MODE_BLOCKING = 'active_blocking' +MODULE_MODE_MONITOR = 'monitor' MODULE_VERSION = 'Python WSGI Module' From 83d8425a533cf64e31bffebdb8eb0ae0c79ab1d4 Mon Sep 17 00:00:00 2001 From: Alex Bluvstein Date: Sat, 24 Nov 2018 13:14:31 +0200 Subject: [PATCH 5/6] Changed momotproimg mode to module mode --- perimeterx/middleware.py | 4 ++-- perimeterx/px_activities_client.py | 2 +- perimeterx/px_constants.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/perimeterx/middleware.py b/perimeterx/middleware.py index 9d76903..1bbd902 100644 --- a/perimeterx/middleware.py +++ b/perimeterx/middleware.py @@ -28,7 +28,7 @@ def __init__(self, app, config=None): 'css_ref': None, 'js_ref': None, 'is_mobile': False, - 'monitor_mode': px_constants.MODULE_MODE_MONITOR, + 'monitor_mode': px_constants.MODULE_MODE_MONITORING, } self.config = dict(self.config.items() + config.items()) @@ -92,7 +92,7 @@ def handle_verification(self, ctx, config, environ, start_response): if config.get('custom_block_handler', False): px_activities_client.send_block_activity(ctx, config) return config['custom_block_handler'](ctx, start_response) - elif config.get('module_mode', px_constants.MODULE_MODE_MONITOR) == px_constants.MODULE_MODE_BLOCKING: + elif config.get('module_mode') == px_constants.MODULE_MODE_BLOCKING: return self.PXBlocker.handle_blocking(ctx=ctx, config=config, start_response=start_response) else: return self.pass_traffic(environ, start_response, ctx) diff --git a/perimeterx/px_activities_client.py b/perimeterx/px_activities_client.py index 119e737..3e06d64 100644 --- a/perimeterx/px_activities_client.py +++ b/perimeterx/px_activities_client.py @@ -74,6 +74,6 @@ def send_block_activity(ctx, config): 'risk_rtt': ctx.get('risk_rtt'), #'cookie_origin':, 'module_version': px_constants.MODULE_VERSION, - 'simulated_block': config.get('monitor_mode') + 'simulated_block': config.get('monitor_mode') is px_constants.MODULE_MODE_MONITORING }) diff --git a/perimeterx/px_constants.py b/perimeterx/px_constants.py index 09a4d20..926843a 100644 --- a/perimeterx/px_constants.py +++ b/perimeterx/px_constants.py @@ -17,6 +17,6 @@ CAPTCHA_FP_PATH = 'captcha' XHR_FP_PATH = 'xhr' MODULE_MODE_BLOCKING = 'active_blocking' -MODULE_MODE_MONITOR = 'monitor' +MODULE_MODE_MONITORING = 'monitor' MODULE_VERSION = 'Python WSGI Module' From af36ee4bfbdbce5588c4d3d31089bf12e630d562 Mon Sep 17 00:00:00 2001 From: Alex Bluvstein Date: Sat, 24 Nov 2018 13:24:45 +0200 Subject: [PATCH 6/6] Fixed according to PR comments --- perimeterx/middleware.py | 1 - perimeterx/px_constants.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/perimeterx/middleware.py b/perimeterx/middleware.py index 1bbd902..b67fd7f 100644 --- a/perimeterx/middleware.py +++ b/perimeterx/middleware.py @@ -15,7 +15,6 @@ def __init__(self, app, config=None): self.config = { 'blocking_score': 60, 'debug_mode': False, - 'module_version': 'Python SDK v1.0.3', 'module_mode': 'monitor', 'perimeterx_server_host': 'sapi.perimeterx.net', 'captcha_enabled': True, diff --git a/perimeterx/px_constants.py b/perimeterx/px_constants.py index 926843a..948d8d8 100644 --- a/perimeterx/px_constants.py +++ b/perimeterx/px_constants.py @@ -19,4 +19,4 @@ MODULE_MODE_BLOCKING = 'active_blocking' MODULE_MODE_MONITORING = 'monitor' -MODULE_VERSION = 'Python WSGI Module' +MODULE_VERSION = 'Python WSGI Module v2.0.0'