Skip to content

Commit 3593e91

Browse files
authored
Merge pull request #205 from PerimeterX/release/v3.10.0
[SDKNEW-2139] Release/v3.10.0 (to master)
2 parents ac63a87 + 1d854f9 commit 3593e91

23 files changed

+717
-76
lines changed

.github/workflows/ci.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: CI
2+
on: pull_request
3+
jobs:
4+
lint:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- name: Checkout code
8+
uses: actions/checkout@v2
9+
- name: Install dependencies
10+
uses: php-actions/composer@v5
11+
with:
12+
php_version: '7.4'
13+
- name: Run linter
14+
uses: michaelw90/PHP-Lint@master
15+
unit-test:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v2
20+
- name: Setup PHP
21+
uses: shivammathur/setup-php@v2
22+
with:
23+
php-version: '5.6'
24+
tools: composer:2.2
25+
- name: Bootstrap tests
26+
run: cp tests/bootstrap.php.dist tests/bootstrap.php
27+
- name: Install dependencies
28+
run: composer install
29+
- name: Run unit tests
30+
run: ./vendor/phpunit/phpunit/phpunit tests/

.travis.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ 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.10.0] - 2022-08-25
9+
10+
### Added
11+
12+
- Support for first party
13+
- Support for CI V2 hashing protocol
14+
15+
### Fixed
16+
17+
- Bug in client IP extraction feature
18+
819
## [3.9.1] - 2022-04-11
920

1021
### Fixed

README.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
# [PerimeterX](http://www.perimeterx.com) PHP SDK
88

