|
| 1 | + |
| 2 | + |
| 3 | +[PerimeterX](http://www.perimeterx.com) Python WSGI Middleware |
| 4 | +============================================================= |
| 5 | +> The PerimeterX Python Middleware is supported by all [WSGI based frameworks](https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface#WSGI-compatible_applications_and_frameworks) |
| 6 | +
|
| 7 | +Table of Contents |
| 8 | +----------------- |
| 9 | + |
| 10 | +- [Usage](#usage) |
| 11 | + * [Dependencies](#dependencies) |
| 12 | + * [Installation](#installation) |
| 13 | + * [Basic Usage Example](#basic-usage) |
| 14 | +- [Configuration](#configuration) |
| 15 | + * [Blocking Score](#blocking-score) |
| 16 | + * [Custom Block Action](#custom-block) |
| 17 | + * [Enable/Disable Captcha](#captcha-support) |
| 18 | + * [Extracting Real IP Address](#real-ip) |
| 19 | + * [Filter Sensitive Headers](#sensitive-headers) |
| 20 | + * [API Timeouts](#api-timeout) |
| 21 | + * [Send Page Activities](#send-page-activities) |
| 22 | + * [Debug Mode](#debug-mode) |
| 23 | +- [Contributing](#contributing) |
| 24 | + * [Tests](#tests) |
| 25 | + |
| 26 | +<a name="Usage"></a> |
| 27 | + |
| 28 | +<a name="dependencies"></a> Dependencies |
| 29 | +---------------------------------------- |
| 30 | + |
| 31 | +- [Python v2.7](https://www.python.org/download/releases/2.7/) |
| 32 | + |
| 33 | + |
| 34 | + |
| 35 | + |
| 36 | +<a name="installation"></a> Installation |
| 37 | +---------------------------------------- |
| 38 | + |
| 39 | +Installation can be done using composer |
| 40 | + |
| 41 | +```sh |
| 42 | +$ pip install perimeterx |
| 43 | +``` |
| 44 | + |
| 45 | +### <a name="basic-usage"></a> Basic Usage Example |
| 46 | +```python |
| 47 | +from perimeterx.middleware import PerimeterX |
| 48 | + |
| 49 | +px_config = { |
| 50 | + 'app_id': 'APP_ID', |
| 51 | + 'cookie_key': 'COOKIE_KEY', |
| 52 | + 'auth_token': 'AUTH_TOKEN', |
| 53 | + 'blocking_score': 70 |
| 54 | +} |
| 55 | + |
| 56 | +application = get_wsgi_application() |
| 57 | +application = PerimeterX(application, px_config) |
| 58 | +``` |
| 59 | +### <a name="configuration"></a> Configuration Options |
| 60 | + |
| 61 | +#### Configuring Required Parameters |
| 62 | + |
| 63 | +Configuration options are set in `px_config` |
| 64 | + |
| 65 | +#### Required parameters: |
| 66 | + |
| 67 | +- app_id |
| 68 | +- cookie_key |
| 69 | +- auth_token |
| 70 | + |
| 71 | +#### <a name="blocking-score"></a> Changing the Minimum Score for Blocking |
| 72 | + |
| 73 | +**default:** 70 |
| 74 | + |
| 75 | +```python |
| 76 | +px_config = { |
| 77 | + .. |
| 78 | + 'blocking_score': 75 |
| 79 | + .. |
| 80 | +} |
| 81 | +``` |
| 82 | + |
| 83 | +#### <a name="custom-block"></a> Custom Blocking Actions |
| 84 | +Setting a custom block handler customizes is done by setting `custom_block_handler` with a user function named on the `px_config`. |
| 85 | + |
| 86 | +Custom handler should contain the action that is taken when a user visits with a high score. Common customizations are to present a reCAPTHA or custom branded block page. |
| 87 | + |
| 88 | +**default:** return HTTP status code 403 and serve the Perimeterx block page. |
| 89 | + |
| 90 | +```python |
| 91 | +def custom_block_handler(ctx, start_response): |
| 92 | + start_response('403 Forbidden', [('Content-Type', 'text/html')]) |
| 93 | + return ['You have been blocked'] |
| 94 | + |
| 95 | + |
| 96 | +px_config = { |
| 97 | + .. |
| 98 | + 'custom_block_handler': custom_block_handler, |
| 99 | + .. |
| 100 | +} |
| 101 | + |
| 102 | +application = get_wsgi_application() |
| 103 | +application = PerimeterX(application, px_config) |
| 104 | +``` |
| 105 | + |
| 106 | +###### Examples |
| 107 | + |
| 108 | +**Serve a Custom HTML Page** |
| 109 | + |
| 110 | +```python |
| 111 | +def custom_block_handler(ctx, start_response): |
| 112 | + block_score = ctx.get('risk_score') |
| 113 | + block_uuid = ctx.get('uuid') |
| 114 | + full_url = ctx.get('full_url') |
| 115 | + |
| 116 | + html = '<div>Access to ' + full_url + ' has been blocked.</div> ' \ |
| 117 | + '<div>Block reference - ' + uuid + ' </div> ' \ |
| 118 | + '<div>Block score - ' + $block_score + '</div>' |
| 119 | + |
| 120 | + start_response('403 Forbidden', [('Content-Type', 'text/html')]) |
| 121 | + return [html] |
| 122 | +}; |
| 123 | + |
| 124 | +application = get_wsgi_application() |
| 125 | +application = PerimeterX(application, px_config) |
| 126 | +``` |
| 127 | + |
| 128 | +#### <a name="module-score"></a> Module Mode |
| 129 | + |
| 130 | +**default:** `active_monitoring` |
| 131 | + |
| 132 | +**Possible Values:** - `['active_monitoring', 'active_blocking', 'inactive']` |
| 133 | + |
| 134 | +```python |
| 135 | +px_config = { |
| 136 | + .. |
| 137 | + 'module_mode': 'active_blocking' |
| 138 | + .. |
| 139 | +} |
| 140 | +``` |
| 141 | + |
| 142 | +#### <a name="captcha-support"></a>Enable/disable captcha in the block page |
| 143 | + |
| 144 | +By enabling captcha support, a captcha will be served as part of the block page giving real users the ability to answer, get score clean up and passed to the requested page. |
| 145 | + |
| 146 | +**default: True** |
| 147 | + |
| 148 | +```python |
| 149 | +px_config = { |
| 150 | + .. |
| 151 | + 'captcha_enabled': True |
| 152 | + .. |
| 153 | +} |
| 154 | +``` |
| 155 | + |
| 156 | +#### <a name="real-ip"></a>Extracting the Real User IP Address |
| 157 | + |
| 158 | +In order to evaluate user's score properly, the PerimeterX module |
| 159 | +requires the real socket ip (client IP address that created the HTTP |
| 160 | +request). The user ip can be returned to the PerimeterX module using a custom user function defined on `px_config`. |
| 161 | + |
| 162 | +**default value:** `environ.get('REMOTE_ADDR')` |
| 163 | + |
| 164 | +```python |
| 165 | +def ip_handler(environ): |
| 166 | + for key in environ.keys(): |
| 167 | + if key == 'HTTP_X_FORWARDED_FOR': |
| 168 | + xff = environ[key].split(' ')[1] |
| 169 | + return xff |
| 170 | + return '1.2.3.4' |
| 171 | + |
| 172 | +px_config = { |
| 173 | + .. |
| 174 | + 'ip_handler': ip_handler, |
| 175 | + .. |
| 176 | +} |
| 177 | + |
| 178 | + |
| 179 | +application = get_wsgi_application() |
| 180 | +application = PerimeterX(application, px_config) |
| 181 | +``` |
| 182 | + |
| 183 | +#### <a name="sensitive-headers"></a> Filter sensitive headers |
| 184 | + |
| 185 | +A user can define a list of sensitive header he want to prevent from being send to perimeterx servers (lowered case header name), filtering cookie header for privacy is set by default and will be overridden if a user set the configuration |
| 186 | + |
| 187 | +**default value:** `['cookie', 'cookies']` |
| 188 | + |
| 189 | +```python |
| 190 | +px_config = { |
| 191 | + .. |
| 192 | + 'sensitive_headers': ['cookie', 'cookies', 'secret-header'] |
| 193 | + .. |
| 194 | +} |
| 195 | +``` |
| 196 | + |
| 197 | +#### <a name="api-timeout"></a>API Timeouts |
| 198 | + |
| 199 | +Control the timeouts for PerimeterX requests. The API is called when the risk cookie does not exist, or is expired or invalid. |
| 200 | + |
| 201 | +API Timeout in seconds (float) to wait for the PerimeterX server API response. |
| 202 | + |
| 203 | + |
| 204 | +**default:** 1 |
| 205 | + |
| 206 | +```python |
| 207 | +px_config = { |
| 208 | + .. |
| 209 | + 'api_timeout': 2 |
| 210 | + .. |
| 211 | +} |
| 212 | +``` |
| 213 | + |
| 214 | + |
| 215 | +#### <a name="send-page-activities"></a> Send Page Activities |
| 216 | + |
| 217 | +Boolean flag to enable or disable sending activities and metrics to |
| 218 | +PerimeterX on each page request. Enabling this feature will provide data |
| 219 | +that populates the PerimeterX portal with valuable information such as |
| 220 | +amount requests blocked and API usage statistics. |
| 221 | + |
| 222 | +**default:** False |
| 223 | + |
| 224 | +```python |
| 225 | +px_config = { |
| 226 | + .. |
| 227 | + 'send_page_activities': True |
| 228 | + .. |
| 229 | +} |
| 230 | +``` |
| 231 | + |
| 232 | +#### <a name="debug-mode"></a> Debug Mode |
| 233 | + |
| 234 | +Enables debug logging |
| 235 | + |
| 236 | +**default:** False |
| 237 | + |
| 238 | +```python |
| 239 | +px_config = { |
| 240 | + .. |
| 241 | + 'debug_mode': True |
| 242 | + .. |
| 243 | +} |
| 244 | +``` |
| 245 | +<a name="contributing"></a> Contributing |
| 246 | +---------------------------------------- |
0 commit comments