Skip to content

Commit

Permalink
fix authentication with unindexed arrays in query strings
Browse files Browse the repository at this point in the history
  • Loading branch information
szeist committed Sep 13, 2016
1 parent 1d0c4a4 commit 8017fa1
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 62 deletions.
107 changes: 55 additions & 52 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions src/Escher.php
Original file line number Diff line number Diff line change
Expand Up @@ -690,16 +690,10 @@ public function getHost()
*/
private function stripAuthParams(EscherRequestHelper $helper, $vendorKey)
{
$parts = parse_url($helper->getCurrentUrl());
parse_str(isset($parts['query']) ? $parts['query'] : '', $params);
$url = $helper->getCurrentUrl();
$signaturePattern = "/(?P<prefix>[?&])X-${vendorKey}-Signature=[a-fA-F0-9]{64}(?P<suffix>&?)/";

$query = array();
foreach ($params as $key => $value) {
if ($key !== 'X-' . $vendorKey . '-Signature') {
$query[$key] = $value;
}
}
return "{$parts['scheme']}://{$parts['host']}{$parts['path']}" . (empty($query) ? '' : '?' . http_build_query($query, '', '&'));
return preg_replace_callback($signaturePattern, array($this, 'handleStripAuthParamMatches'), $url);
}

private function getExpires()
Expand All @@ -722,6 +716,12 @@ public function getDateTime()
{
return $this->dateTime;
}

private function handleStripAuthParamMatches($matches) {
return (!empty($matches['suffix']) || $matches['prefix'] === '?')
? $matches['prefix']
: $matches['suffix'];
}
}


Expand Down
78 changes: 77 additions & 1 deletion test/unit/AuthenticateRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,85 @@ public function itShouldFailToValidateInvalidQueryStrings()
$this->createEscher('us-east-1/host/aws4_request')->authenticate($keyDB, $serverVars, '');
}

/**
* @test
*/
public function itShouldValidatePresignedUrlRequestWithUnindexedArray()
{
$serverVars = array(
'REQUEST_TIME' => $this->strtotime('20150310T173248Z'),
'REQUEST_METHOD' => 'GET',
'HTTP_HOST' => 'service.example.com',
'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=utf-8',
'REQUEST_URI' => '/login?id=12345678&domain=login.example.com&redirect_to=https%3A%2F%2Fhome.dev%2Fbootstrap.php%3Fr%3Dservice%2Findex%26service%3Dservice_name&param1%5B%5D=1&param1%5B%5D=2%3F&X-EMS-Algorithm=EMS-HMAC-SHA256&X-EMS-Credentials=service_api_key%2F20150310%2Feu%2Fservice%2Fems_request&X-EMS-Date=20150310T173248Z&X-EMS-Expires=86400&X-EMS-SignedHeaders=host&X-EMS-Signature=ddb1e6479f28752c23a2a7f12fa54d3f21c4b36b8247e88e5992975a10ba616c',
'HTTPS' => 'on',
'SERVER_PORT' => '443',
'SERVER_NAME' => 'service.example.com',
);
$keyDB = array('service_api_key' => 'service_secret');
$this->createEscher('eu/service/ems_request', new DateTime('20150310T173248Z', new DateTimeZone('GMT')))->authenticate($keyDB, $serverVars);
}

/**
* @test
*/
public function itShouldValidatePresignedUrlRequestWithIndexedArray()
{
$serverVars = array(
'REQUEST_TIME' => $this->strtotime('20150310T173248Z'),
'REQUEST_METHOD' => 'GET',
'HTTP_HOST' => 'service.example.com',
'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=utf-8',
'REQUEST_URI' => '/login?id=12345678&domain=login.example.com&redirect_to=https%3A%2F%2Fhome.dev%2Fbootstrap.php%3Fr%3Dservice%2Findex%26service%3Dservice_name&param1%5B0%5D=1&param1%5B1%5D=2%3F&X-EMS-Algorithm=EMS-HMAC-SHA256&X-EMS-Credentials=service_api_key%2F20150310%2Feu%2Fservice%2Fems_request&X-EMS-Date=20150310T173248Z&X-EMS-Expires=86400&X-EMS-SignedHeaders=host&X-EMS-Signature=196bc22e36ea13d2bfe59c3fb42fbf67a09ec501a79924284d9281d7d8c773ce',
'HTTPS' => 'on',
'SERVER_PORT' => '443',
'SERVER_NAME' => 'service.example.com',
);
$keyDB = array('service_api_key' => 'service_secret');
$this->createEscher('eu/service/ems_request', new DateTime('20150310T173248Z', new DateTimeZone('GMT')))->authenticate($keyDB, $serverVars);
}

/**
* @test
*/
public function itShouldValidatePresignedUrlIfSignatureIsTheFirstParam()
{
$serverVars = array(
'REQUEST_TIME' => $this->strtotime('20150310T173248Z'),
'REQUEST_METHOD' => 'GET',
'HTTP_HOST' => 'service.example.com',
'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=utf-8',
'REQUEST_URI' => '/login?X-EMS-Signature=196bc22e36ea13d2bfe59c3fb42fbf67a09ec501a79924284d9281d7d8c773ce&id=12345678&domain=login.example.com&redirect_to=https%3A%2F%2Fhome.dev%2Fbootstrap.php%3Fr%3Dservice%2Findex%26service%3Dservice_name&param1%5B0%5D=1&param1%5B1%5D=2%3F&X-EMS-Algorithm=EMS-HMAC-SHA256&X-EMS-Credentials=service_api_key%2F20150310%2Feu%2Fservice%2Fems_request&X-EMS-Date=20150310T173248Z&X-EMS-Expires=86400&X-EMS-SignedHeaders=host',
'HTTPS' => 'on',
'SERVER_PORT' => '443',
'SERVER_NAME' => 'service.example.com',
);
$keyDB = array('service_api_key' => 'service_secret');
$this->createEscher('eu/service/ems_request', new DateTime('20150310T173248Z', new DateTimeZone('GMT')))->authenticate($keyDB, $serverVars);
}

/**
* @test
*/
public function itShouldValidatePresignedUrlIfSignatureIsInTheMiddleOfTheQueryString()
{
$serverVars = array(
'REQUEST_TIME' => $this->strtotime('20150310T173248Z'),
'REQUEST_METHOD' => 'GET',
'HTTP_HOST' => 'service.example.com',
'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=utf-8',
'REQUEST_URI' => '/login?id=12345678&domain=login.example.com&X-EMS-Signature=196bc22e36ea13d2bfe59c3fb42fbf67a09ec501a79924284d9281d7d8c773ce&redirect_to=https%3A%2F%2Fhome.dev%2Fbootstrap.php%3Fr%3Dservice%2Findex%26service%3Dservice_name&param1%5B0%5D=1&param1%5B1%5D=2%3F&X-EMS-Algorithm=EMS-HMAC-SHA256&X-EMS-Credentials=service_api_key%2F20150310%2Feu%2Fservice%2Fems_request&X-EMS-Date=20150310T173248Z&X-EMS-Expires=86400&X-EMS-SignedHeaders=host',
'HTTPS' => 'on',
'SERVER_PORT' => '443',
'SERVER_NAME' => 'service.example.com',
);
$keyDB = array('service_api_key' => 'service_secret');
$this->createEscher('eu/service/ems_request', new DateTime('20150310T173248Z', new DateTimeZone('GMT')))->authenticate($keyDB, $serverVars);
}

private function strtotime($dateString)
{
return EscherUtils::parseLongDate($dateString)->format('U');
}
}


0 comments on commit 8017fa1

Please sign in to comment.