CVE-2022-0122 (JavaScript, published 2022-01-06T05:15Z)
Description: value: forge is vulnerable to URL Redirection to Untrusted Site
Severity: MEDIUM (CVSS v3 base score: 6.1)
Weakness: CWE-601 \u2014 URL Redirection to Untrusted Site ('Open Redirect')
A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks.
Repository: https://github.com/digitalbazaar/forge
Files changed:
CHANGELOG.md
README.md
lib/http.js
lib/util.js
lib/xhr.js
package.json
tests/websockets/server-webid.js
Commit message: Remove forge.util.parseUrl.

- Switch URL parsing to the WHATWG URL Standard `URL` API.
- Older browser or Node.js usage of related code might now require a URL
  polyfill.


Vulnerable code:

// parse a URL
var parsed = forge.util.parseUrl('http://example.com/foo?bar=baz');
// parsed.scheme, parsed.host, parsed.port, parsed.path, parsed.fullHost
    client.url.scheme + '.' +
    client.url.host + '.' +
      host: client.url.host,
        host: client.url.host,
 *     socketPool: the flash socket pool to use.
  var url = http.parseUrl(options.url);
  if(!url) {
    secure: (url.scheme === 'https'),
      if(cn === null || client.url.host !== cn.value) {
      virtualHost: options.virtualHost || url.host,
      options.request.setField('Host', client.url.fullHost);
/**
 * Parses the scheme, host, and port from an http(s) url.
 *
 * @param str the url string.
 *
 * @return the parsed url object or null if the url is invalid.
 */
http.parseUrl = forge.util.parseUrl;

      url = http.parseUrl(url);
    // add '.' to front of URL host to match against domain
    var host = '.' + url.host;
/**
 * Parses the scheme, host, and port from an http(s) url.
 *
 * @param str the url string.
 *
 * @return the parsed url object or null if the url is invalid.
 */
util.parseUrl = function(str) {
  // FIXME: this regex looks a bit broken
  var regex = /^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g;
  regex.lastIndex = 0;
  var m = regex.exec(str);
  var url = (m === null) ? null : {
    full: str,
    scheme: m[1],
    host: m[2],
    port: m[3],
    path: m[4]
  };
  if(url) {
    url.fullHost = url.host;
    if(url.port) {
      if(url.port !== 80 && url.scheme === 'http') {
        url.fullHost += ':' + url.port;
      } else if(url.port !== 443 && url.scheme === 'https') {
        url.fullHost += ':' + url.port;
      }
    } else if(url.scheme === 'http') {
      url.port = 80;
    } else if(url.scheme === 'https') {
      url.port = 443;
    }
    url.full = url.scheme + '://' + url.fullHost;
  }
  return url;
};

  _clients[_client.url.full] = _client;
    var url = http.parseUrl(options.url);
    if(!url) {
    if(url.full in _clients) {
      _state.client = _clients[url.full];
      _clients[url.full] = _state.client;
    "node": ">= 6.0.0"
  url = forge.util.parseUrl(url);
  var client = http.createClient(
    url.port, url.fullHost, url.scheme === 'https');

Fixed code:
- **SECURITY**, **BREAKING**: Remove `forge.util.parseUrl()` (and
  `forge.http.parseUrl` alias) and use the [WHATWG URL
  Standard](https://url.spec.whatwg.org/). `URL` is supported by modern browers
  and modern Node.js. This change is needed to address URL parsing security
  issues. If `forge.util.parseUrl()` is used directly or through `forge.xhr` or
  `forge.http` APIs, and support is needed for environments without `URL`
  support, then a polyfill must be used.
### Changed
- **BREAKING**: Increase supported Node.js version to 6.13.0 for URL support.

### Notes
- The URL related changes may expose bugs in some of the networking related
  code (unrelated to the much wider used cryptography code). The automated and
  manual test coverage for this code is weak at best. Issues or patches to
  update the code or tests would be appriciated.

    client.url.protocol.slice(0, -1) + '.' +
    client.url.hostname + '.' +
      host: client.url.hostname,
        host: client.url.hostname,
 *   socketPool: the flash socket pool to use.
  var url;
  try {
    url = new URL(options.url);
  } catch(e) {
    secure: (url.protocol === 'https:'),
      if(cn === null || client.url.hostname !== cn.value) {
      virtualHost: options.virtualHost || url.hostname,
      options.request.setField('Host', client.url.origin);
      url = new URL(url);
    // add '.' to front of URL hostname to match against domain
    var host = '.' + url.hostname;
  _clients[_client.url.origin] = _client;
    var url;
    try {
      url = new URL(options.url);
    } catch(e) {
    if(url.origin in _clients) {
      _state.client = _clients[url.origin];
      _clients[url.origin] = _state.client;
    "node": ">= 6.13.0"
  url = new URL(url);
  var client = http.createClient({
    url: url
  });