Uh oh!
There was an error while loading. Please reload this page.
tls: throw on invalid ALPNProtocols instead of aborting - #65076
Conversation
nodejs-github-bot
commented
Aug 6, 2026
Review requested:
|
pimterry
left a comment
There was a problem hiding this comment.
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.
Uh oh!
There was an error while loading. Please reload this page.
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
commented
Aug 6, 2026
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. |
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
dab0602 to
af6b21fComparesankalpsthakur
commented
Aug 6, 2026
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. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
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
@pimterry empty ALPN skip, convertALPNProtocols validation, CHECK_EQ, and tests are on latest head. Ready when you have a moment. |
nodejs-github-bot
commented
Aug 9, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@## main #65076 +/- ##
==========================================
+ Coverage 90.12% 90.14% +0.01%
==========================================
Files 751 751 Lines 252425 252625 +200 Branches 47471 47542 +71 ==========================================
+ Hits 227504 227724 +220 + Misses 16216 16200 -16 + Partials 8705 8701 -4
🚀 New features to boost your workflow:
|
82aed18 to
193e77bComparetrivikr
commented
Aug 22, 2026
@sankalpsthakur Can you please rebase? The merge commits don't work with our tooling. |
82aed18 to
1e49721CompareAddress 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
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
commented
Aug 22, 2026
rebased onto main (a48e33f), merge commit dropped, six commits linear now. diff is unchanged: lib/tls.js and the two tls tests. |
1e49721 to
eaaedf8Comparesankalpsthakur
commented
Aug 22, 2026
correction to my last note: squashed to a single commit (eaaedf8) rather than the six i mentioned, message rewritten to describe the final js-only validation since the earlier ones still described the reverted c++ change. diff is unchanged. |
trivikr
commented
Aug 22, 2026
@sankalpsthakur Can you please sign the commit? It's required as per instructions
|
73e91cb to
4e001a7Comparetls.connect() with malformed ALPNProtocols hit CHECK_EQ(0, SSL_set_alpn_protos(...)) in the C++ layer and aborted the process with SIGABRT. Validate in JS instead, in convertALPNProtocols, so both client and server fail early with a recoverable ERR_INVALID_ARG_VALUE: - zero-length string protocols now throw from convertProtocols - wire-format buffers are checked for zero-length and truncated entries - an empty buffer or array is still accepted and means skip ALPN, matching the historical behavior for [] The C++ CHECK_EQ is left unchanged: once JS has validated the input, a non-zero SSL_set_alpn_protos return is an internal invariant failure rather than user-facing input. Fixes: nodejs#65069 Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com>
4e001a7 to
e074e05Comparesankalpsthakur
commented
Aug 23, 2026
Signed-off-by is on e074e05, author Sankalp Thakur sankalphimself@gmail.com. |
nodejs-github-bot
commented
Aug 23, 2026
nodejs-github-bot
commented
Aug 24, 2026
Uh oh!
There was an error while loading. Please reload this page.
nodejs-github-bot
commented
Aug 24, 2026
Landed in 278ead1 |
tls.connect() with malformed ALPNProtocols hit CHECK_EQ(0, SSL_set_alpn_protos(...)) in the C++ layer and aborted the process with SIGABRT. Validate in JS instead, in convertALPNProtocols, so both client and server fail early with a recoverable ERR_INVALID_ARG_VALUE: - zero-length string protocols now throw from convertProtocols - wire-format buffers are checked for zero-length and truncated entries - an empty buffer or array is still accepted and means skip ALPN, matching the historical behavior for [] The C++ CHECK_EQ is left unchanged: once JS has validated the input, a non-zero SSL_set_alpn_protos return is an internal invariant failure rather than user-facing input. Fixes: #65069 Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com> PR-URL: #65076 Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
tls.connect() with malformed ALPNProtocols hit CHECK_EQ(0, SSL_set_alpn_protos(...)) in the C++ layer and aborted the process with SIGABRT. Validate in JS instead, in convertALPNProtocols, so both client and server fail early with a recoverable ERR_INVALID_ARG_VALUE: - zero-length string protocols now throw from convertProtocols - wire-format buffers are checked for zero-length and truncated entries - an empty buffer or array is still accepted and means skip ALPN, matching the historical behavior for [] The C++ CHECK_EQ is left unchanged: once JS has validated the input, a non-zero SSL_set_alpn_protos return is an internal invariant failure rather than user-facing input. Fixes: #65069 Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com> PR-URL: #65076 Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
tls.connect() with malformed ALPNProtocols hit CHECK_EQ(0, SSL_set_alpn_protos(...)) in the C++ layer and aborted the process with SIGABRT. Validate in JS instead, in convertALPNProtocols, so both client and server fail early with a recoverable ERR_INVALID_ARG_VALUE: - zero-length string protocols now throw from convertProtocols - wire-format buffers are checked for zero-length and truncated entries - an empty buffer or array is still accepted and means skip ALPN, matching the historical behavior for [] The C++ CHECK_EQ is left unchanged: once JS has validated the input, a non-zero SSL_set_alpn_protos return is an internal invariant failure rather than user-facing input. Fixes: #65069 Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com> PR-URL: #65076 Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
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