Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Change Log
## [x.x.x] - YYYY-MM-DD
- Added support for data enrichment header feature (`px_data_enrichment_header_name` configuration)
- Added `px_secured_pxhd_enabled` configuration option to enable secure flag on `pxhd` cookie
- Added `is_sensitive_route` to risk api and async activities
- Added `additional_token_info` to risk api and async activities
Expand Down
3 changes: 2 additions & 1 deletion ci_files/enforcer-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,6 @@
"px_cors_support_enabled": true,
"px_cors_preflight_request_filter_enabled": true,
"px_url_decode_reserved_characters": true,
"px_secured_pxhd_enabled": true
"px_secured_pxhd_enabled": true,
"px_data_enrichment_header_name": "X-PX-Data-Enrichment"
}
1 change: 1 addition & 0 deletions px_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"custom_parameters",
"custom_proxy",
"custom_sensitive_request",
"data_enrichment_header",
"enforced_routes",
"enforcer_error",
"filter_by_extension",
Expand Down
24 changes: 22 additions & 2 deletions src/main/java/com/perimeterx/api/PerimeterX.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,17 @@
import com.perimeterx.utils.logger.IPXLogger;
import com.perimeterx.utils.StringUtils;
import com.perimeterx.utils.logger.LoggerFactory;
import edu.emory.mathcs.backport.java.util.Collections;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.Closeable;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.List;

import static com.perimeterx.utils.Constants.*;
import static com.perimeterx.utils.PXCommonUtils.cookieKeysToCheck;
Expand Down Expand Up @@ -240,6 +239,7 @@ private void addCustomHeadersToRequest(HttpServletRequest request, PXContext con
setBreachedAccount(request, context);
setAdditionalS2SActivityHeaders(request, context);
}
setDataEnrichmentHeader(request, context);
}

private void setBreachedAccount(HttpServletRequest request, PXContext context) {
Expand All @@ -260,6 +260,26 @@ private void setAdditionalS2SActivityHeaders(HttpServletRequest request, PXConte
}
}

private void setDataEnrichmentHeader(HttpServletRequest request, PXContext context) {
try {
String headerName = configuration.getPxDataEnrichmentHeaderName();
if (headerName == null || headerName.isEmpty()) {
return;
}

if (context.getPxde() == null || !context.isPxdeVerified()) {
return;
}

String pxdeJson = context.getPxde().toString();
byte[] utf8Bytes = pxdeJson.getBytes(StandardCharsets.UTF_8);
String encodedPxde = new String(utf8Bytes, StandardCharsets.ISO_8859_1);
((RequestWrapper) request).addHeader(headerName, encodedPxde);
} catch (Exception e) {
context.logger.debug("Failed to add data enrichment header", e);
}
}

public void pxPostVerify(ResponseWrapper response, PXContext context) throws PXException {
try {
if (context != null) {
Expand Down
10 changes: 4 additions & 6 deletions src/main/java/com/perimeterx/internals/PXS2SValidator.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.perimeterx.internals;

import com.perimeterx.api.PerimeterX;
import com.perimeterx.api.additionalContext.PXHDSource;
import com.perimeterx.http.PXClient;
import com.perimeterx.internals.cookie.DataEnrichmentCookie;
import com.perimeterx.models.PXContext;
import com.perimeterx.models.configuration.PXConfiguration;
import com.perimeterx.models.exceptions.PXException;
Expand All @@ -14,7 +12,6 @@
import com.perimeterx.models.risk.S2SErrorReasonInfo;
import com.perimeterx.utils.Constants;
import com.perimeterx.utils.EnforcerErrorUtils;
import com.perimeterx.utils.logger.IPXLogger;
import com.perimeterx.utils.logger.LogReason;
import org.apache.http.conn.ConnectTimeoutException;

Expand Down Expand Up @@ -99,9 +96,10 @@ private void updateContextFromResponse(PXContext pxContext, RiskResponse respons
pxContext.setRiskScore(response.getScore());
pxContext.setUuid(response.getUuid());
pxContext.setBlockAction(response.getAction());
DataEnrichmentCookie dataEnrichment = new DataEnrichmentCookie(response.getDataEnrichment(), true);
pxContext.setPxde(dataEnrichment.getJsonPayload());
pxContext.setPxdeVerified(dataEnrichment.isValid());
if (response.getDataEnrichment() != null) {
pxContext.setPxde(response.getDataEnrichment());
pxContext.setPxdeVerified(true);
}

if(isNoneBlank(response.getPxhd())) {
pxContext.setPxhd(response.getPxhd());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,11 @@ public static void setPxLoggerSeverity(LoggerSeverity severity) {
@Builder.Default
@JsonProperty("px_jwt_header_additional_field_names")
private List<String> pxJwtHeaderAdditionalFieldNames = new ArrayList<>();

@Builder.Default
@JsonProperty("px_data_enrichment_header_name")
private String pxDataEnrichmentHeaderName = "";

/**
* @return Configuration Object clone without cookieKey and authToken
**/
Expand Down
3 changes: 3 additions & 0 deletions web/src/main/java/com/web/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ public PXConfiguration getPxConfiguration() {
case "px_jwt_header_additional_field_names":
builder.pxJwtHeaderAdditionalFieldNames(extractStringList(key));
break;
case "px_data_enrichment_header_name":
builder.pxDataEnrichmentHeaderName(enforcerConfig.getString(key));
break;
case "px_user_agent_max_length":
case "px_risk_cookie_max_length":
case "px_risk_cookie_max_iterations":
Expand Down
15 changes: 13 additions & 2 deletions web/src/main/java/com/web/PXFilter.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.web;

import com.perimeterx.api.PerimeterX;
import com.perimeterx.api.additionalContext.credentialsIntelligence.loginrequest.CredentialsExtractorFactory;
import com.perimeterx.http.RequestWrapper;
import com.perimeterx.http.ResponseWrapper;
import com.perimeterx.models.PXContext;
Expand Down Expand Up @@ -39,14 +38,14 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
final PXContext context = pxFilter.pxVerify((HttpServletRequest) request, new HttpServletResponseWrapper((HttpServletResponse) response));

setDefaultPageAttributes((HttpServletRequest) request, config);
copyDataEnrichmentHeaderToResponse((HttpServletRequest) request, (HttpServletResponse) response);

if (context != null && context.isRequestLowScore()) {
filterChain.doFilter(request, response);
}

response = new ResponseWrapper((HttpServletResponse) response);
pxFilter.pxPostVerify((ResponseWrapper) response, context);

} catch (PXException e) {
filterChain.doFilter(request, response);
}
Expand All @@ -61,4 +60,16 @@ public void destroy() {
e.printStackTrace();
}
}

private void copyDataEnrichmentHeaderToResponse(HttpServletRequest request, HttpServletResponse response) {
String dataEnrichmentHeaderName = config.getPxConfiguration().getPxDataEnrichmentHeaderName();
if (dataEnrichmentHeaderName == null || dataEnrichmentHeaderName.isEmpty()) {
return;
}

String dataEnrichmentHeaderValue = request.getHeader(dataEnrichmentHeaderName);
if (dataEnrichmentHeaderValue != null && !dataEnrichmentHeaderValue.isEmpty()) {
response.setHeader(dataEnrichmentHeaderName, dataEnrichmentHeaderValue);
}
}
}