Skip to content

tls.connect() options ciphers no longer accept null as a valid value in node v15.3.0 #36292

Closed
@T1B0

Description

@T1B0
  • Version:

node v15.3.0

  • Platform:

Reproduced on Linux 5.9.0-3-amd64 #1 SMP Debian 5.9.9-1 (2020-11-19) x86_64 GNU/Linux - but probably applicable on all platform

  • Subsystem:

tls.connect() options

What steps will reproduce the bug?

Before version 15.3.0 tls.connect (also accepted by https.request() ) option value null was accepted as falsy value for the cipthers option.
As of version 15.3.0, passing option.ciphers = null throw an error.

case.js (tweaked from https://nodejs.org/api/https.html#https_https_request_options_callback )

const https = require('https');

const options = {
  hostname: 'nodejs.org',
  port: 443,
  path: '/en/',
  ciphers: null,
  method: 'GET'
};

const req = https.request(options, (res) => {
  console.log('statusCode:', res.statusCode);
  console.log('headers:', res.headers);

  res.on('data', (d) => {
    process.stdout.write(d);
  });
});

req.on('error', (e) => {
  console.error(e);
});

req.end();

You get a connection that end up with 200 OK using this v15.2.1 dockerfile

FROM node:15.2.1-buster-slim

COPY ./case.js ./

CMD node case.js

but it will throw an error with a v15.3.0 dockerfile

FROM node:15.3.0-buster-slim

COPY ./case.js ./

CMD node case.js

How often does it reproduce? Is there a required condition?

throw an error 100% of the time on v15.3.0 with options.ciphers = null

What is the expected behavior?

I have no doubt it is a changing behavior, but i don't know what was the expected behavior of an undocumented cipher option value in the first place either. i just know that it used to work.

What do you see instead?

behavior changed, it now throw an error :

node:internal/validators:123
    throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "options.ciphers" property must be of type string. Received null
    at new NodeError (node:internal/errors:278:15)
    at validateString (node:internal/validators:123:11)
    at Object.createSecureContext (node:_tls_common:267:5)
    at Object.connect (node:_tls_wrap:1581:48)
    at Agent.createConnection (node:https:129:22)
    at Agent.createSocket (node:_http_agent:323:26)
    at Agent.addRequest (node:_http_agent:274:10)
    at new ClientRequest (node:_http_client:318:16)
    at Object.request (node:https:313:10)
    at Object.<anonymous> (/case.js:11:19) {
  code: 'ERR_INVALID_ARG_TYPE'

Additional information

The point of this report is to warn about this non-obvious breaking behavior change and not to say it's not acceptable/legit api change.

ps: Thanks to @jasnell for encouraging me to write an issue 👍

Metadata

Metadata

Assignees

No one assigned

    Labels

    tlsIssues and PRs related to the tls subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions