urllib 2.43.0 → 2.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -32,7 +32,7 @@ export interface RequestOptions {
32
32
  writeStream?: Writable;
33
33
  /** consume the writeStream, invoke the callback after writeStream close. */
34
34
  consumeWriteStream?: boolean;
35
- /**
35
+ /**
36
36
  * The files will send with multipart/form-data format, base on formstream.
37
37
  * If method not set, will use POST method by default.
38
38
  */
@@ -130,7 +130,7 @@ export interface RequestOptions {
130
130
  * It receive two arguments(ip and family) and should return true or false to identified the address is legal or not.
131
131
  * It rely on lookup and have the same version requirement.
132
132
  */
133
- checkAddress?: (ip: string, family: number | string) => boolean;
133
+ checkAddress?: (ip: string, family: number | string, hostname: string) => boolean;
134
134
  /**
135
135
  * UNIX domain socket path. (Windows is not supported)
136
136
  */
package/lib/urllib.js CHANGED
@@ -66,6 +66,71 @@ var TEXT_DATA_TYPES = [
66
66
 
67
67
  var PROTO_RE = /^https?:\/\//i;
68
68
 
69
+ // Credential-bearing headers that must not be forwarded across an origin
70
+ // boundary when following a redirect, to avoid leaking them to a third party.
71
+ var CROSS_ORIGIN_SENSITIVE_HEADERS = [ 'authorization', 'cookie', 'proxy-authorization' ];
72
+
73
+ // Build an absolute href good enough to compute the origin. `currentUrl` may be
74
+ // a parsed URL object (with href) or an http options-style object built from
75
+ // { host/hostname, port, path }, which has no href.
76
+ function resolveOriginHref(currentUrl) {
77
+ if (currentUrl.href) {
78
+ return currentUrl.href;
79
+ }
80
+ var host = currentUrl.host || currentUrl.hostname;
81
+ if (!host) {
82
+ return null;
83
+ }
84
+ var protocol = currentUrl.protocol || 'http:';
85
+ if (protocol.charAt(protocol.length - 1) !== ':') {
86
+ protocol += ':';
87
+ }
88
+ if (currentUrl.port && String(host).indexOf(':') === -1) {
89
+ host += ':' + currentUrl.port;
90
+ }
91
+ return protocol + '//' + host + (currentUrl.path || currentUrl.pathname || '/');
92
+ }
93
+
94
+ function isCrossOriginRedirect(currentUrl, toUrl) {
95
+ try {
96
+ var fromHref = resolveOriginHref(currentUrl);
97
+ if (!fromHref) {
98
+ // origin cannot be determined: fail closed
99
+ return true;
100
+ }
101
+ if (URL) {
102
+ return new URL(fromHref).origin !== new URL(toUrl, fromHref).origin;
103
+ }
104
+ // Fallback for runtimes without the WHATWG URL global.
105
+ // urlutil.parse does not normalize default ports, so compare protocol +
106
+ // hostname + normalized port instead of the raw `host`.
107
+ var from = urlutil.parse(fromHref);
108
+ var to = urlutil.parse(urlutil.resolve(fromHref, toUrl));
109
+ var fromPort = from.port || (from.protocol === 'https:' ? '443' : '80');
110
+ var toPort = to.port || (to.protocol === 'https:' ? '443' : '80');
111
+ return from.protocol !== to.protocol || from.hostname !== to.hostname || fromPort !== toPort;
112
+ } catch (err) {
113
+ // Fail closed: if the origin cannot be determined, treat it as cross-origin
114
+ // so credentials are stripped rather than leaked.
115
+ return true;
116
+ }
117
+ }
118
+
119
+ function cleanCrossOriginHeaders(headers, sensitive) {
120
+ var list = sensitive || CROSS_ORIGIN_SENSITIVE_HEADERS;
121
+ var cleaned = {};
122
+ if (headers) {
123
+ var names = utility.getOwnEnumerables(headers, true);
124
+ for (var i = 0; i < names.length; i++) {
125
+ var name = names[i];
126
+ if (list.indexOf(name.toLowerCase()) === -1) {
127
+ cleaned[name] = headers[name];
128
+ }
129
+ }
130
+ }
131
+ return cleaned;
132
+ }
133
+
69
134
  // Keep-Alive: timeout=5, max=100
70
135
  var KEEP_ALIVE_RE = /^timeout=(\d+)/i;
71
136
 
@@ -276,7 +341,7 @@ function requestWithCallback(url, args, callback) {
276
341
  lookup = function(host, dnsopts, callback) {
277
342
  _lookup(host, dnsopts, function emitLookup(err, ip, family) {
278
343
  // add check address logic in custom dns lookup
279
- if (!err && !args.checkAddress(ip, family)) {
344
+ if (!err && !args.checkAddress(ip, family, host)) {
280
345
  err = new Error('illegal address');
281
346
  err.name = 'IllegalAddressError';
282
347
  err.hostname = host;
@@ -688,6 +753,24 @@ function requestWithCallback(url, args, callback) {
688
753
  options.headers.host = null;
689
754
  args.headers = options.headers;
690
755
  }
756
+ // do not forward credential-bearing headers / auth to a different origin
757
+ if (isCrossOriginRedirect(parsedUrl, newUrl)) {
758
+ // Clone so this redirect-specific sanitization never corrupts the
759
+ // caller's reusable options object.
760
+ var redirectArgs = Object.assign({}, args);
761
+ var sensitiveHeaders = CROSS_ORIGIN_SENSITIVE_HEADERS;
762
+ if (proxyTunnelAgent) {
763
+ // Proxy-Authorization authenticates the (unchanged) proxy hop, not
764
+ // the redirected origin, so keep it when the request is proxied.
765
+ sensitiveHeaders = sensitiveHeaders.filter(function (name) {
766
+ return name !== 'proxy-authorization';
767
+ });
768
+ }
769
+ redirectArgs.headers = cleanCrossOriginHeaders(args.headers || options.headers, sensitiveHeaders);
770
+ redirectArgs.auth = null;
771
+ redirectArgs.digestAuth = null;
772
+ args = redirectArgs;
773
+ }
691
774
  // avoid done will be execute in the future change.
692
775
  var cb = callback;
693
776
  callback = null;
@@ -1017,7 +1100,7 @@ function requestWithCallback(url, args, callback) {
1017
1100
  family = 6;
1018
1101
  }
1019
1102
  if (family) {
1020
- if (!args.checkAddress(hostname, family)) {
1103
+ if (!args.checkAddress(hostname, family, hostname)) {
1021
1104
  var err = new Error('illegal address');
1022
1105
  err.name = 'IllegalAddressError';
1023
1106
  err.hostname = hostname;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "urllib",
3
- "version": "2.43.0",
3
+ "version": "2.44.1",
4
4
  "publishConfig": {
5
5
  "tag": "latest-2"
6
6
  },