PluginProbe ʕ •ᴥ•ʔ
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization / 1.5.19
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization v1.5.19
1.19.8 1.19.7 1.19.6 1.19.5 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.12.0 1.13.0 1.14.0 1.15.0 1.15.1 1.15.2 1.15.3 1.16.0 1.16.1 1.16.2 1.16.3 1.16.4 1.16.5 1.16.6 1.16.7 1.16.8 1.17.0 1.17.6 1.17.7 1.17.8 1.17.9 1.18.0 1.18.1 1.18.2 1.18.3 1.18.4 1.18.5 1.18.6 1.18.7 1.18.8 1.18.9 1.19.0 1.19.1 1.19.2 1.19.3 1.19.4 1.3.19 1.3.20 1.4.0 1.4.1 1.5.0 1.5.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.16 1.5.17 1.5.18 1.5.19 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.7.0 1.7.1 1.8.0 1.8.1 1.8.3 1.9.0 1.9.1 1.9.2
nitropack / nitropack-sdk / NitroPack / SDK / Api / SignedBase.php
nitropack / nitropack-sdk / NitroPack / SDK / Api Last commit date
AdditionalDomains.php 3 years ago Base.php 3 years ago Cache.php 3 years ago ExcludedUrls.php 3 years ago Integration.php 6 years ago RemoteConfigFetcher.php 4 years ago RequestMaker.php 5 years ago Response.php 6 years ago ResponseStatus.php 6 years ago SafeMode.php 5 years ago SecureRequestMaker.php 5 years ago SignedBase.php 3 years ago Stats.php 6 years ago Tagger.php 3 years ago Url.php 6 years ago VariationCookie.php 6 years ago Varnish.php 3 years ago Warmup.php 6 years ago Webhook.php 6 years ago
SignedBase.php
136 lines
1 <?php
2 namespace NitroPack\SDK\Api;
3 use \NitroPack\Url\Url;
4
5 // Src: http://php.net/manual/en/function.hash-equals.php
6 if(!function_exists('hash_equals')) {
7 function hash_equals($str1, $str2) {
8 if(strlen($str1) != strlen($str2)) {
9 return false;
10 } else {
11 $res = $str1 ^ $str2;
12 $ret = 0;
13 for($i = strlen($res) - 1; $i >= 0; $i--) $ret |= ord($res[$i]);
14 return !$ret;
15 }
16 }
17 }
18
19 class SignedBase extends Base {
20
21 private static $signatureHeader = 'X-Nitro-Signature';
22 private static $algorithm = 'sha512';
23
24 protected $secret;
25
26 public function __construct($siteId, $siteSecret) {
27 parent::__construct($siteId);
28 $this->secret = $siteSecret;
29 }
30
31 protected function addToBacklog($entry) {
32 $entry["siteSecret"] = $this->secret;
33 parent::addToBacklog($entry);
34 }
35
36 protected function makeRequest($path, $headers = array(), $cookies = array(), $type = 'GET', $bodyData=array(), $async = false, $verifySSL = false) {
37 // calculate request signature
38 $url = new Url($this->baseUrl . $path);
39 $noParamsPath = $url->getPath();
40 $params = array();
41 if(!is_null($url->getQuery())) {
42 parse_str($url->getQuery(), $params);
43 }
44 $params = $params + $bodyData;
45 $headers[SignedBase::$signatureHeader] = static::calculateRequestSignature($noParamsPath, $params, static::getSignatureHeaders($headers), $this->secret);
46
47 // make the request
48 $http = parent::makeRequest($path, $headers, $cookies, $type, $bodyData, $async, $verifySSL);
49
50 if ($async) {
51 $http->setOnCompleteCallback(array($this, 'verifySignature'));
52 } else {
53 $this->verifySignature($http);
54 }
55
56 return $http;
57 }
58
59 protected function verifySignature($http) {
60 if ($http->getStatusCode() === ResponseStatus::OK) {
61 $responseHeaders = $http->getHeaders();
62 if (!isset($responseHeaders[strtolower(SignedBase::$signatureHeader)])) {
63 throw new \RuntimeException('Server did not include a signature for a request that was expected to be signed');
64 }
65 $signature = static::calculateResponseSignature($http->getBody(), static::getSignatureHeaders($responseHeaders), $this->secret);
66 if (!hash_equals($signature, $responseHeaders[strtolower(SignedBase::$signatureHeader)])) { // TODO move RemoteConfigFetcher::internal_hash_equals to a place where its accessible everywhere and use it here
67 throw new \RuntimeException('Server signature is wrong'); // TODO better message
68 }
69 }
70 }
71
72 /** Signature data:
73 * UrlPath|header1:value,header2:value|param1:value,param2:value
74 * if not using headers, we still expect their delimiter UrlPath||param1:value,param2:value
75 */
76 protected static function calculateRequestSignature($urlPath, $parameters, $headers, $secret) {
77 // do not include the header that specifies the signature
78 if (isset($headers[SignedBase::$signatureHeader])) {
79 unset($headers[SignedBase::$signatureHeader]);
80 }
81
82 $data = $urlPath;
83
84 ksort($headers);
85 $headersTemp = [];
86 foreach ($headers as $header => $value) {
87 $headersTemp[] = str_replace('-', '_', strtolower($header)) . ':' . $value;
88 }
89
90 $data .= '|' . implode(',', $headersTemp);
91 $headersTemp = null;
92
93 ksort($parameters);
94 $paramsTemp = [];
95 foreach ($parameters as $param => $value) {
96 if (is_array($value)) {
97 $paramsTemp[] = $param . ':' . json_encode($value);
98 } else {
99 $paramsTemp[] = $param . ':' . $value;
100 }
101 }
102
103 $data .= '|' . implode(',', $paramsTemp);
104 $paramsTemp = null;
105 return SignedBase::hmac($data, $secret);
106 }
107
108 protected static function getSignatureHeaders($headers) {
109 $signatureHeaders = [];
110 foreach ($headers as $header => $value) {
111 if (stripos($header, 'x-nitro-') !== false && strtolower($header) != strtolower(SignedBase::$signatureHeader)) {
112 $signatureHeaders[$header] = $value;
113 }
114 }
115
116 return $signatureHeaders;
117 }
118
119 protected static function calculateResponseSignature($data, $headers, $secret) {
120 ksort($headers);
121 $headersTemp = [];
122 foreach ($headers as $header => $value) {
123 $headersTemp[] = str_replace('-', '_', strtolower($header)) . ':' . $value;
124 }
125
126 $data = implode(',', $headersTemp) . '|' . $data;
127 $headersTemp = null;
128
129 return SignedBase::hmac($data, $secret);
130 }
131
132 private static function hmac($data, $secret) {
133 return hash_hmac(SignedBase::$algorithm, $data, $secret);
134 }
135
136 }