Skip to content

tls: throw on invalid ALPNProtocols instead of aborting - #65076

Open
sankalpsthakur wants to merge 6 commits into
nodejs:mainfrom
sankalpsthakur:fix/65069-alpn-sigabrt
Open

tls: throw on invalid ALPNProtocols instead of aborting#65076
sankalpsthakur wants to merge 6 commits into
nodejs:mainfrom
sankalpsthakur:fix/65069-alpn-sigabrt

Conversation

@sankalpsthakur

Copy link
Copy Markdown

Fixes #65069

tls.connect() with malformed ALPNProtocols (e.g. [''] or invalid wire format buffers like Buffer.from([0])) aborts the process with SIGABRT. The failure is CHECK_EQ(0, SSL_set_alpn_protos(...)) in TLSWrap::SetALPNProtocols when OpenSSL rejects the malformed list.

This change replaces the hard abort with THROW_ERR_INVALID_ARG_VALUE so invalid input throws a recoverable JavaScript exception. Valid inputs are unchanged; e.g. ['h2','http/1.1'] and wire buffers produced by convertProtocols continue to work.

Repro: node -e "require('node:tls').connect({ host: '127.0.0.1', port: 9999, ALPNProtocols: [''] })"

Before: SIGABRT exit 134
After: throws ERR_INVALID_ARG_VALUE

Assisted-by: Codex

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/crypto

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run. labels Aug 6, 2026

@pimterry pimterry left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking at this @sankalpsthakur! I agree it'd be good to fix, but I think there's a different approach that would cover the server case too and be a bit cleaner.

We do also need a test covering this, either as a new test or extending any existing validation tests we have here.

Comment thread src/crypto/crypto_tls.cc Outdated
sankalpsthakur pushed a commit to sankalpsthakur/node that referenced this pull request Aug 6, 2026
Address review feedback on nodejs#65076: move validation closer to call
site in convertALPNProtocols so both client and server are covered
and fail early. Empty string protocols now throw before reaching
OpenSSL; wire-format buffers are validated for truncated/zero-length
entries. C++ defense (THROW_ERR_INVALID_ARG_VALUE) remains for safety.

Refs: nodejs#65076
sankalpsthakur pushed a commit to sankalpsthakur/node that referenced this pull request Aug 6, 2026
@sankalpsthakur

Copy link
Copy Markdown
Author

Updated per review: validation now in lib/tls.js convertALPNProtocols (covers client and server, fails early), C++ defense kept, added test covering [''] and malformed buffers (Buffer.from([0]), [2,0x61], [1,0x61,0x62]). Ready for re-review.

sankalpsthakur added 4 commits August 6, 2026 18:12
Fixes nodejs#65069

tls.connect() with malformed ALPNProtocols (empty string, invalid
wire format buffers) hits CHECK_EQ(0, SSL_set_alpn_protos(...)) and
aborts the process with SIGABRT. Replace the hard abort with
THROW_ERR_INVALID_ARG_VALUE so invalid input throws a recoverable
JavaScript exception.

Assisted-by: Codex
Signed-off-by: sankalpsthakur <sankalp@example.com>
Address review feedback on nodejs#65076: move validation closer to call
site in convertALPNProtocols so both client and server are covered
and fail early. Empty string protocols now throw before reaching
OpenSSL; wire-format buffers are validated for truncated/zero-length
entries. C++ defense (THROW_ERR_INVALID_ARG_VALUE) remains for safety.

Refs: nodejs#65076
Signed-off-by: Sankalp Thakur <sankalp@example.com>
@sankalpsthakur
sankalpsthakur force-pushed the fix/65069-alpn-sigabrt branch from dab0602 to af6b21f Compare August 6, 2026 12:42
@sankalpsthakur

Copy link
Copy Markdown
Author

Thanks for the feedback. I moved validation into convertALPNProtocols so both client and server fail early before reaching OpenSSL, and kept the C++ check as a defense in depth. Empty string protocols now throw via convertProtocols and wire format buffers are validated for empty, zero length and truncated cases. Added test coverage for the repro cases from #65069. I fixed the lint and formatting issues as well and rebased onto latest main.

Comment thread lib/tls.js Outdated
Comment thread src/crypto/crypto_tls.cc Outdated
Empty ALPN buffer/array means skip ALPN (same as historical
behavior for []). Zero-length protocol entries and malformed
wire buffers still throw from convertALPNProtocols.

Revert the C++ THROW_ERR_INVALID_ARG_VALUE back to CHECK_EQ:
after JS validation, a non-zero SSL_set_alpn_protos return is
an internal invariant failure, not user-facing input.

Refs: nodejs#65076
@sankalpsthakur

sankalpsthakur commented Aug 7, 2026

Copy link
Copy Markdown
Author

@pimterry empty [] / empty buffer allowed again (skip ALPN). C++ is CHECK_EQ again, no user throw there. still reject [''] and bad wire buffers in convertALPNProtocols. 6e497bb.

@sankalpsthakur

sankalpsthakur commented Aug 8, 2026

Copy link
Copy Markdown
Author

@pimterry empty ALPN skip, convertALPNProtocols validation, CHECK_EQ, and tests are on latest head. Ready when you have a moment.

@pimterry pimterry added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Aug 9, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 9, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@sankalpsthakur

sankalpsthakur commented Aug 9, 2026

Copy link
Copy Markdown
Author

CI job 75694 ran on 6e497bb before the fixture fix. That commit still used invalid ALPN bytes (abcd) in test-tls-basic-validations.js, so the reds there are expected.

193e77b uses valid length-prefixed fixtures (same copy-isolation check). Could someone re-run CI on current HEAD? Thanks.

@codecov

codecov Bot commented Aug 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.30%. Comparing base (ee64033) to head (193e77b).
⚠️ Report is 57 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main   #65076    +/-   ##
========================================
  Coverage   90.29%   90.30%            
========================================
  Files         759      759            
  Lines      247754   248355   +601     
  Branches    46721    46857   +136     
========================================
+ Hits       223708   224270   +562     
+ Misses      15521    15514     -7     
- Partials     8525     8571    +46     
Files with missing lines Coverage Δ
lib/tls.js 93.47% <100.00%> (+0.33%) ⬆️

... and 61 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pimterry pimterry added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run. request-ci Add this label to start a Jenkins CI on a PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tls.connect() aborts process on malformed ALPNProtocols instead of throwing an error

4 participants