Node: User defined SSL CA environment variable should always be honored

Created on 9 Aug 2017  路  11Comments  路  Source: nodejs/node

Per @silverwind's request, I'm creating a separate issue that I had brought up over here:

Node.js implements the following environment variables for the user to augment Nodes default certificates list:

https://nodejs.org/api/cli.html#cli_node_extra_ca_certs_file
https://nodejs.org/api/cli.html#cli_ssl_cert_dir_dir
https://nodejs.org/api/cli.html#cli_ssl_cert_file_file

It it explicitly states that if a ca option is directly utilized with the TLS or HTTPSClient module it is overridden. I've run across instances where as an end user, attempting to configure node with my private / internal CA cert, some node module author is somehow overriding this through their own usage of request and thus I have no way to get this to work correctly.

It would seem that if the end user has specified these environment variables that they should not be allowed to be overridden through direct utilization / configuration within code as this allows for a use case where an imported node module can override the user's intention of utilizing specific CA certificates, which is undesirable.

tls

Most helpful comment

Using ca: indicates that the writer of the code wishes to completely control the CAs.

If the author of the code wanted to use sensible defaults (builtin CAs, possibly as modified by env vars), they should not use ca.

Put another way: using ca is an explicit way to NOT use node's CAs... if the code author doesn't even want to allow the well-known and trusted CAs that node provides compiled in, its not so likely that they want to use the ones you just stuck in an env var, frustrating though that may be to you.

You should bring this up with the author.

All 11 comments

Sorry @silverwind but I think you're mistaken on this: programmatic configuration should always trump configuration through the environment.

@bnoordhuis I'm not sure I understand. Isn't the purpose of the environment variable to allow the end user to specify their custom / internal CA certificates to node at runtime to append these to the default node openssl trusted CA certificates?

If we allow node module authors to override this unbeknownst to the end user then the intended behavior of modifying Node's CA certificates is not being honored.

programmatic configuration should always trump configuration through the environment.

I think it depends on the option. A end user wanting to extend the list of trusted CA's via NODE_EXTRA_CA_CERTS should always be able to extend the CA list. If code is able to overrule that, I think that's a pretty clear indication of a bug to me. Maybe someone can show a test case of it happening.

NODE_EXTRA_CA_CERTS extends the default/compiled-in CA list.

Code that explicitly specifies a ca: option is choosing to not use the default list, that means it won't see the compiled-in CAs, _and_ it won't see the ones added to the default list with NODE_EXTRA_CA_CERTS.

It is generally the case that explicit code overrides env, I think the current behaviour is best, and its definitely documented and been like that for a long time.

I do believe that a feature to expose the default list into javascript would be useful, so code could use it explicitly, and perhaps even modify it.

@sam-github I have ran across instances of attempting to utilize other node modules who within their own code either unknowingly or inadvertently are setting this ca option or overwriting this with null on their own. This leads to my attempt of extending these certificates to be futile as they are overwritten due to the behavior of how node will interpret this.

What recourse do I have as an end user to extend the default CA certificate list under this situation.

@matthewwiesen Your only recourse is to bring it up with the the node module authors. If you have specific examples, I'd be interested in seeing them, I could contact the authors, and also generally have a better understanding how TLS is used in node. Generally, the only reason to set the ca option is because you have a private ca, not something that you do in a package for general use, though perhaps people are implementing their own CA configuration mechanisms, which was necessary before if you had extra CA certificates, and why I added the env var, but not all package authors may have realized that there is now a core mechanism.

If you turn your question around you can see why node is how it is: how can I as the author of code guarantee that the only recognized CAs are the ones I trust? Answer: provide the ca option. Absolute control by the js code author is favoured by Node.

Absolute control by the js code author is favoured by Node.

I'm not sure how I understand this since the node modules can just be altered within my environment. The user has absolute control over what code is executed within the environment.

I do see how there may be some legacy issues with how this was handled in the past, but the suggestion of having to ping every node module author to correct this seems concerning. While I'm not sure how wide spread this issue may exist in this case, I will provide some examples of issues I have run into where I'm trying to ensure that when node modules make https connections to internal servers that have internally issued certificates that these requests can validate certificates with my corporate root CA cert which I am attempting to pass to Node via this ENV variable.

@matthewwiesen I didn't mean control in a security sense. Its not about you vs some other author, I intended to express that explicitly written code should do what the author intends. If completely specifying the CA trust roots (and thus ignoring the default CA roots) is not what the author intended to do when they wrote the code, then they have a bug. Bugs need fixing in code, not configuration.

I will provide some examples of issues I have run into where I'm trying to ensure that when node modules make https connections to internal servers that have internally issued certificates that these requests can validate certificates with my corporate root CA cert which I am attempting to pass to Node via this ENV variable.

Having difficulty with privately issued HTTPS certs is common, and is what NODE_EXTRA_CA_CERTS is intended to address. Having that difficulty actually be caused by explicit use of the ca: option is not something I've seen, so please do provide references.

Closing, this issue has been dormant for a month-and-a-half and there is no consensus either.

I ran into this at $work. Why is ca: allowed to be overridden with no recourse? I expected NODE_EXTRA_CA_CERTS to allow me to add an internal CA, but it doesn't.

Using ca: indicates that the writer of the code wishes to completely control the CAs.

If the author of the code wanted to use sensible defaults (builtin CAs, possibly as modified by env vars), they should not use ca.

Put another way: using ca is an explicit way to NOT use node's CAs... if the code author doesn't even want to allow the well-known and trusted CAs that node provides compiled in, its not so likely that they want to use the ones you just stuck in an env var, frustrating though that may be to you.

You should bring this up with the author.

Was this page helpful?
0 / 5 - 0 ratings