diff --git a/src/signing/RequestSigner.php b/src/signing/RequestSigner.php index 5846a94c..8ce91c56 100644 --- a/src/signing/RequestSigner.php +++ b/src/signing/RequestSigner.php @@ -36,6 +36,7 @@ public function sign(RequestInterface $request): RequestInterface 'keyid' => $this->keyId, 'created' => $created, 'expires' => $created + $this->expiresAfter, + 'tag' => 'craft-cloud', ], ); diff --git a/tests/unit/RequestSignerTest.php b/tests/unit/RequestSignerTest.php index ded73ebd..ae1cbe9f 100644 --- a/tests/unit/RequestSignerTest.php +++ b/tests/unit/RequestSignerTest.php @@ -9,6 +9,7 @@ use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use HttpMessageSignatures\Algorithm\HmacSha256; +use HttpMessageSignatures\Exception\VerificationException; use HttpMessageSignatures\Verifier; use Psr\Http\Message\RequestInterface; @@ -46,6 +47,19 @@ public function testCreatesHandlerStackForSignedRequests(): void $this->assertSignedRequest($capturedRequest); } + public function testRejectsTamperedSignatureTag(): void + { + $request = (new RequestSigner('test-signing-key')) + ->sign(new Request('GET', 'https://example.test/status')); + $request = $request->withHeader( + 'Signature-Input', + str_replace('tag="craft-cloud"', 'tag="other"', $request->getHeaderLine('Signature-Input')), + ); + + $this->expectException(VerificationException::class); + (new Verifier(new HmacSha256('test-signing-key')))->verify($request); + } + private function assertSignedRequest(RequestInterface $request): void { $this->assertNotSame('', $request->getHeaderLine('Signature')); @@ -57,6 +71,7 @@ private function assertSignedRequest(RequestInterface $request): void $this->assertStringContainsString('"@target-uri"', $signatureInput); $this->assertStringContainsString('alg="hmac-sha256"', $signatureInput); $this->assertStringContainsString('keyid="hmac"', $signatureInput); + $this->assertStringContainsString('tag="craft-cloud"', $signatureInput); $matches = []; $this->assertSame(1, preg_match('/created=(\d+);expires=(\d+)/', $signatureInput, $matches));