Skip to content

Commit

Permalink
Merge pull request #177 from PerimeterX/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
ori-gold-px authored Jan 7, 2022
2 parents 828bf05 + 9ffd7f4 commit a5ae5b0
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 13 deletions.
14 changes: 12 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,25 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [3.7.6] - 2022-01-07

### Fixed

- Bug with sensitive routes on mobile

### Added

- Sending graphql operation type and name on activities

## [3.7.5] - 2021-12-22

## Fixed
### Fixed

- Allows extraction of login credentials via a custom static class method

## [3.7.4] - 2021-12-20

## Added
### Added

- Option to extract login credentials via custom callback function

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

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

> Latest stable version: [v3.7.4](https://packagist.org/packages/perimeterx/php-sdk#3.7.4)
> Latest stable version: [v3.7.6](https://packagist.org/packages/perimeterx/php-sdk#3.7.6)
## Table of Contents

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "perimeterx/php-sdk",
"description": "PerimeterX SDK for PHP",
"version" : "3.7.5",
"version" : "3.7.6",
"keywords": [
"perimeterx",
"websecurity",
Expand Down
2 changes: 1 addition & 1 deletion px_metadata.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "3.7.5",
"version": "3.7.6",
"supported_features": [
"additional_activity_handler",
"advanced_blocking_response",
Expand Down
61 changes: 61 additions & 0 deletions src/GraphqlExtractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Perimeterx;

class GraphqlExtractor {
/**
* @return GraphqlFields
*/
public static function ExtractGraphqlFields() {
$postBody = json_decode(PerimeterxUtils::getPostRequestBody(), true);
if (!isset($postBody)) {
return null;
}

$query = GraphqlExtractor::extractGraphqlQuery($postBody);
$queryArray = preg_split('/[^A-Za-z0-9_]/', $query);

$operationType = GraphqlExtractor::extractOperationType($query, $queryArray);
$operationName = GraphqlExtractor::extractOperationName($postBody, $queryArray);

return new GraphqlFields($operationType, $operationName);
}

private static function extractGraphqlQuery(&$postRequestBody) {
if (!array_key_exists('query', $postRequestBody)) {
return '';
}

return $postRequestBody['query'];
}

private static function extractOperationType(&$query, &$queryArray) {
$isGraphqlShorthand = $query[0] === '{';
if ($isGraphqlShorthand) {
return 'query';
}

$operationType = $queryArray[0];
if (!in_array($operationType, ['query', 'mutation', 'subscription'])) {
$operationType = 'query';
}

return $operationType;
}

private static function extractOperationName(&$postBody, &$queryArray) {
if (array_key_exists('operationName', $postBody)) {
return $postBody['operationName'];
}

if (!in_array($queryArray[0], ['query', 'mutation', 'subscription'])) {
return $queryArray[0];
}

if ($queryArray[1]) {
return $queryArray[1];
}

return null;
}
}
31 changes: 31 additions & 0 deletions src/GraphqlFields.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Perimeterx;

class GraphqlFields {
private $operationType;
private $operationName;

/**
* @param string $operationType
* @param string $operationName
*/
public function __construct($operationType, $operationName) {
$this->operationType = $operationType;
$this->operationName = $operationName;
}

/**
* @return string
*/
public function getOperationType() {
return $this->operationType;
}

/**
* @return string
*/
public function getOperationName() {
return $this->operationName;
}
}
52 changes: 45 additions & 7 deletions src/Perimeterx.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ private function __construct(array $pxConfig = [])
'max_buffer_len' => 1,
'send_page_activities' => true,
'send_block_activities' => true,
'sdk_name' => 'PHP SDK v3.7.5',
'sdk_name' => 'PHP SDK v3.7.6',
'debug_mode' => false,
'perimeterx_server_host' => 'https://sapi-' . strtolower($pxConfig['app_id']) . '.perimeterx.net',
'captcha_script_host' => 'https://captcha.px-cdn.net',
Expand Down Expand Up @@ -139,11 +139,9 @@ public function pxVerify()
return 1;
}

if (!is_null($this->pxFieldExtractorManager)) {
$extractedCredentials = $this->pxFieldExtractorManager->extractFields();
}
$additionalFields = $this->createAdditionalFields();

$pxCtx = new PerimeterxContext($this->pxConfig, $extractedCredentials);
$pxCtx = new PerimeterxContext($this->pxConfig, $additionalFields);
$this->pxConfig['logger']->debug('Request context created successfully');

$validator = new PerimeterxCookieValidator($pxCtx, $this->pxConfig);
Expand Down Expand Up @@ -399,11 +397,51 @@ public function getPxConfig()
* @return PerimeterxFieldExtractorManager
*/

private function createFieldExtractorManager() {
private function createFieldExtractorManager() {
if (empty($this->pxConfig['px_enable_login_creds_extraction']) || empty($this->pxConfig['px_login_creds_extraction'])) {
return null;
}
$extractorMap = PerimeterxFieldExtractorManager::createExtractorMap($this->pxConfig['px_login_creds_extraction']);
return new PerimeterxFieldExtractorManager($extractorMap, $this->pxConfig['logger']);
}
}

private function createAdditionalFields() {
$additionalFields = array();

if (!is_null($this->pxFieldExtractorManager)) {
$extractedCredentials = $this->pxFieldExtractorManager->extractFields();
if (isset($extractedCredentials)) {
$additionalFields = array_merge($additionalFields, $extractedCredentials);
}
}

if (strpos($_SERVER['REQUEST_URI'], "graphql") !== false) {
$graphqlFields = $this->extractGraphqlFields();
if (isset($graphqlFields)) {
$additionalFields = array_merge($additionalFields, [
'graphql_operation_type' => $graphqlFields->getOperationType(),
'graphql_operation_name' => $graphqlFields->getOperationName()
]);
}
}

return $additionalFields;
}

private function extractGraphqlFields() {
try {
$this->pxConfig['logger']->debug("GraphQL endpoint identified");
$graphqlFields = GraphqlExtractor::ExtractGraphqlFields();
if (!is_null($graphqlFields)) {
$this->pxConfig['logger']->debug('Successfully extracted graphql fields');
return $graphqlFields;
} else {
$this->pxConfig['logger']->debug("Unable to extract graphql fields");
return null;
}
} catch (\Exception $e) {
$this->pxConfig['logger']->error('Exception while handling graphql body: ' . $e->getMessage());
return null;
}
}
}
3 changes: 2 additions & 1 deletion src/PerimeterxCookieValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ public function verify()
}
return false;
}
} else {
$this->pxCtx->setCookieOrigin("cookie");
}
$cookie = PerimeterxPayload::pxPayloadFactory($this->pxCtx, $this->pxConfig);
$this->pxConfig['logger']->debug("Cookie {$this->pxCtx->getCookieVersion()} found, Evaluating");
$this->pxCtx->setCookieOrigin("cookie");

if (!$cookie->deserialize()) {
$this->pxConfig['logger']->debug("Cookie decryption failed, value: {$this->pxCtx->getPxCookie()}");
Expand Down

0 comments on commit a5ae5b0

Please sign in to comment.