Skip to content

ReceiptUtility.extractTransactionIdFromAppReceipt throws "too short ASN.1 value" on Xcode receipts with jsrsasign >= 11.1.2 #417

@Forbiddem

Description

@Forbiddem

Summary

A fresh install of @apple/app-store-server-library@3.1.0 resolves jsrsasign to 11.1.3 (the package declares "jsrsasign": "^11.0.0"). With jsrsasign >= 11.1.2, ReceiptUtility.extractTransactionIdFromAppReceipt() throws Error: too short ASN.1 value when parsing Xcode-generated app receipts (indefinite-length ASN.1 encoding). Production App Store receipts (definite-length) are unaffected.

The repository CI passes because the committed yarn.lock pins jsrsasign to 11.1.1; that lockfile is not delivered to consumers, so end users who install the library today get the broken 11.1.3.

Reproduction

mkdir repro && cd repro && npm init -y
npm install @apple/app-store-server-library@3.1.0
node -e "console.log('jsrsasign:', require('jsrsasign/package.json').version)"
# -> jsrsasign: 11.1.3
const { ReceiptUtility } = require('@apple/app-store-server-library');
const fs = require('fs');
// tests/resources/xcode/xcode-app-receipt-with-transaction from this repo
const receipt = fs.readFileSync('xcode-app-receipt-with-transaction', 'utf8').trim();
new ReceiptUtility().extractTransactionIdFromAppReceipt(receipt);
// -> Error: too short ASN.1 value

The two existing Xcode receipt unit tests fail on a fresh install:

● Receipt Utility Tets › should not extract a transaction id from an xcode receipt without a transaction
● Receipt Utility Tets › should extract a transaction id from an xcode receipt with a transaction

  receipt_utility.ts:41
    let receiptInfo = ASN1HEX.getVbyList(Buffer.from(appReceipt, 'base64').toString('hex'), 0, [1, 0, 2, 1, 0])
  at Object.ASN1HEX.getChildIdx (node_modules/jsrsasign/lib/jsrsasign.js)

Version bisect

jsrsasign tests/unit-tests/receipt_utility.test.ts
11.1.1 3/3 pass
11.1.2 2 fail (both Xcode receipt cases)
11.1.3 2 fail (both Xcode receipt cases)

Root cause

jsrsasign 11.1.2 tightened ASN.1 length validation in ASN1HEX (a stricter "too short ASN.1 value" check in the getChildIdx code path). ReceiptUtility.extractTransactionIdFromAppReceipt() handles the indefinite-length encoding (80 00) used by Xcode receipts by monkey-patching ASN1HEX.getVblen and ASN1HEX.getLblen. The new strict check in 11.1.2+ is reached on a code path that those two patched functions no longer compensate for, so parsing throws instead of completing.

Impact

extractTransactionIdFromAppReceipt() is a documented public API. On a fresh install it fails for Xcode / StoreKit local-testing receipts, which breaks local IAP testing workflows for consumers of the library. This is a functional/compatibility regression, not a security issue.

Possible fixes

  • Pin jsrsasign to the last known-good version: "jsrsasign": "11.1.1" (also the version where the prior jsrsasign advisories were fixed). Simple, but blocks future patch updates.
  • Update receipt_utility.ts so the indefinite-length handling stays compatible with jsrsasign >= 11.1.2, then raise the floor accordingly.

Happy to open a PR for whichever direction the maintainers prefer.

Environment

  • @apple/app-store-server-library: 3.1.0
  • jsrsasign: 11.1.3 (resolved from declared ^11.0.0)
  • Node.js: v22.x (also reproduced on v24.x)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions