Skip to content

Commit d56fa30

Browse files
authored
Merge pull request #418 from PerimeterX/feature/data-enrichment-header
2 parents a1eb7de + 46dfa0f commit d56fa30

8 files changed

Lines changed: 51 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Change Log
22
## [x.x.x] - YYYY-MM-DD
3+
- Added support for data enrichment header feature (`px_data_enrichment_header_name` configuration)
34
- Added `px_secured_pxhd_enabled` configuration option to enable secure flag on `pxhd` cookie
45
- Added `is_sensitive_route` to risk api and async activities
56
- Added `additional_token_info` to risk api and async activities

ci_files/enforcer-config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,6 @@
114114
"px_cors_support_enabled": true,
115115
"px_cors_preflight_request_filter_enabled": true,
116116
"px_url_decode_reserved_characters": true,
117-
"px_secured_pxhd_enabled": true
117+
"px_secured_pxhd_enabled": true,
118+
"px_data_enrichment_header_name": "X-PX-Data-Enrichment"
118119
}

px_metadata.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"custom_parameters",
1919
"custom_proxy",
2020
"custom_sensitive_request",
21+
"data_enrichment_header",
2122
"enforced_routes",
2223
"enforcer_error",
2324
"filter_by_extension",

src/main/java/com/perimeterx/api/PerimeterX.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,17 @@
5858
import com.perimeterx.utils.logger.IPXLogger;
5959
import com.perimeterx.utils.StringUtils;
6060
import com.perimeterx.utils.logger.LoggerFactory;
61-
import edu.emory.mathcs.backport.java.util.Collections;
6261

6362
import javax.servlet.http.HttpServletRequest;
6463
import javax.servlet.http.HttpServletResponseWrapper;
6564
import java.io.Closeable;
6665
import java.io.IOException;
6766
import java.net.URISyntaxException;
67+
import java.nio.charset.StandardCharsets;
6868
import java.security.InvalidKeyException;
6969
import java.security.MessageDigest;
7070
import java.security.NoSuchAlgorithmException;
7171
import java.util.Base64;
72-
import java.util.List;
7372

7473
import static com.perimeterx.utils.Constants.*;
7574
import static com.perimeterx.utils.PXCommonUtils.cookieKeysToCheck;
@@ -240,6 +239,7 @@ private void addCustomHeadersToRequest(HttpServletRequest request, PXContext con
240239
setBreachedAccount(request, context);
241240
setAdditionalS2SActivityHeaders(request, context);
242241
}
242+
setDataEnrichmentHeader(request, context);
243243
}
244244

245245
private void setBreachedAccount(HttpServletRequest request, PXContext context) {
@@ -260,6 +260,26 @@ private void setAdditionalS2SActivityHeaders(HttpServletRequest request, PXConte
260260
}
261261
}
262262

