PluginProbe ʕ •ᴥ•ʔ
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization / 1.19.6
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization v1.19.6
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 1 year ago Base.php 8 months ago Cache.php 1 year ago ExcludedUrls.php 1 year ago Excludes.php 1 year ago Integration.php 1 year ago RemoteConfigFetcher.php 1 year ago RequestMaker.php 1 year ago Response.php 1 year ago ResponseStatus.php 1 year ago SafeMode.php 1 year ago SecureRequestMaker.php 1 year ago SignedBase.php 1 year ago Stats.php 1 year ago Tagger.php 1 year ago Url.php 1 year ago VariationCookie.php 1 year ago Varnish.php 1 year ago Warmup.php 1 year ago Webhook.php 1 year 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 }