You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Alert 219 (high, runtime): GHSA-86w9-cpqp-85rv / CVE-2026-85393, "node-forge RSA PKCS#1 v1.5 signature verification accepts extra nested DigestAlgorithm elements", vulnerable range <= 1.4.0. The advisory lists no patched version; the alert resolves because 1.4.2 is outside the vulnerable range.
node-apn uses node-forge only to parse credentials (pem.decode, pem.encode, pki.decryptRsaPrivateKey, asn1.fromDer, pki.certificateFromAsn1, pkcs12.pkcs12FromAsn1, pki.getPublicKeyFingerprint). It never calls verify, so the vulnerable signature verification path isn't reached, and this upgrade is hardening. Token-based (.p8) authentication doesn't use node-forge.
Five other fixes in 1.4.1 apply to node-apn's credential parsing (PEM, ASN.1, PKCS#12, PKCS#7 padding); see Changes and the compatibility check below.
HIGH: ASN.1 resource exhaustion via BIT STRING decoding (GHSA-rhr8-3pm8-cq29). asn1.fromDer() applies the maxDepth limit inside BIT STRING contents and decodes only one level of BIT STRINGs; nested ones stay undecoded. Structures such as SubjectPublicKeyInfo use one level.
HIGH: Regular expression denial of service in PEM decoding (GHSA-7wch-p9px-956x). PEM messages and encapsulated headers are found in linear time. Messages match as before, except that a BEGIN line's label is the shortest one followed by -----.
HIGH: PKCS#12 MAC forgery due to a missing iteration count check (GHSA-jc66-7q78-782g). PKCS#12 MAC iteration counts and PKCS#12 key derivation iteration counts below 1 are rejected.
LOW: ASN.1 OID first arc truncation (GHSA-4642-5mcj-2rqw). asn1.oidToDer() rejects OIDs whose first arc isn't 0, 1 or 2, or whose second arc is over 39 under 0 or 1. A multi-byte first OID subidentifier (e.g. 2.999) is encoded and decoded in base 128.
LOW: Incomplete PKCS#7 padding validation in CBC and ECB decryption (GHSA-2vgq-wchc-25w7). Decryption requires valid PKCS#7 padding: a count from 1 to the block size, with every padding byte equal to the count. This applies when decrypting encrypted PEM keys and PKCS#12 contents. OpenSSL and Keychain exports use PKCS#7 padding.
Not reached by node-apn, which doesn't verify signatures or certificate chains and doesn't use forge's TLS, AES-GCM, HTTP client or RSA key generation:
HIGH: Signature forgery in RSA-PKCS due to an ASN.1 extra field in DigestAlgorithm (CVE-2026-85393, forge advisory GHSA-2g46-22mc-6gwp; alert 219), and HIGH: signature forgery in RSA-PKCS due to non-canonical DigestInfo encoding (GHSA-6qrw-m8cv-hcxf). RSASSA-PKCS1-v1_5 verification requires a canonical DER DigestInfo.
HIGH: Denial of service in TLS record processing via call stack exhaustion (GHSA-hqq3-7jhf-c5jx). Records are processed in a loop instead of recursively.
HIGH: Denial of service in TLS record processing via an interleaved record during a fragmented handshake message (GHSA-8hrf-8g6f-7xwp).
HIGH: basicConstraints bypass via deprecated extension OIDs in certificate chain verification (GHSA-5x38-2vff-x55p). Only OID 2.5.29.19 is used.
MODERATE: Denial of service in the TLS client when the server sends no certificate (GHSA-525v-9gp9-w22h).
MODERATE: pathLenConstraint bypass in certificate chain verification (GHSA-h46v-rmh6-fq4f). It's now enforced for CA certificates without a keyUsage extension.
MODERATE: AES-GCM authentication bypass with an invalid tag length (GHSA-5cwg-6vw7-rj6p). Only the NIST SP 800-38D tag lengths are allowed.
MODERATE: Prototype pollution via Set-Cookie in forge.http (GHSA-6wvx-3r32-xmcg).
LOW: Certificate signature verified with the issuer's signature scheme (GHSA-9wg5-mj3p-v49q).
LOW: Certificate chain verification removes trusted certificates from the CA store (GHSA-4487-j8r4-4g2f).
LOW: Denial of service in BigInteger.modInverse() with negative inputs (GHSA-h6cr-wjv9-3cpp).
[tls] Heartbeat requests received before the first handshake is complete are ignored.
Compatibility check
node-apn's credential parsing was run with node-forge 1.4.0 and 1.4.2: parsePemKey, parsePemCertificate, parsePkcs12, validate, and the full prepare → load → parse → validate flow. The inputs were the 19 credential fixtures in test/, plus 8 files generated with OpenSSL 3.6 from the test certificate and key:
an AES-256-CBC legacy PEM key
PKCS#8 keys, PBES2 AES-256-CBC and unencrypted
PKCS#12 files with OpenSSL 3 defaults (PBES2 AES-256-CBC, SHA-256 MAC), with -legacy, and without a password
openssl pkcs12 PEM output with Bag Attributes text, plain and encrypted
Each PEM input was passed as a string (inline PEM) and as a Buffer (file path or Buffer config). The comparison covered key fingerprints and parameters, certificate validity, environment, subject, issuer, extensions and TBS bytes, and error messages.
Input
Cases
Identical
Differences
Full prepare flow: file paths, Buffers, inline PEM and PFX, with production unset, true and false, at the current date and at a date within the certificates' validity
108
108
None
Valid PEM formatting variants (CRLF, CR, trailing spaces, leading Bag Attributes text, indentation, 76-column and single-line bodies, …), as string and Buffer
336
336
None
Every fixture through every parser, with no, the correct, and a wrong passphrase
292
288
4: a wrong or missing passphrase on an encrypted key now reports unable to parse key, incorrect passphrase instead of unable to parse key, no private key found
Malformed input: truncated, missing END line, mismatched or invalid labels, invalid base64, broken encryption headers, slow-regex patterns, nested BIT STRINGs, damaged PKCS#12
142
135
6: a PEM label containing ----- now reports not a valid PEM file, since RFC 7468 labels can't contain --. 1: a PKCS#12 file with MAC iteration count 0 (GHSA-jc66-7q78-782g), which 1.4.0 parsed, is now rejected as not a PFX/P12 file
200 wrong passphrases on each of 6 encrypted keys (DES-CBC, DES-EDE3-CBC, PKCS#12 PBE 3DES, AES-256-CBC, PBES2 AES-256-CBC)
6
0
1.4.0 reported no private key found for 10–27% of wrong passphrases, because its padding check was lenient. 1.4.2 reports incorrect passphrase for 99–100%
Every valid input gives identical results. All differences are on error paths and in the stricter direction.
Breaking Changes
None
Code Changes Required
None. Only the node-forge entries in package.json and package-lock.json change.
Follow-up
Merging publishes a new @parse/node-apn patch release. @parse/push-adapter and parse-server pin @parse/node-apn, so they need a follow-up @parse/node-apn bump to pick this up.
Summary by CodeRabbit
Maintenance
Updated an underlying application component to a newer version. This release does not add or remove user-facing features, change the interface, or alter any behavior described in the change summary. No additional user-visible changes are noted.
🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review.
Tip
Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
Group code into logical blocks. Add a short comment before each block to explain its purpose.
We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.
Note
Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect.
Caution
Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement. Our CI and AI review are safeguards, not development tools. If many issues are flagged, rethink your development approach. Invest more effort in planning and design rather than using review cycles to fix low-quality code.
No actionable comments were generated in the recent review.
Recent review info
Run configuration
Source mode: Auto
Repository: Unavailable
Branch: Unavailable
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Organization UI
Review profile: CHILL
Plan: Essentials
Run ID: 7e16503f-ce49-489c-a68b-1a9de9dd8246
Commits
Reviewing files that changed from the base of the PR and between 8ef92d6 and f50ba76.
Files selected for processing: 2
package-lock.json
package.json
Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.
Walkthrough
The declared and locked node-forge dependency changes from version 1.4.0 to 1.4.2.
Changes: node-forge dependency update
Layer / File(s)
Summary
Update node-forge version package.json, package-lock.json
The package manifest and lockfile specify node-forge 1.4.2. The lockfile also updates the resolved tarball and integrity hash.
No actionable merge-blocking risk was identified in this dependency update.
Pre-merge checks: 7
Check name
Status
Explanation
Description Check
Check skipped - CodeRabbit’s high-level summary is enabled.
Title check
The title begins with the required fix: prefix, and the first letter after the prefix is capitalized. It accurately describes the dependency update from node-forge 1.4.0 to 1.4.2.
Docstring Coverage
No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Security Check
The pull request changes only the pinned node-forge dependency from 1.4.0 to 1.4.2 in package.json and package-lock.json. The lockfile updates the matching tarball URL and integrity hash. No app…
Engage In Review Feedback
No review feedback required engagement. The supplied review data reports no posted CodeRabbit review threads and zero actionable findings in the current review.
Full details: Docstring Coverage
Explanation
No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 0 files. (2 skipped: 2 unsupported.)
Full details: Security Check
Explanation
The pull request changes only the pinned node-forge dependency from 1.4.0 to 1.4.2 in package.json and package-lock.json. The lockfile updates the matching tarball URL and integrity hash. No application code, scripts, permissions, network behavior, or security-sensitive logic changes. This diff introduces no problematic security pattern.
Finishing Touches
🧪 Generate unit tests (beta)
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Warning
Some tools did not complete. Review the errors below.
ESLint
If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.
package.json
Parsing error: Unexpected token :
Comment @coderabbitai help to get the list of available commands.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security
<= 1.4.0. The advisory lists no patched version; the alert resolves because 1.4.2 is outside the vulnerable range.pem.decode,pem.encode,pki.decryptRsaPrivateKey,asn1.fromDer,pki.certificateFromAsn1,pkcs12.pkcs12FromAsn1,pki.getPublicKeyFingerprint). It never callsverify, so the vulnerable signature verification path isn't reached, and this upgrade is hardening. Token-based (.p8) authentication doesn't use node-forge.Changes
1.4.2
pem.decode()converts non-string input such as aBufferto a string again, as before 1.4.1 (pem.decodethrowsTypeError: str.charAt is not a functionfor Buffer input in 1.4.1 (breaksnode-jose) digitalbazaar/forge#1165, Convert non-string input inpem.decode(). digitalbazaar/forge#1166). The rewritten PEM scanner in 1.4.1 threwTypeError: str.charAt is not a functionfor Buffers. node-apn passes Buffers whencertandkeyare file paths or Buffers, so 1.4.1 alone breaks node-apn's PEM credential parsing; 1.4.2 doesn't.1.4.1 (security release, 17 advisories)
Applies to node-apn's credential parsing:
asn1.fromDer()applies themaxDepthlimit inside BIT STRING contents and decodes only one level of BIT STRINGs; nested ones stay undecoded. Structures such as SubjectPublicKeyInfo use one level.-----.asn1.oidToDer()rejects OIDs whose first arc isn't 0, 1 or 2, or whose second arc is over 39 under 0 or 1. A multi-byte first OID subidentifier (e.g.2.999) is encoded and decoded in base 128.Not reached by node-apn, which doesn't verify signatures or certificate chains and doesn't use forge's TLS, AES-GCM, HTTP client or RSA key generation:
basicConstraintsbypass via deprecated extension OIDs in certificate chain verification (GHSA-5x38-2vff-x55p). Only OID2.5.29.19is used.pathLenConstraintbypass in certificate chain verification (GHSA-h46v-rmh6-fq4f). It's now enforced for CA certificates without akeyUsageextension.Set-Cookieinforge.http(GHSA-6wvx-3r32-xmcg).BigInteger.modInverse()with negative inputs (GHSA-h6cr-wjv9-3cpp).Compatibility check
node-apn's credential parsing was run with node-forge 1.4.0 and 1.4.2:
parsePemKey,parsePemCertificate,parsePkcs12,validate, and the fullprepare→load→parse→validateflow. The inputs were the 19 credential fixtures intest/, plus 8 files generated with OpenSSL 3.6 from the test certificate and key:-legacy, and without a passwordopenssl pkcs12PEM output with Bag Attributes text, plain and encryptedEach PEM input was passed as a string (inline PEM) and as a
Buffer(file path or Buffer config). The comparison covered key fingerprints and parameters, certificate validity, environment, subject, issuer, extensions and TBS bytes, and error messages.prepareflow: file paths, Buffers, inline PEM and PFX, withproductionunset, true and false, at the current date and at a date within the certificates' validityunable to parse key, incorrect passphraseinstead ofunable to parse key, no private key found-----now reportsnot a valid PEM file, since RFC 7468 labels can't contain--. 1: a PKCS#12 file with MAC iteration count 0 (GHSA-jc66-7q78-782g), which 1.4.0 parsed, is now rejected asnot a PFX/P12 fileno private key foundfor 10–27% of wrong passphrases, because its padding check was lenient. 1.4.2 reportsincorrect passphrasefor 99–100%Every valid input gives identical results. All differences are on error paths and in the stricter direction.
Breaking Changes
None
Code Changes Required
None. Only the node-forge entries in
package.jsonandpackage-lock.jsonchange.Follow-up
Merging publishes a new
@parse/node-apnpatch release.@parse/push-adapterandparse-serverpin@parse/node-apn, so they need a follow-up@parse/node-apnbump to pick this up.Summary by CodeRabbit