Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node uses an hardcoded list of certificate authorities #4175

Closed
fir4 opened this Issue Dec 7, 2015 · 29 comments

Comments

Projects
None yet
@fir4
Copy link

fir4 commented Dec 7, 2015

I was dumbfounded when I realized that Node uses a statically compiled, manually updated, hardcoded list of certificate authorities, rather than relying on the system's trust store, or even just a directory truststore of its own.

This causes a large amount of problems :

  • Dependancy on the Node community for reactiveness in addition or removal of certificates
  • Dependancy on the Node community in terms of certificate trust
  • Prevents companies and anyone with their own PKI from using their certificates globally
  • Requires support from EVERY node application making use of SSL to include certificates
  • Requires modification of source code if an application doesn't happen to support it
  • Requires modification and rebuilding of Node to remove certificates that wouldn't be trusted by an organisation

Now, I can see no practical use for that. While this is acceptable in a development environment, where you can make changes to your own application, this is outright unusable... and i can't stress enough the security implications for many organisations.

Proposed solutions :

  • Make use of the standard system trust store, like any sensible application
  • Use a dedicated globally installed trust store, allowing user modifications, and why not, handling with npm
  • Dynamically load CAs using relative path, in a way similar to the usage of the node_modules folder

TL;DR: CA Certificates are hardcoded in node. It may be OK for dev, but it sucks big time for ops.

@saghul saghul added the tls label Dec 7, 2015

@kapouer

This comment has been minimized.

Copy link
Contributor

kapouer commented Dec 9, 2015

Indeed, a distribution like debian needs to work around that using that kind of patch.

I already asked this in
#3159
I suppose a pull request could make it now ? @fir4 feels like writing one ?

@doodadjs

This comment has been minimized.

Copy link

doodadjs commented Dec 9, 2015

@kapouer Path should not be hard-coded. Also what for other distributions of Linux, and other OSs like Windows and OS X ? This issue requires more research

@kapouer

This comment has been minimized.

Copy link
Contributor

kapouer commented Dec 9, 2015

I think the simplest thing to do is to have a configurable path as a build option - so that each distributor can point nodejs to the right place where it can find the system-installed root ca(s).
I don't think it's worth the time spent to be able to change that path at runtime.

@fir4

This comment has been minimized.

Copy link
Author

fir4 commented Dec 9, 2015

Yeah, those were simple ideas, in case you'd want more flexibility. Using a configurable path on ./configure step would be a great start, however I have literally zero idea how Certificates are handled on MacOS and Windows...

@doodadjs

This comment has been minimized.

Copy link

doodadjs commented Dec 9, 2015

For Windows it's too complicated. It's not just a folder. I'm thinking of a solution... Have a download link to an automatically generated zip file with the CAs. Bundle the current version with each distribution of nodejs. Add an environment variable to nodejs to locate the CAs folder. The installer will extract CAs to a proper location and set the environment variable. For Unix-like systems, the installer may try to locate system CAs. If no installer, this will have to be done manually.

EDIT: By default, use a build option like kapouer mentionned.

@royallabs

This comment has been minimized.

Copy link

royallabs commented Dec 12, 2015

+1

@cpmsmith

This comment has been minimized.

Copy link

cpmsmith commented Jan 8, 2016

👍

@ghost

This comment has been minimized.

Copy link

ghost commented Jan 13, 2016

Absolutely +1

Using the systems certificates store would of cause be best.
But even that should be configurable.

A configuration option like the one used by npm (setting a caFile) would be of great help for me and presumably for most others running into problems with ca-certs.

This could be a global configuration option, an environment variable and/or a commandline param.
It should not be a compile option in my opinion - at least not without being overwriteable afterwards.

While this is acceptable in a development environment…

It may be acceptable in most development environments.
Anyhow it is absolutely not acceptable by any means in my development environment nor in some others.

We are working behind a corporate proxy with ssl scanning.
Meaning the secure connection does not exist between our machines and the internet servers but between our machines and a trusted proxy and another between that proxy and the internet servers.

This leads to absolutely unexpected behavior, for example when installing packages using npm.

While we can configure npm to accept our certificate we can not make the postinstall scripts do the same. This leads to many packages not being able to be installed properly.

