Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

Commit 27f59c6

Browse files
Make domain-task/fetch disable HTTPS cert validation when making relative requests to own server as workaround for #1089
1 parent 943fb2f commit 27f59c6

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/Microsoft.AspNetCore.SpaServices/npm/domain-task/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "domain-task",
3-
"version": "3.0.0",
3+
"version": "3.0.2",
44
"description": "Tracks outstanding operations for a logical thread of execution",
55
"main": "index.js",
66
"scripts": {
@@ -18,6 +18,7 @@
1818
},
1919
"dependencies": {
2020
"domain-context": "^0.5.1",
21+
"is-absolute-url": "^2.1.0",
2122
"isomorphic-fetch": "^2.2.1"
2223
},
2324
"devDependencies": {

src/Microsoft.AspNetCore.SpaServices/npm/domain-task/src/fetch.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import * as url from 'url';
22
import * as domain from 'domain';
33
import * as domainContext from 'domain-context';
4+
import * as isAbsoluteUrl from 'is-absolute-url';
45
import { baseUrl } from './main';
56
const isomorphicFetch = require('isomorphic-fetch');
67
const isNode = typeof process === 'object' && process.versions && !!process.versions.node;
8+
const nodeHttps = isNode && require('https');
79

810
function issueRequest(baseUrl: string, req: string | Request, init?: RequestInit): Promise<any> {
11+
const reqUrl = (req instanceof Request) ? req.url : req;
12+
const isRelativeUrl = reqUrl && !isAbsoluteUrl(reqUrl);
13+
914
// Resolve relative URLs
1015
if (baseUrl) {
1116
if (req instanceof Request) {
@@ -25,9 +30,42 @@ function issueRequest(baseUrl: string, req: string | Request, init?: RequestInit
2530
`);
2631
}
2732

33+
init = applyHttpsAgentPolicy(init, isRelativeUrl);
2834
return isomorphicFetch(req, init);
2935
}
3036

37+
function applyHttpsAgentPolicy(init: RequestInit, isRelativeUrl: boolean): RequestInit {
38+
// HTTPS is awkward in Node because it uses a built-in list of CAs, rather than recognizing
39+
// the OS's system-level CA list. There are dozens of issues filed against Node about this,
40+
// but still (as of v8.0.0) no resolution besides manually duplicating your CA config.
41+
//
42+
// The biggest problem for typical isomorphic-SPA development this causes is that if you're
43+
// using a self-signed localhost cert in development, Node won't be able to make API calls
44+
// to it (e.g., https://github.com/aspnet/JavaScriptServices/issues/1089). Developers could
45+
// fix this by either manually configuring the cert in Node (which is extremely inconvenient,
46+
// especially if multiple devs on a team have different self-signed localhost certs), or by
47+
// disabling cert verification on their API requests.
48+
//
49+
// Fortunately, 'domain-task/fetch' knows when you're making a relative-URL request to your
50+
// own web server (as opposed to an arbitrary request to anywhere else). In this specific case,
51+
// there's no real point in cert verification, since the request never even leaves the machine
52+
// so a MitM attack isn't meaningful. So by default, when your code is running in Node and
53+
// is making a relative-URL request, *and* if you haven't explicitly configured any option
54+
// for 'agent' (which would let you set up other HTTPS-handling policies), then we automatically
55+
// disable cert verification for that request.
56+
if (isNode && isRelativeUrl) {
57+
const hasAgentConfig = init && ('agent' in init);
58+
if (!hasAgentConfig) {
59+
const agentForRequest = new (nodeHttps.Agent)({ rejectUnauthorized: false });
60+
61+
init = init || {};
62+
(init as any).agent = agentForRequest;
63+
}
64+
}
65+
66+
return init;
67+
}
68+
3169
export function fetch(url: string | Request, init?: RequestInit): Promise<any> {
3270
// As of domain-task 2.0.0, we no longer auto-add the 'fetch' promise to the current domain task list.
3371
// This is because it's misleading to do so, and can result in race-condition bugs, e.g.,

0 commit comments

Comments
 (0)