diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4232a6f..15e531a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,12 +14,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x, 14.x, 16.x, 18.x, 19,x] + node-version: [12.x, 14.x, 16.x, 18.x, 19.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' @@ -40,9 +40,9 @@ jobs: needs: test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: sudo apt-get install -y oathtool - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v4 with: node-version: 16 registry-url: https://registry.npmjs.org/ diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 3f165c1..a653bd1 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -20,9 +20,9 @@ jobs: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' diff --git a/lib/utils/razorpay-utils.js b/lib/utils/razorpay-utils.js index 6ba6468..bdf0251 100644 --- a/lib/utils/razorpay-utils.js +++ b/lib/utils/razorpay-utils.js @@ -95,11 +95,23 @@ function validateWebhookSignature (body, signature, secret) { body = body.toString(); - var expectedSignature = crypto.createHmac('sha256', secret) - .update(body) - .digest('hex'); + // Compute HMAC as raw bytes (32 bytes for SHA-256) + var expectedBuffer = crypto.createHmac('sha256', secret) + .update(body) + .digest(); + + // Decode incoming hex signature to raw bytes + // Note: Buffer.from(hex) returns empty/partial Buffer on invalid hex (no throw), + // which is caught by the length check below + var signatureBuffer = Buffer.from(signature, 'hex'); + + // Both should be 32 bytes (SHA-256 output) + if (expectedBuffer.length !== signatureBuffer.length) { + return false; + } - return expectedSignature === signature; + // Constant-time comparison to prevent timing attacks + return crypto.timingSafeEqual(expectedBuffer, signatureBuffer); } function validatePaymentVerification(params={}, signature, secret){