This means we can not even npm install some simple grunt tasks although npm already has the option to change the trusted CAs.

@ijstokes

This comment has been minimized.

Copy link

ijstokes commented Mar 19, 2016

This is a major issue for commercial deployment of nodejs and a major obstacle to our node based software being adopted by large organizations that have their own in-house PKI. It is also indicative of a problem with the node developers lack of understanding of the importance of doing security "right".

I am very interested in seeing this issue get resolved and if there are sensible ways I can contribute to its resolution, please someone from the NodeJS team let me know (yes, a PR, I realize, but if there is any guidance on how to put that together or other considerations/constraints...)

@bnoordhuis

This comment has been minimized.

Copy link
Member

bnoordhuis commented Mar 19, 2016

It is also indicative of a problem with the node developers lack of understanding of the importance of doing security "right".

Please.

yes, a PR, I realize, but if there is any guidance on how to put that together or other considerations/constraints...

Start with reading CONTRIBUTING.md. If you still have questions afterwards, I can probably answer them.

@bkreider

This comment has been minimized.

Copy link

bkreider commented Mar 24, 2016

Please.

Please as in, "please fix this" or "please, it is a super good idea to hard code the list of certificate authorities? "

this is outright unusable... and i can't stress enough the security implications for many organisations.

+1.

@Fishrock123

This comment has been minimized.

Copy link
Member

Fishrock123 commented Mar 24, 2016

Please as in, "please fix this" or "please, it is a super good idea to hard code the list of certificate authorities? "

I Think that was a "Please do not assume things".

@ghost

This comment has been minimized.

Copy link

ghost commented Mar 24, 2016

Please as in, "please fix this" or "please, it is a super good idea to hard code the list of certificate authorities? "

I think its more sort of "please stop being that accusing".

It is also indicative of a problem with the node developers lack of understanding of the importance of doing security "right".

I do not think they do not understand the importance to do it right.
One major problem of security is, that most people do not know, how to do it right and do not see all the problems which may arise. This is btw. a major problem in software engineering in general.

As long as no authoritys certs need to be removed, nobody outside of corporate environments with high security and compliance standards may even notice any problems with the integration as it is today. And nobody outside such environments would even think about all the problems wich will arise inside this environments.

This seems pretty much normal to me and there is no point in being harsh, accusing the developers not to try to do things right or anything alike.

Anyways, in my opinion the issue is of great importance and it needs to be fixed asap.

@bkreider

This comment has been minimized.

Copy link

bkreider commented Mar 24, 2016

I Think that was a "Please do not assume things".

Thank you for clarifying.

One major problem of security is, that most people do not know, how to do it right and do not see all the problems which may arise.

I agree. Thanks for taking the time to explain.

@willink

This comment has been minimized.

Copy link

willink commented Apr 5, 2016

We are working behind a corporate proxy with ssl scanning.
Meaning the secure connection does not exist between our machines and the internet servers but between our machines and a trusted proxy and another between that proxy and the internet servers.

This leads to absolutely unexpected behavior, for example when installing packages using npm.

While we can configure npm to accept our certificate we can not make the postinstall scripts do the same. This leads to many packages not being able to be installed properly.

I am in the exact same scenario. This is an important issue that needs a solution.

@aldahick

This comment has been minimized.

Copy link

aldahick commented May 26, 2016

Putting in my two cents: trying to write a Node application for a major university, and it's not exactly optimal with this issue.

Is anyone currently working on this? Microsoft/tfs-cli#118 has a workaround, but I'd love to see the issue fixed in Node itself.

@bnoordhuis

This comment has been minimized.

Copy link
Member

bnoordhuis commented May 26, 2016

Is anyone currently working on this?

Not that I know of. I think I speak for the project when I say that we'll review patches but that none of the collaborators feel a strong urge to work on it themselves.

@DuBistKomisch

This comment has been minimized.

Copy link

DuBistKomisch commented Jul 4, 2016

+1

Our product targets education environments, where MITM'ing SSL is almost standard, so this is a major problem for us. We didn't even realise this behaviour was the case until customers kept complaining their certs weren't trusted, since every other piece of software I've seen does this by default.

