Advanced Configuration
Data Enrichment
Users can use the additional activity handler to retrieve information for the request using the PXDE (PerimeterX Data Enrichment) object.
First, check that the data enrichment object is verified, then you can access its properties.
MyVerificationHandler.java:
...
public class MyVerificationHandler implements VerificationHandler {
PXConfiguration pxConfig;
VerificationHandler defaultVerificationHandler;
public AutomationVerificationHandler(PXConfiguration pxConfig) throws PXException {
this.pxConfig = pxConfig;
PXClient pxClient = new PXHttpClient(pxConfig);
ActivityHandler activityHandler = new DefaultActivityHandler(pxClient, pxConfig);
this.defaultVerificationHandler = new DefaultVerificationHandler(pxConfig, activityHandler);
}
public boolean handleVerification(PXContext pxContext, HttpServletResponseWrapper httpServletResponseWrapper) throws PXException, IOException {
if (pxContext.isPxdeVerified()) {
JsonNode dataEnrichmentPayload = pxContext.getPxde();
<handle data enrichment payload here>
}
return defaultVerificationHandler.handleVerification(pxContext, httpServletResponseWrapper);
}
}
Then, in your filter:
...
PXConfiguration config = new PXConfiguration.Builder()
...
.build();
PerimeterX enforcer = new PerimeterX(config);
enforcer.setVerificationHandler(new MyVerificationHandler(config));
...
Custom Parameters
With the customParametersProvider
function you can add up to 10 custom parameters to be sent back to HUMAN servers.
When set, the function is called before setting the payload on every request to HUMAN servers.
MyCustomParametersProvider.java:
...
public class MyCustomParametersProvider implements CustomParametersProvider {
public CustomParameters buildCustomParameters(PXConfiguration pxConfiguration, PXContext pxContext) {
CustomParameters customParameters = new CustomParameters();
customParameters.setCustomParam1("my_custom_param_1");
customParameters.setCustomParam2("my_custom_param_2");
...
customParameters.setCustomParam10("my_custom_param_10");
return customParameters;
}
}
Then, in your filter:
...
PXConfiguration pxConfiguration = new PXConfiguration.Builder()
...
.customParametersProvider(new MyCustomParametersProvider())
.build();
...
Multiple Application Support
Simply create multiple instances of the HUMAN class:
PerimeterX enforcerApp1 = new PerimeterX(new PXConfiguration.Builder().appId(APP_ID_1)...build(););
PerimeterX enforcerApp2 = new PerimeterX(new PXConfiguration.Builder().appId(APP_ID_2)...build(););
...
// Inside route request handler for app 1:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOExcption {
PXContext ctx = enforcerApp1.px(req, new HttpServletResponseWrapper(resp);
...
}
...
// Inside route request handler for app 2:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOExcption {
PXContext ctx = enforcerApp2.pxVerify(req, new HttpServletResponseWrapper(resp);
if(ctx != null) {
...
}
}
Credentials Intelligence
This feature extracts credentials (hashed username and password) from requests and sends them to HUMAN as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths. The settings are adjusted by modifying the custom/pxConfig
JSON object.
If credentials are found to be compromised, the header px-compromised-credentials
will be added to the origin request with the value 1
. You may configure the name of this header with the px_compromised_credentials_header
configuration.
Default Values
- px_compromised_credentials_header: "px-compromised-credentials"
- px_login_credentials_extraction_enabled: false
- px_login_credentials_extraction: []
{
...
" px_compromised_credentials_header": "x-px-comp-creds",
"px_login_credentials_extraction_enabled": true,
"px_login_credentials_extraction": [
{
"pathType": "regex" or null // default: null
"path": "/login", // support regular expressions and exact path configuration
"method": "post", // supports all http methods
"sent_through": "body", // supported sentThroughs: body, header, query-param
"pass_field": "password", // name (or array of names) of the password field in the request (can also be nested field using dots i.e details.password)
"user_field": ["username", "email"] // name (or array of names) of the username field in the request (can also be nested field using dots i.e details.username)
},
...
],
...
};
Important Notice
Define regular expression "path": When using pathType "regex" the path attribute should contain regular expression as a string pattern without slashes and without flags (i.e, instead of /ab+c/i configure "ab+c"). Regular expressions are treated as case-insensitive by the enforcer by default.
Configure
user_field
orpass_field
as an array when the same login endpoint can have two or more different field names as input.
It is also possible to define a custom class to extract the username and password. The class should implement CredentialsExtractor interface and override the extractCredentials method. The method accepts the HttpServletRequest object as a parameter and return the LoginCredentialsClass. If extraction is unsuccessful, the function should return null
.
public class DefaultCredentialsCustomExtractor implements CredentialsExtractor {
@Override
public LoginCredentials extractCredentials(HttpServletRequest request) {
return null;
}
}
Additional S2S Activity
To enhance detection on login credentials extraction endpoints, the following additional information is sent to HUMAN via an additional_s2s
activity:
- Response Code - The numerical HTTP status code of the response.
- Login Success - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
- Raw Username - The original username used for the login attempt. In order to report this information, make sure the configuration
px_send_raw_username_on_additional_s2s_activity
is set totrue
.
Login Success Reporting
There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as false
.
Default: Empty
private LoginResponseValidationReportingMethod loginResponseValidationReportingMethod = LoginResponseValidationReportingMethod.STATUS
Status
Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to true
. Otherwise, it's set to false
.
Note: To define a range of statuses, use the
custom
reporting method.
Default Values
px_login_successful_status: 200
private int[] loginResponseValidationStatusCode = {200};
Header
Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to true
. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to false
.
Default Values
px_login_successful_header_name: x-px-login-successful
px_login_successful_header_value: 1
private String headerNameToValidateLoginResponse = "x-px-login-successful";
private String headerValueToValidateLoginResponse = "1";
Body
Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set to true
. If no match is found, the login successful status is set to false
.
Default Values
px_login_successful_body_regex: Empty
private String regexPatternToValidateLoginResponseBody = "You logged in successfully!" // string or RegExp
Custom
Provide a custom class that implements LoginResponseValidator and override isSuccessfulLogin which receives HttpServletResponseWrapper and returns a boolean.
Default Values
px_login_successful_custom_callback: null
public class DefaultCustomLoginResponseValidator implements LoginResponseValidator {
@Override
public boolean isSuccessfulLogin(HttpServletResponseWrapper response) {
return false;
}
}
Additional S2S Activity Headers
Rather than sending the additional_s2s
activity automatically, it is instead possible to generate the base additional_s2s
activity along with the URL endpoint, and pass them to the origin server as headers on the original HTTP request. When enabled, the module will add two new headers to the original request and send them to the origin:
px-additional-activity
, a stringified JSON activity that should be sent.px-additional-activity-url
, the complete URL endpoint to which the JSON object should be sent.
Note: Enabling this feature will disable the automatic sending of the
additional_s2s
activity.
Default Values
px_additional_s2s_activity_header_enabled: false
private boolean additionalS2SActivityHeaderEnabled = true;
The px-additional-activity
header value is a stringified JSON object that looks like this. Only the fields indicated with // MODIFY
should be changed prior to sending. Other fields should not be altered in any way.
{
"type": "additional_s2s",
"timestamp": 1637000000,
"socket_ip": "1.1.1.1",
"px_app_id": "PX_APP_ID",
"url": "https://www.example.com/the-target-url",
"vid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"details": {
"client_uuid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"request_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"ci_version": "v1",
"http_status_code": null, // MODIFY, number (e.g., 200, 401, 404, etc.)
"login_successful": null, // MODIFY, boolean (e.g., true, false)
"raw_username": null // MODIFY, string (e.g., "[email protected]")
}
}
After parsing the object and adding the appropriate http_status_code
and login_successful
fields in the origin server, send the JSON object as an HTTP POST
request to the URL provided in the px-additional-activity-url
header.
Note
The POST request should be sent with the
Content-Type: application/json
andAuthorization: Bearer <PX_AUTH_TOKEN>
headers.
Raw Username
When enabled, the raw username used for logins on login credentials extraction endpoints will be reported to HUMAN if (1) the credentials were identified as compromised, and (2) the login was successful as reported via the property above.
Default: false
private boolean addRawUsernameOnAdditionalS2SActivity = true;
Wrappers implementation
Credentials Intelligence require reading the login request and response. In order to apply this and enable reading multiple times two wrappers were created: RequestWrapper and ResponseWrapper. The wrappers should be used inside an interceptor in the following manner.
This should be added before the request is verified by the enforcer:
request = new RequestWrapper((HttpServletRequest) request);
This should be added after the response was sent to the client:
response = new ResponseWrapper((HttpServletResponse) response);
pxFilter.pxPostVerify((ResponseWrapper) response, context);
.
Example for implementation inside interceptor:
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// The request wrapper enables to read the request multiple times.
request = new RequestWrapper((HttpServletRequest) request);
try {
PXContext pxContext = this.enforcer.pxVerify((HttpServletRequest) servletRequest, new HttpServletResponseWrapper((HttpServletResponse) servletResponse));
boolean isHandledResponse = pxContext.isHandledResponse();
if (isHandledResponse) {
return;
}
filterChain.doFilter(servletRequest, servletResponse);
// This enables to read the response, it should happen after the response was already sent to the client
response = new ResponseWrapper((HttpServletResponse) response);
pxFilter.pxPostVerify((ResponseWrapper) response, context);
} catch (Exception e) {
// Fail open in case of Exception
filterChain.doFilter(servletRequest, servletResponse);
}
}
Test Block Flow on Monitoring Mode
Allows you to test an enforcer’s blocking flow while you are still in Monitor Mode. When the header name is set(e.g., x-px-block
) and the value is set to 1
, when there is a block response (for example from using a User-Agent header with the value of PhantomJS/1.0
) the Monitor Mode is bypassed and full block mode is applied. If one of the conditions is missing you will stay in Monitor Mode. This is done per request. To stay in Monitor Mode, set the header value to 0
.
The Header Name is configurable using the px_bypass_monitor_header
property.
Default: Empty
private String bypassMonitorHeader = "x-px-block";
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 containing 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,
"altBlockScript": String,
"customLogo": 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.
Default Values
px_advanced_blocking_response: true
Updated 12 days ago