File: CVE-2019-5448.diff

package info (click to toggle)
node-yarnpkg 1.13.0-1%2Bdeb10u1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 93,036 kB
  • sloc: sh: 323; makefile: 19
file content (75 lines) | stat: -rw-r--r-- 2,897 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
Description: Forces using https for the regular registries
Author: Maƫl Nison <https://github.com/arcanis>
Origin: upstream, https://github.com/yarnpkg/yarn/commit/2f08a740
Bug: https://hackerone.com/reports/640904
Bug-Debian: https://bugs.debian.org/941354
Forwarded: not-needed
Reviewed-By: Xavier Guimard <yadd@debian.org>
Last-Update: 2019-10-03

--- a/__tests__/registries/npm-registry.js
+++ b/__tests__/registries/npm-registry.js
@@ -750,6 +750,30 @@
 
     expect(npmRegistry.getRequestUrl(registry, pathname)).toEqual('https://my.registry.co/registry/foo/bar/baz');
   });
+
+  for (const host of [`registry.yarnpkg.com`, `registry.npmjs.org`, `registry.npmjs.com`]) {
+    test(`enforces loading packages through https when they come from ${host}`, () => {
+      const testCwd = '.';
+      const {mockRequestManager, mockRegistries, mockReporter} = createMocks();
+      const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter, true, []);
+      const registry = `http://${host}/registry`;
+      const pathname = 'foo/bar/baz';
+
+      expect(npmRegistry.getRequestUrl(registry, pathname)).toEqual(`https://${host}/registry/foo/bar/baz`);
+    });
+  }
+
+  test("doesn't change the protocol for packages from other registries", () => {
+    const testCwd = '.';
+    const {mockRequestManager, mockRegistries, mockReporter} = createMocks();
+    const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter, true, []);
+    const registry = 'http://registry.mylittlepony.org/registry';
+    const pathname = 'foo/bar/baz';
+
+    expect(npmRegistry.getRequestUrl(registry, pathname)).toEqual(
+      'http://registry.mylittlepony.org/registry/foo/bar/baz',
+    );
+  });
 });
 
 describe('getScope functional test', () => {
--- a/src/registries/npm-registry.js
+++ b/src/registries/npm-registry.js
@@ -22,6 +22,7 @@
 import ini from 'ini';
 
 const DEFAULT_REGISTRY = 'https://registry.npmjs.org/';
+const REGEX_REGISTRY_ENFORCED_HTTPS = /^https?:\/\/([^\/]+\.)?(yarnpkg\.com|npmjs\.(org|com))(\/|$)/;
 const REGEX_REGISTRY_HTTP_PROTOCOL = /^https?:/i;
 const REGEX_REGISTRY_PREFIX = /^(https?:)?\/\//i;
 const REGEX_REGISTRY_SUFFIX = /registry\/?$/;
@@ -112,13 +113,17 @@
   }
 
   getRequestUrl(registry: string, pathname: string): string {
-    const isUrl = REGEX_REGISTRY_PREFIX.test(pathname);
+    let resolved = pathname;
 
-    if (isUrl) {
-      return pathname;
-    } else {
-      return url.resolve(addSuffix(registry, '/'), pathname);
+    if (!REGEX_REGISTRY_PREFIX.test(pathname)) {
+      resolved = url.resolve(addSuffix(registry, '/'), pathname);
     }
+
+    if (REGEX_REGISTRY_ENFORCED_HTTPS.test(resolved)) {
+      resolved = resolved.replace(/^http:\/\//, 'https://');
+    }
+
+    return resolved;
   }
 
   isRequestToRegistry(requestUrl: string, registryUrl: string): boolean {