263+
private void setDataEnrichmentHeader(HttpServletRequest request, PXContext context) {
264+
try {
265+
String headerName = configuration.getPxDataEnrichmentHeaderName();
266+
if (headerName == null || headerName.isEmpty()) {
267+
return;
268+
}
269+
270+
if (context.getPxde() == null || !context.isPxdeVerified()) {
271+
return;
272+
}
273+
274+
String pxdeJson = context.getPxde().toString();
275+
byte[] utf8Bytes = pxdeJson.getBytes(StandardCharsets.UTF_8);
276+
String encodedPxde = new String(utf8Bytes, StandardCharsets.ISO_8859_1);
277+
((RequestWrapper) request).addHeader(headerName, encodedPxde);
278+
} catch (Exception e) {
279+
context.logger.debug("Failed to add data enrichment header", e);
280+
}
281+
}
282+
263283
public void pxPostVerify(ResponseWrapper response, PXContext context) throws PXException {
264284
try {
265285
if (context != null) {

src/main/java/com/perimeterx/internals/PXS2SValidator.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package com.perimeterx.internals;
22

3-
import com.perimeterx.api.PerimeterX;
43
import com.perimeterx.api.additionalContext.PXHDSource;
54
import com.perimeterx.http.PXClient;
6-
import com.perimeterx.internals.cookie.DataEnrichmentCookie;
75
import com.perimeterx.models.PXContext;
86
import com.perimeterx.models.configuration.PXConfiguration;
97
import com.perimeterx.models.exceptions.PXException;
@@ -14,7 +12,6 @@
1412
import com.perimeterx.models.risk.S2SErrorReasonInfo;
1513
import com.perimeterx.utils.Constants;
1614
import com.perimeterx.utils.EnforcerErrorUtils;
17-
import com.perimeterx.utils.logger.IPXLogger;
1815
import com.perimeterx.utils.logger.LogReason;
1916
import org.apache.http.conn.ConnectTimeoutException;
2017

@@ -99,9 +96,10 @@ private void updateContextFromResponse(PXContext pxContext, RiskResponse respons
9996
pxContext.setRiskScore(response.getScore());
10097
pxContext.setUuid(response.getUuid());
10198
pxContext.setBlockAction(response.getAction());
102-
DataEnrichmentCookie dataEnrichment = new DataEnrichmentCookie(response.getDataEnrichment(), true);
103-
pxContext.setPxde(dataEnrichment.getJsonPayload());
104-
pxContext.setPxdeVerified(dataEnrichment.isValid());
99+
if (response.getDataEnrichment() != null) {
100+
pxContext.setPxde(response.getDataEnrichment());
101+
pxContext.setPxdeVerified(true);
102+
}
105103

106104
if(isNoneBlank(response.getPxhd())) {
107105
pxContext.setPxhd(response.getPxhd());

src/main/java/com/perimeterx/models/configuration/PXConfiguration.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@ public static void setPxLoggerSeverity(LoggerSeverity severity) {
355355
@Builder.Default
356356
@JsonProperty("px_jwt_header_additional_field_names")
357357
private List<String> pxJwtHeaderAdditionalFieldNames = new ArrayList<>();
358+
359+
@Builder.Default
360+
@JsonProperty("px_data_enrichment_header_name")
361+
private String pxDataEnrichmentHeaderName = "";
362+
358363
/**
359364
* @return Configuration Object clone without cookieKey and authToken
360365
**/

web/src/main/java/com/web/Config.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ public PXConfiguration getPxConfiguration() {
178178
case "px_jwt_header_additional_field_names":
179179
builder.pxJwtHeaderAdditionalFieldNames(extractStringList(key));
180180
break;
181+
case "px_data_enrichment_header_name":
182+
builder.pxDataEnrichmentHeaderName(enforcerConfig.getString(key));
183+
break;
181184
case "px_user_agent_max_length":
182185
case "px_risk_cookie_max_length":
183186
case "px_risk_cookie_max_iterations":

web/src/main/java/com/web/PXFilter.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.web;
22

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

4140
setDefaultPageAttributes((HttpServletRequest) request, config);
41+
copyDataEnrichmentHeaderToResponse((HttpServletRequest) request, (HttpServletResponse) response);
4242

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

4747
response = new ResponseWrapper((HttpServletResponse) response);
4848
pxFilter.pxPostVerify((ResponseWrapper) response, context);
49-
5049
} catch (PXException e) {
5150
filterChain.doFilter(request, response);
5251
}
@@ -61,4 +60,16 @@ public void destroy() {
6160
e.printStackTrace();
6261
}
6362
}
63+
64+
private void copyDataEnrichmentHeaderToResponse(HttpServletRequest request, HttpServletResponse response) {
65+
String dataEnrichmentHeaderName = config.getPxConfiguration().getPxDataEnrichmentHeaderName();
66+
if (dataEnrichmentHeaderName == null || dataEnrichmentHeaderName.isEmpty()) {
67+
return;
68+
}
69+
70+
String dataEnrichmentHeaderValue = request.getHeader(dataEnrichmentHeaderName);
71+
if (dataEnrichmentHeaderValue != null && !dataEnrichmentHeaderValue.isEmpty()) {
72+
response.setHeader(dataEnrichmentHeaderName, dataEnrichmentHeaderValue);
73+
}
74+
}
6475
}

0 commit comments

Comments
 (0)