My workaround is to load and parse the system CA certs manually. Then, as recommended by the request docs, pass them in with the ca option everywhere we make a request. I presume you could also just set ca on the global agent if that works for your use case.

fs.readFileSync('/etc/ssl/certs/ca-certificates.crt')
  .toString()
  .split(/-----END CERTIFICATE-----\n?/)
  // may include an extra empty string at the end
  .filter(function (cert) { return cert !== ''; })
  // effectively split after delimiter by adding it back
  .map(function (cert) { return cert + '-----END CERTIFICATE-----\n'; })
@xel-x

This comment has been minimized.

Copy link

xel-x commented Jul 4, 2016

I think I speak for the project when I say that we'll review patches but that none of the collaborators feel a strong urge to work on it themselves.

I guess we should stop using Node to do any serious work then.

@Fishrock123

This comment has been minimized.

Copy link
Member

Fishrock123 commented Jul 4, 2016

Please leave the sarcasm for elsewhere; we'd gladly review a patch for this if someone were to make a pull request.

Most of us are pretty busy so we can't necessarily guarantee when this will get done if no-one steps up, though.

@xel-x

This comment has been minimized.

Copy link

xel-x commented Jul 4, 2016

I am sorry, it seems I didn't made clear what my point is. There was absolutely no sarcasm intended in any way.

See: As we can not influence the environments our projects need to run in, we simply can not build upon a foundation which does not cover such cases.

We had to move an entire project to a different language, as it was impossible to make it work using Node inside our clients environment.

@bnoordhuis

This comment has been minimized.

Copy link
Member

bnoordhuis commented Jul 4, 2016

I don't get that attitude. You feel strongly enough to complain about it on the bug tracker, apparently strongly enough to switch to a different language but not strongly enough to spend an hour or two on a pull request. The whole point of open source is that you can change it if you don't like what it does.

@doodadjs

This comment has been minimized.

Copy link

doodadjs commented Jul 4, 2016

I have proposed a solution and I think it will be more productive if others do the same or make a pull request instead of just bumping the thread.

@mwain

This comment has been minimized.

Copy link
Contributor

mwain commented Aug 8, 2016

Had similar issues with this, have internal apps using an internally signed cert.
Opted to use https.globalAgent and set an array of CA's which are defined in a config and updated on an env basis.

E.g.

const trustedCa = [
    '/etc/pki/tls/certs/ca-bundle.crt',
    '/path/to/custom/cert.crt'
];

https.globalAgent.options.ca = [];
for (const ca of trustedCa) {
    https.globalAgent.options.ca.push(fs.readFileSync(ca));
}
@jan-swiecki

This comment has been minimized.

Copy link

jan-swiecki commented Aug 17, 2016

It turns out that https.request module with ca option doesn't support having multiple certificates in pem file. @DuBistKomisch solution solved this problem. I'm using node v4.

@AdamMajer

This comment has been minimized.

Copy link
Contributor

AdamMajer commented Aug 31, 2016

#8334 fixes most of this.

@sam-github

This comment has been minimized.

Copy link
Member

sam-github commented Oct 17, 2016

@jan-swiecki In #4175 (comment) you mention that

It turns out that https.request module with ca option doesn't support having multiple certificates in pem file

Its not clear if you are talking about a user-land module, but if you are talking about node's https.request() method, I did a some testing, and it supports concatenated PEM certificates in options.ca in node 6.x (which I expected from reading the code), but not node 4.x.

If you can't upgrade, open an issue about it and make the case that this is a feature that should be back-ported to 4 from 6. I'm not sure what the current stance is on back-porting features, but if its low risk, it may be possible.

@JPvRiel JPvRiel referenced this issue May 22, 2018

Open

CA File #340

@SeanHayes

This comment has been minimized.

Copy link

SeanHayes commented Feb 8, 2019

Setting https.globalAgent.options.ca works for connections to my own server but causes SSL errors for regular connections (which normally work when https.globalAgent.options.ca isn't set). Is there a way to get https.globalAgent.options.ca to append to the default list of certificates used by node?

@sam-github

This comment has been minimized.

Copy link
Member

sam-github commented Feb 9, 2019

Not programmatically, but with env configuration it is: https://nodejs.org/api/cli.html#cli_node_extra_ca_certs_file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.