9-
> Latest stable version: [v3.9.1](https://packagist.org/packages/perimeterx/php-sdk#3.9.1)
9+
> Latest stable version: [v3.10.0](https://packagist.org/packages/perimeterx/php-sdk#3.10.0)
1010
1111
## Table of Contents
1212

@@ -29,6 +29,8 @@
2929
* [Sensitive Route](#sensitive-routes)
3030
* [API Timeouts](#api-timeout)
3131
* [Activities API Timeouts](#activities-api-timeout)
32+
* [First Party](#first-party)
33+
* [First Party for Code Defender](#first-party-code-defender)
3234
* [Send Page Activities](#send-page-activities)
3335
* [Additional Page Activity Handler](#additional-page-activity-handler)
3436
* [Data-Enrichment](#data-enrichment)
@@ -385,7 +387,7 @@ The API Connection Timeout, in seconds (float), to wait for the connection to th
385387

386388
```php
387389
$perimeterxConfig = [
388-
..
390+
..
389391
'api_connect_timeout' => 2
390392
..
391393
]
@@ -401,7 +403,7 @@ The activities API Timeout, in seconds (float), to wait for the PerimeterX serve
401403

402404
```php
403405
$perimeterxConfig = [
404-
..
406+
..
405407
'activities_timeout' => 2
406408
..
407409
]
@@ -413,12 +415,40 @@ The activities API Connection Timeout, in seconds (float), to wait for the conne
413415

414416
```php
415417
$perimeterxConfig = [
416-
..
418+
..
417419
'activities_connect_timeout' => 2
418420
..
419421
]
420422
```
421423

424+
#### <a name="first-party"></a>First Party
425+
426+
A boolean flag to enable/disable first party mode.
427+
428+
**Default:** true
429+
430+
```php
431+
$perimeterxConfig = [
432+
..
433+
'px_first_party_enabled' => false
434+
..
435+
]
436+
```
437+
438+
#### <a name="first-party-code-defender"></a>First Party for Code Defender
439+
440+
A boolean flag to enable/disable first party mode for Code Defender.
441+
442+
**Default:** false
443+
444+
```php
445+
$perimeterxConfig = [
446+
..
447+
'px_cd_first_party_enabled' => true
448+
..
449+
]
450+
```
451+
422452
#### <a name="send-page-activities"></a> Send Page Activities
423453

424454
A boolean flag to enable or disable sending of activities and metrics to

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "perimeterx/php-sdk",
33
"description": "PerimeterX SDK for PHP",
4-
"version" : "3.9.1",
4+
"version" : "3.10.0",
55
"keywords": [
66
"perimeterx",
77
"websecurity",
@@ -33,7 +33,7 @@
3333
},
3434
"autoload-dev": {
3535
"psr-4": {
36-
"Perimeterx\\Tests\\": "tests/"
36+
"PerimeterxTests\\": "tests/"
3737
}
3838
}
3939
}

px_metadata.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
{
2-
"version": "3.9.1",
2+
"version": "3.10.0",
33
"supported_features": [
44
"additional_activity_handler",
5-
"additional_s2s",
65
"advanced_blocking_response",
76
"block_activity",
87
"block_page_captcha",
@@ -14,9 +13,10 @@
1413
"css_ref",
1514
"custom_logo",
1615
"custom_parameters",
16+
"first_party",
1717
"js_ref",
1818
"logger",
19-
"login_credentials_extraction",
19+
"credentials_intelligence",
2020
"mobile_support",
2121
"module_enable",
2222
"module_mode",

src/CredentialsIntelligence/Protocol/CIVersion.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44

55
class CIVersion {
66
const V1 = "v1";
7+
const V2 = "v2";
78
const MULTISTEP_SSO = "multistep_sso";
89
}

src/CredentialsIntelligence/Protocol/CredentialsIntelligenceProtocolFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public static function Create($version) {
1111
switch($version) {
1212
case CIVersion::V1:
1313
return new V1CredentialsIntelligenceProtocol();
14+
case CIVersion::V2:
15+
return new V2CredentialsIntelligenceProtocol();
1416
case CIVersion::MULTISTEP_SSO:
1517
return new MultistepSSOCredentialsIntelligenceProtocol();
1618
default:
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Perimeterx\CredentialsIntelligence\Protocol;
4+
5+
use Perimeterx\PerimeterxUtils;
6+
use Perimeterx\CredentialsIntelligence\LoginCredentialsFields;
7+
8+
9+
class V2CredentialsIntelligenceProtocol implements ICredentialsIntelligenceProtocol {
10+
public function ProcessCredentials($username, $password) {
11+
$normalizedUsername = PerimeterxUtils::isEmailAddress($username) ? $this->normalizeEmailAddress($username) : $username;
12+
$hashedUsername = PerimeterxUtils::sha256($normalizedUsername);
13+
return new LoginCredentialsFields(
14+
$hashedUsername,
15+
$this->hashPassword($hashedUsername, $password),
16+
CIVersion::V2,
17+
$username
18+
);
19+
}
20+
21+
private function normalizeEmailAddress($emailAddress) {
22+
$lowercaseEmail = strtolower($emailAddress);
23+
$atIndex = strpos($lowercaseEmail, "@");
24+
$domain = substr($lowercaseEmail, $atIndex);
25+
$normalizedUsername = substr($lowercaseEmail, 0, $atIndex);
26+
27+
$plusIndex = strpos($normalizedUsername, "+");
28+
if ($plusIndex !== false) {
29+
$normalizedUsername = substr($normalizedUsername, 0, $plusIndex);
30+
}
31+
32+
if ($domain === "@gmail.com") {
33+
$normalizedUsername = str_replace(".", "", $normalizedUsername);
34+
}
35+
36+
return $normalizedUsername . $domain;
37+
}
38+
39+
private function hashPassword($salt, $password) {
40+
$hashedPassword = PerimeterxUtils::sha256($password);
41+
return PerimeterxUtils::sha256($salt . $hashedPassword);
42+
}
43+
}

src/Perimeterx.php

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
use Perimeterx\CredentialsIntelligence\Protocol\CredentialsIntelligenceProtocolFactory;
3232
use Perimeterx\CredentialsIntelligence\LoginSuccess\LoginSuccessfulReportingMethod;
3333
use Perimeterx\CredentialsIntelligence\LoginSuccess\LoginSuccessfulParserFactory;
34+
use Perimeterx\Utils\GuzzleHttpClient;
35+
3436
final class Perimeterx
3537
{
3638
/**
@@ -96,7 +98,7 @@ private function __construct(array $pxConfig = [])
9698
'max_buffer_len' => 1,
9799
'send_page_activities' => true,
98100
'send_block_activities' => true,
99-
'sdk_name' => 'PHP SDK v3.9.1',
101+
'sdk_name' => 'PHP SDK v3.10.0',
100102
'debug_mode' => false,
101103
'perimeterx_server_host' => 'https://sapi-' . strtolower($pxConfig['app_id']) . '.perimeterx.net',
102104
'captcha_script_host' => 'https://captcha.px-cdn.net',
@@ -114,10 +116,12 @@ private function __construct(array $pxConfig = [])
114116
'defer_activities' => true,
115117
'enable_json_response' => false,
116118
'return_response' => false,
119+
'px_first_party_enabled' => true,
120+
'px_cd_first_party_enabled' => false,
117121
'px_login_credentials_extraction_enabled' => false,
118122
'px_login_credentials_extraction' => [],
119123
'px_compromised_credentials_header' => 'px-compromised-credentials',
120-
'px_credentials_intelligence_version' => CIVersion::V1,
124+
'px_credentials_intelligence_version' => CIVersion::V2,
121125
'px_additional_s2s_activity_header_enabled' => false,
122126
'px_automatic_additional_s2s_activity_enabled' => true,
123127
'px_send_raw_username_on_additional_s2s_activity' => false,
@@ -150,7 +154,11 @@ public function pxVerify()
150154
$this->pxConfig['logger']->debug('Request will not be verified, module is disabled');
151155
return 1;
152156
}
153-
157+
158+
if ($this->pxConfig['px_first_party_enabled'] || $this->pxConfig['px_cd_first_party_enabled']) {
159+
$this->handleFirstParty();
160+
}
161+
154162
$additionalFields = $this->createAdditionalFields();
155163

156164
$pxCtx = new PerimeterxContext($this->pxConfig, $additionalFields);
@@ -261,21 +269,30 @@ private function handleVerification($pxCtx)
261269
'loader' => new \Mustache_Loader_FilesystemLoader(dirname(__FILE__) . '/templates'),
262270
));
263271

264-
$collectorUrl = 'https://collector-' . strtolower($this->pxConfig['app_id']) . '.perimeterx.net';
265272
$appId = $this->pxConfig['app_id'];
273+
$collectorUrl = 'https://collector-' . strtolower($appId) . '.perimeterx.net';
274+
275+
$captchaScript = $this->getCaptchaScript($this->pxConfig['captcha_script_host'], $appId, $pxCtx);
276+
$jsClientSrc = "//client.perimeterx.net/$appId/main.min.js";
277+
if ($this->pxConfig['px_first_party_enabled']) {
278+
$appIdWithoutPx = substr($appId, 2);
279+
$captchaScript = $this->getCaptchaScript("/$appIdWithoutPx/captcha", $appId, $pxCtx);
280+
$jsClientSrc = "/$appIdWithoutPx/init.js";
281+
$collectorUrl = "/$appIdWithoutPx/xhr";
282+
}
266283

267284
$templateInputs = array(
268-
'appId' => $this->pxConfig['app_id'],
285+
'appId' => $appId,
269286
'vid' => $pxCtx->getVid(),
270287
'uuid' => $block_uuid,
271288
'cssRef' => $this->getCssRef(),
272289
'jsRef' => $this->getJsRef(),
273290
'hostUrl' => $collectorUrl,
274291
'customLogo' => isset($this->pxConfig['custom_logo']) ? $this->pxConfig['custom_logo'] : '',
275-
'blockScript' => $this->getCaptchaScript($this->pxConfig['captcha_script_host'], $appId, $pxCtx),
292+
'blockScript' => $captchaScript,
276293
'altBlockScript' => $this->getCaptchaScript($this->pxConfig['alternate_captcha_script_host'], $appId, $pxCtx),
277-
'firstPartyEnabled' => 'false',
278-
'jsClientSrc' => "//client.perimeterx.net/{$this->pxConfig['app_id']}/main.min.js"
294+
'firstPartyEnabled' => $this->pxConfig['px_first_party_enabled'],
295+
'jsClientSrc' => $jsClientSrc
279296
);
280297

281298
http_response_code(403);
@@ -310,7 +327,7 @@ private function handleVerification($pxCtx)
310327
$result = array(
311328
'appId' => $this->pxConfig['app_id'],
312329
'jsClientSrc' => $templateInputs['jsClientSrc'],
313-
'firstPartyEnabled' => false,
330+
'firstPartyEnabled' => $this->pxConfig['px_first_party_enabled'],
314331
'vid' => $templateInputs['vid'],
315332
'uuid' => $templateInputs['uuid'],
316333
'hostUrl' => $templateInputs['hostUrl'],
@@ -348,6 +365,29 @@ private function handleVerification($pxCtx)
348365
die();
349366
}
350367

368+
/**
369+
* Method for handling first party requests for both BD and CD
370+
*/
371+
private function handleFirstParty() {
372+
$pxFirstParty = new PerimeterxFirstPartyClient($this->pxConfig, new GuzzleHttpClient());
373+
374+
if ($this->pxConfig['px_first_party_enabled']) {
375+
$response = $pxFirstParty->handleFirstParty();
376+
if (isset($response)) {
377+
echo $response;
378+
die();
379+
}
380+
}
381+
382+
if ($this->pxConfig['px_cd_first_party_enabled']) {
383+
$response = $pxFirstParty->handleCodeDefenderFirstParty();
384+
if (isset($response)) {
385+
echo $response;
386+
die();
387+
}
388+
}
389+
}
390+
351391
/*
352392
* Method for assembling the Captcha script tag source
353393
*/

0 commit comments

Comments
 (0)