There should be a way to allow insecure https requests, using window.fetch() for example.
It should disable certificate validation for all requests made from the program.
As of implementation, there are two optoins that come to my mind: environment variable and flag. Below are some examples of how it's done in other web-related software, so we can come up with intuitive name and approach.
Examples:
NODE_TLS_REJECT_UNAUTHORIZED environment variable that can be set to 0 to disable TLS certificate validation. It takes name from tls.connect options.rejectUnauthorized-k or --insecure flag, which allows insecure server connections when using SSL--unsafely-treat-insecure-origin-as-secure="https://example.com" for the same purposesThat said, I'd like to see --accept-insecure-certs flag option, because deno already uses flags for a lot of things, including permissions.
My use-case: I'm using a corporate Windows laptop with network monitoring. AFAIK, all https requests are also monitored, so there's a custom SSL-certificate installed system-wide. So, most of the software, that uses system CA storage, works just fine. But some uses custom or bundled CA, and it seems like it's a case with deno. Anyway, it downloads deps just fine, but fails to perfprm any https request.
Issue created as a follow up to gitter conversation: December 18, 2018 1:24 PM
Seems like it'd be better to allow adding new CA entries that requests would trust, no? Having this flag is probably fine in exceptional circumstances, but for any production system leaving this flag on all the time is a huge red flag.
I wonder if this ought to share a prefix i.e. --allow? Would it be added to DenoPermissions, would it be "upgradeable" at runtime?
Related: #1064
@eventualbuddha yes, I'd like to have that option too. I mean, for some non-production cases, it might be better to completely disable any checks. And later, you might want to add new CA entries when preparing the code for production.
@hayd I made more research on that because I need to make it work already. So, I discovered, that these checks are performed in rustls. And as far as I can tell, we'll be unable to disable certificate checks, or add custom CA's unless this lib is built with "dangerous_configuration" feature turned on. After enabling it, we can create Connector with custom ClientConfig that has custom ServerCertVerifier. It should be done in //src/http_util.rs -> fn get_client.
That said, I'm not sure is it a good idea at all, to always build deno with dangerous_configuration feature. It sounds... "dangerous" :) But also I don't like locking CAs using webpki-roots with static CAs list, which is used by rustls. I'm more then sure, that if @ry wants deno to be adopted by corporations, it might be really vital to at least add an option to support system CAs, so developers on machines with monitored traffic by an employer, can also develop with deno.
So, even tho, adding option for custom CAs will require building rustls with dangerous_configuration feature, I think we should consider doing so.
Back to @hayd questions, I might be wrong, but I think that ideally, deno should pick up system CAs instead of bundled CAs without any additional flags. AFAIK, it will be a more browser-like approach.
If @ry decides to go with the flag instead, I don't think that it should be a permission, but rather a configuration. If we take a look at Chromes behavior, it will allow visiting the website with a bad certificate after we choose to proceed, but all insecure requests from that page to other sources with bad certificates will fail without any prompts and there's no way to allow them in "upgradable" manner.
Please, let me know what do you think about it?
As an update to this, I have a working branch, and it works fine, but I'm not ready to open a PR yet. Anyway, it's my first time coding in rust, so I expect a lot of help from code review. Currently, the branch is here: https://github.com/Maxim-Mazurok/deno/tree/accept-insecure-certs and it adds --accept-insecure-certs flag support. It's not considered permission, and thus, not upgradable during run-time. Someone might find it helpful. Luckily, I'm no longer an employee of company where I had to use Windows laptop with custom CA certs and I'm back to my lovely personal CentOS laptop :) So that issue is not critical for me anymore, but still I want to finish what I've started in hope that it'll help somebody else to adopt deno for their project. And in case if anyone is looking for an employee in SF Bay Area, I'm open for new opportunities :)
Chiming in that the Go tls.Config kind of supports both strategies.
InsecureSkipVerify boolean that seems analogous to curl's -kDocs here: https://golang.org/pkg/crypto/tls/#Config
We could start with something like number 1, but leave the door open for more granular configuration.
My biggest worry here is that TLS in rust is kind of rough as it stands. We will be bound to the underlying implementation chosen, but we should take care to avoid letting the underlying implementation leak into the TypeScript API.
My dream would be a Typescript interface that roughly maps onto what Go does, and each capability added would be a runtime escalation just like allow-network. But we can start simple, e.g.
export interface TLSConfig {
// defaults to false
insecureSkipVerify?: boolean;
}
It looks like deno is now using the reqwest library, which claims:
By default, a Client will make use of system-native transport layer security to connect to HTTPS destinations. This means schannel on Windows, Security-Framework on macOS, and OpenSSL on Linux.
But I'm still getting certificate errors when behind a corporate proxy. It looks like deno is configured to use rustls-tls instead of default-tls or native-tls. I think that's why it's still not working. Is there a reason to not use default-tls or native-tls?
I'm looking here. Specifically this line:
reqwest = { version = "0.10.1", default-features = false, features = ["rustls-tls", "stream", "gzip"] }
Seems like you could just change it to
reqwest = { version = "0.10.1", default-features = false, features = ["native-tls", "stream", "gzip"] }
And that would fix it.
Is there any update on this issue, because I am facing this error when calling internally hosted reviewboard api using fetch while on VPN.
The error I get is
error: Uncaught Http: error sending request for url (https://[CUSTOM_HOST]/api/users/): error trying to connect: tls handshake eof
at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
at Object.sendAsync ($deno$/ops/dispatch_json.ts:98:10)
at async fetch ($deno$/web/fetch.ts:591:27)
deno --version
deno 1.0.2
v8 8.4.300
typescript 3.9.2
I'm not sure about a flag, but at least ConnectOptions should support ignoring SSL problems. Unless I'm missing something, there is currently no way to connect to a server with a self-signed certificate.
Would love to see something like this implemented, i'm trying to run integration tests for a web app to ensure serveTls works, but all fetch calls (to test the endpoint works) fail
There needs to be both a environment variable and a fetch option for this. The former should be chosen over an cli argument for cases when one does not have control of the arguments passed to deno, which certainly will be the case sometimes.
Most helpful comment
It looks like deno is now using the reqwest library, which claims:
But I'm still getting certificate errors when behind a corporate proxy. It looks like deno is configured to use rustls-tls instead of default-tls or native-tls. I think that's why it's still not working. Is there a reason to not use default-tls or native-tls?
I'm looking here. Specifically this line:
Seems like you could just change it to
And that would fix it.