Skip to content

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

@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
    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