Skip to content
This repository was archived by the owner on Oct 29, 2025. It is now read-only.

Commit ecfcd32

Browse files
authored
Merge pull request #216 from PerimeterX/dev
Dev
2 parents b3ad189 + 3b13a16 commit ecfcd32

File tree

7 files changed

+48
-4
lines changed

7 files changed

+48
-4
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## [3.2.1] - 2022-01-31
9+
10+
### Added
11+
12+
- Support for dynamic cookie signing with IP (requires PXHD)
13+
814
## [3.2.0] - 2022-01-24
915

1016
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[PerimeterX](http://www.perimeterx.com) Shared base for NodeJS enforcers
77
=============================================================
88

9-
> Latest stable version: [v3.2.0](https://www.npmjs.com/package/perimeterx-node-core)
9+
> Latest stable version: [v3.2.1](https://www.npmjs.com/package/perimeterx-node-core)
1010
1111
This is a shared base implementation for PerimeterX Express enforcer and future NodeJS enforcers. For a fully functioning implementation example, see the [Node-Express enforcer](https://github.com/PerimeterX/perimeterx-node-express/) implementation.
1212

lib/cookie/cookieV3.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ class CookieV3 extends Payload {
3232
}
3333

3434
isSecure() {
35-
const hmacStr = this.pxCookie + this.ctx.userAgent;
35+
let hmacStr = this.pxCookie;
36+
if (this.ctx.signedFields) {
37+
hmacStr += this.ctx.signedFields.join('');
38+
}
3639
return this.isHmacValid(hmacStr, this.getHmac());
3740
}
3841
}

lib/cookie/tokenV3.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ class TokenV3 extends Payload {
3232
}
3333

3434
isSecure() {
35-
return this.isHmacValid(this.pxCookie, this.getHmac());
35+
let hmacStr = this.pxCookie;
36+
if (this.ctx.signedFields) {
37+
hmacStr += this.ctx.signedFields.join('');
38+
}
39+
return this.isHmacValid(hmacStr, this.getHmac());
3640
}
3741
}
3842

lib/pxcontext.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ class PxContext {
2929
this.shouldBypassMonitor = config.BYPASS_MONITOR_HEADER && req.headers[config.BYPASS_MONITOR_HEADER] === '1';
3030
this.cookieOrigin = CookieOrigin.COOKIE;
3131
this.additionalFields = additionalFields || {};
32+
this.signedFields = [this.userAgent];
3233
const mobileHeader = this.headers[mobileSdkHeader];
3334
if (mobileHeader !== undefined) {
35+
this.signedFields = null;
3436
this.cookieOrigin = CookieOrigin.HEADER;
3537
config.logger.debug('Mobile SDK token detected');
3638
this.originalToken = this.headers[mobileSdkOriginalTokenHeader];

lib/pxcookie.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ function evalCookie(ctx, config) {
6262
ctx.uuid = cookie.getUuid();
6363
ctx.hmac = cookie.getHmac();
6464
ctx.blockAction = cookie.getBlockAction();
65+
ctx.signedFields = getSignedFields(ctx);
6566

6667
if (cookie.isExpired()) {
6768
config.logger.debug(`Cookie TTL is expired, value: ${JSON.stringify(cookie.decodedCookie)}, age: ${Date.now() - cookie.getTime()}`);
@@ -121,6 +122,34 @@ function pxCookieFactory(ctx, config) {
121122
}
122123
}
123124

125+
function getSignedFields(pxCtx) {
126+
const { decodedCookie } = pxCtx;
127+
if (typeof decodedCookie.x !== 'string') {
128+
return pxCtx.signedFields;
129+
}
130+
131+
const signedFields = [];
132+
for (const char of decodedCookie.x) {
133+
signedFields.push(convertCharToField(char, pxCtx));
134+
}
135+
return signedFields;
136+
}
137+
138+
function convertCharToField(char, pxCtx) {
139+
let field;
140+
switch (char) {
141+
case 'u':
142+
field = pxCtx.userAgent;
143+
break;
144+
case 's':
145+
field = pxCtx.ip;
146+
break;
147+
default:
148+
break;
149+
}
150+
return field ? field : '';
151+
}
152+
124153
function getCookieVersion(ctx) {
125154
return ctx.cookies['_px3'] ? 'V3' : 'V1';
126155
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "perimeterx-node-core",
3-
"version": "3.2.0",
3+
"version": "3.2.1",
44
"description": "PerimeterX NodeJS shared core for various applications to monitor and block traffic according to PerimeterX risk score",
55
"main": "index.js",
66
"scripts": {

0 commit comments

Comments
 (0)