From b909452080aa8d517b1acc740d31451677a2f927 Mon Sep 17 00:00:00 2001 From: Vaibhav Chopra Date: Sun, 10 May 2026 20:34:06 +0530 Subject: [PATCH 1/3] test: add negative-path crypto utility tests Add comprehensive tests for signature verification edge cases: - Empty signature rejection - Wrong length signature rejection - Non-hex signature rejection - Tampered valid-length hex signature rejection - Valid dynamic signature acceptance - Special characters in payload - Unicode in payload Co-Authored-By: Claude Opus 4.7 --- tests/SignatureVerificationNegativeTest.php | 119 ++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 tests/SignatureVerificationNegativeTest.php diff --git a/tests/SignatureVerificationNegativeTest.php b/tests/SignatureVerificationNegativeTest.php new file mode 100644 index 0000000..6402b31 --- /dev/null +++ b/tests/SignatureVerificationNegativeTest.php @@ -0,0 +1,119 @@ +expectException(SignatureVerificationError::class); + + $this->api->utility->verifyWebhookSignature( + $this->webhookPayload, + '', + $this->webhookSecret + ); + } + + /** + * Test that wrong length signature is rejected + */ + public function testWrongLengthSignatureRejected() + { + $this->expectException(SignatureVerificationError::class); + + $this->api->utility->verifyWebhookSignature( + $this->webhookPayload, + 'abc123', + $this->webhookSecret + ); + } + + /** + * Test that non-hex signature is rejected + */ + public function testNonHexSignatureRejected() + { + $this->expectException(SignatureVerificationError::class); + + $nonHexSig = str_repeat('z', 64); + $this->api->utility->verifyWebhookSignature( + $this->webhookPayload, + $nonHexSig, + $this->webhookSecret + ); + } + + /** + * Test that tampered valid-length hex signature is rejected + */ + public function testTamperedValidHexSignatureRejected() + { + $this->expectException(SignatureVerificationError::class); + + $tamperedSig = str_repeat('a', 64); + $this->api->utility->verifyWebhookSignature( + $this->webhookPayload, + $tamperedSig, + $this->webhookSecret + ); + } + + /** + * Test that dynamically generated valid signature is accepted + */ + public function testValidDynamicSignatureAccepted() + { + $validSig = hash_hmac('sha256', $this->webhookPayload, $this->webhookSecret); + + $this->assertNull($this->api->utility->verifyWebhookSignature( + $this->webhookPayload, + $validSig, + $this->webhookSecret + )); + } + + /** + * Test signature verification with special characters in payload + */ + public function testSpecialCharsInPayload() + { + $specialPayload = '{"event":"payment","data":{"notes":"Test & "}}'; + $validSig = hash_hmac('sha256', $specialPayload, $this->webhookSecret); + + $this->assertNull($this->api->utility->verifyWebhookSignature( + $specialPayload, + $validSig, + $this->webhookSecret + )); + } + + /** + * Test signature verification with unicode in payload + */ + public function testUnicodeInPayload() + { + $unicodePayload = '{"event":"payment","data":{"name":"日本語テスト"}}'; + $validSig = hash_hmac('sha256', $unicodePayload, $this->webhookSecret); + + $this->assertNull($this->api->utility->verifyWebhookSignature( + $unicodePayload, + $validSig, + $this->webhookSecret + )); + } +} From 004e675bbecb27dfc8660df2c26974c6c1b61e34 Mon Sep 17 00:00:00 2001 From: Vaibhav Chopra Date: Wed, 13 May 2026 12:28:46 +0530 Subject: [PATCH 2/3] Add CI and composer updates for PHP 8.2+ compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update GitHub Actions to v4 - Test matrix: 8.2, 8.3, 8.4, 8.5 (8.1 is EOL) - Fix kint package: raveren/kint → kint-php/kint - Update PHPUnit ^9 → ^10.5 - Rename testNonHexSignatureRejected → testWrongValueSignatureRejected Co-Authored-By: Claude Opus 4.7 --- .github/workflows/ci.yml | 18 +++++++++++------- composer.json | 6 +++--- tests/SignatureVerificationNegativeTest.php | 9 +++++---- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 869955d..5dad7ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,29 +9,33 @@ on: branches: - master jobs: - run: + test: runs-on: ubuntu-latest + strategy: + matrix: + php-version: ['8.2', '8.3', '8.4', '8.5'] steps: - name: Checkout - uses: actions/checkout@v2 - - name: Set up php 8.0 + uses: actions/checkout@v4 + - name: Set up PHP ${{ matrix.php-version }} uses: shivammathur/setup-php@v2 with: - php-version: '8.0' + php-version: ${{ matrix.php-version }} + coverage: xdebug - name: 'Create env file' run: | touch ${{ github.workspace }}/tests/.env echo RAZORPAY_API_KEY=${{ secrets.RAZORPAY_API_KEY }} >> ${{ github.workspace }}/tests/.env echo RAZORPAY_API_SECRET=${{ secrets.RAZORPAY_API_SECRET }} >> ${{ github.workspace }}/tests/.env - cat ${{ github.workspace }}/tests/.env - name: Install dependencies run: composer self-update && composer install && composer require vlucas/phpdotenv && composer dump-autoload - name: Run tests and collect coverage - run: vendor/bin/phpunit ./tests/CoverageTest.php --coverage-clover coverage.xml . + run: vendor/bin/phpunit ./tests/CoverageTest.php --coverage-clover coverage.xml env: RAZORPAY_API_KEY: ${{ secrets.RAZORPAY_API_KEY }} RAZORPAY_API_SECRET: ${{ secrets.RAZORPAY_API_SECRET }} RAZORPAY_PARTNER_API_KEY: ${{ secrets.RAZORPAY_PARTNER_API_KEY }} RAZORPAY_PARTNER_API_SECRET: ${{ secrets.RAZORPAY_PARTNER_API_SECRET }} - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + if: matrix.php-version == '8.5' + uses: codecov/codecov-action@v4 diff --git a/composer.json b/composer.json index 2ce0f7d..f8a055d 100644 --- a/composer.json +++ b/composer.json @@ -23,13 +23,13 @@ "homepage": "https://docs.razorpay.com", "license": "MIT", "require": { - "php": ">=7.3", + "php": ">=8.2", "rmccue/requests": "^2.0", "ext-json": "*" }, "require-dev": { - "raveren/kint": "1.*", - "phpunit/phpunit": "^9" + "kint-php/kint": "^5.0", + "phpunit/phpunit": "^10.5" }, "autoload": { "psr-4": { diff --git a/tests/SignatureVerificationNegativeTest.php b/tests/SignatureVerificationNegativeTest.php index 6402b31..3f6361c 100644 --- a/tests/SignatureVerificationNegativeTest.php +++ b/tests/SignatureVerificationNegativeTest.php @@ -44,16 +44,17 @@ public function testWrongLengthSignatureRejected() } /** - * Test that non-hex signature is rejected + * Test that wrong value signature is rejected + * (rejected because value doesn't match, not because SDK validates hex format) */ - public function testNonHexSignatureRejected() + public function testWrongValueSignatureRejected() { $this->expectException(SignatureVerificationError::class); - $nonHexSig = str_repeat('z', 64); + $wrongSig = str_repeat('z', 64); $this->api->utility->verifyWebhookSignature( $this->webhookPayload, - $nonHexSig, + $wrongSig, $this->webhookSecret ); } From b60896ae0ef81c7ad72bf4fab093e806d1900e83 Mon Sep 17 00:00:00 2001 From: Vaibhav Chopra Date: Wed, 13 May 2026 12:30:34 +0530 Subject: [PATCH 3/3] Use PHPUnit 9.6 instead of 10.5 PHPUnit 10 changed TestCase constructor signature, which breaks existing tests that instantiate test classes directly. Co-Authored-By: Claude Opus 4.7 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f8a055d..5a2aca8 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ }, "require-dev": { "kint-php/kint": "^5.0", - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^9.6" }, "autoload": { "psr-4": {