CVE-2021-4260 (published 2022-12-19T14:15Z)

A vulnerability was found in oils-js. It has been declared as critical. This vulnerability affects unknown code of the file core/Web.js. The manipulation leads to open redirect. The attack can be initiated remotely. The name of the patch is fad8fbae824a7d367dacb90d56cb02c5cb999d42. It is recommended to apply a patch to fix this issue. The identifier of this vulnerability is VDB-216268.

CVSS v3 base score: 6.1, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)

Weakness information:
cwe_id: CWE-601
cwe_name: URL Redirection to Untrusted Site ('Open Redirect')
description: 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.
extended_description: An http parameter may contain a URL value and could cause the web application to redirect the request to the specified URL. By modifying the URL value to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials. Because the server name in the modified link is identical to the original site, phishing attempts have a more trustworthy appearance. Whether this issue poses a vulnerability will be subject to the intended behavior of the application. For example, a search engine might intentionally provide redirects to arbitrary URLs.
         

Fix information:
repo_url: https://github.com/mannyvergel/oils-js
commit_details: repo_url: https://github.com/mannyvergel/oils-js
author: Manny
author_date: 2021-03-23 20:43:39+08:00
msg: Framework fix for open redirect vulnerability
repository: repo_url: https://github.com/mannyvergel/oils-js
repo_name: mannyvergel/oils-js
description: Oils JS Framework for Node JS. Built on top of Express.
repo_language: JavaScript
owner: mannyvergel
file_changes: filename: Web.js
change_type: ModificationType.MODIFY
diff: @@ -122,6 +122,9 @@ class Web {
     }
 
     this.app = express();
+
+    fixOpenRedirect(this);
+
     this.events = {};
     this.modelCache = new Object();
     this.plugins = [];
@@ -763,6 +766,42 @@ function defaultRedirectToHttpsMiddleware(req, res) {
   res.end();
 }
 
+function fixOpenRedirect(web) {
+  // Fix for open redirect security
+  let redirectSafe = web.app.response.redirect;
+  web.app.response.redirectSafe = function(url) {
+    return redirectSafe.call(this, url);
+  }
+
+  var addHostOnceFlag = true;
+
+  web.app.response.redirect = function(url) {
+  
+    if (url.indexOf('://') != -1) {
+
+      let req = this.req;
+
+      if (addHostOnceFlag) {
+        var host = req.protocol + '://' + req.headers.host;
+        web.conf.allowedRedirectHosts.push(host);
+        addHostOnceFlag = false;
+        console.log("Added host once: " + host);
+      }
+
+      const found = web.conf.allowedRedirectHosts.find(el => url.indexOf(el) == 0);
+
+      if (!found) {
+        var ip = web.utils.getClientIp(req);
+
+        console.warn("Open redirect was triggered: ", req.method, req.user ? req.user.email : "unsigned user", ip, "accessed", req.url, req.headers['user-agent']);
+        throw new Error("Action not allowed.");
+      }
+
+    }
+    return redirectSafe.call(this, url);
+  }
+}
+
 
 function startServer(web, cb) {
 

programming_language: TypeScript
filename: conf-default.js
change_type: ModificationType.MODIFY
diff: @@ -11,6 +11,7 @@ module.exports = function(webSel) {
 
     dataDir: 'data',
     tmpDir: 'data/tmp',
+    allowedRedirectHosts: [],
 
     extendWeb: {
       enabled: true,

programming_language: JavaScript
filename: package-lock.json
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,6 @@
 {
   "name": "oils",
-  "version": "7.8.6",
+  "version": "8.0.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -14,6 +14,28 @@
       "resolved": "https://registry.npmjs.org/@root/request/-/request-1.5.0.tgz",
       "integrity": "sha512-J9RUIwVU99/cOVuDVYlNpr4G0A1/3ZxhCXIRiTZzu8RntOnb0lmDBMckhaus5ry9x/dBqJKDplFIgwHbLi6rLA=="
     },
+    "@types/bson": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz",
+      "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "@types/mongodb": {
+      "version": "3.6.10",
+      "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.10.tgz",
+      "integrity": "sha512-BkwAHFiZSSWdTIqbUVGmgvIsiXXjqAketeK7Izy7oSs6G3N8Bn993tK9eq6QEovQDx6OQ2FGP2KWDDxBzdlJ6Q==",
+      "requires": {
+        "@types/bson": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/node": {
+      "version": "14.14.35",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz",
+      "integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag=="
+    },
     "a-sync-waterfall": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
@@ -249,9 +271,9 @@
       "dev": true
     },
     "bson": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz",
-      "integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg=="
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz",
+      "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg=="
     },
     "bytes": {
       "version": "3.1.0",
@@ -630,9 +652,9 @@
       "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
     },
     "denque": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
-      "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz",
+      "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ=="
     },
     "depd": {
       "version": "1.1.2",
@@ -1347,9 +1369,9 @@
       }
     },
     "kareem": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
-      "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz",
+      "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ=="
     },
     "keygrip": {
       "version": "1.1.0",
@@ -1738,9 +1760,9 @@
       }
     },
     "mongodb": {
-      "version": "3.6.2",
-      "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.2.tgz",
-      "integrity": "sha512-sSZOb04w3HcnrrXC82NEh/YGCmBuRgR+C1hZgmmv4L6dBz4BkRse6Y8/q/neXer9i95fKUBbFi4KgeceXmbsOA==",
+      "version": "3.6.5",
+      "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.5.tgz",
+      "integrity": "sha512-mQlYKw1iGbvJJejcPuyTaytq0xxlYbIoVDm2FODR+OHxyEiMR021vc32bTvamgBjCswsD54XIRwhg3yBaWqJjg==",
       "requires": {
         "bl": "^2.2.1",
         "bson": "^1.1.4",
@@ -1751,16 +1773,17 @@
       }
     },
     "mongoose": {
-      "version": "5.10.6",
-      "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.10.6.tgz",
-      "integrity": "sha512-p32oja2ydzFMS0K4P7G408Kagju6Qz/LmiAFAcP6BqnIi1McLTd6VZ3+ZQtQmaHM7w8iNupLLambCrsPKNJpYw==",
+      "version": "5.12.2",
+      "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.2.tgz",
+      "integrity": "sha512-kT9t6Nvu9WPsfssn7Gzke446Il8UdMilY7Sa5vALtwoOoNOGtZEVjekZBFwsBFzTWtBA/x5gBmJoYFP+1LeDlg==",
       "requires": {
+        "@types/mongodb": "^3.5.27",
         "bson": "^1.1.4",
-        "kareem": "2.3.1",
-        "mongodb": "3.6.2",
+        "kareem": "2.3.2",
+        "mongodb": "3.6.5",
         "mongoose-legacy-pluralize": "1.0.2",
-        "mpath": "0.7.0",
-        "mquery": "3.2.2",
+        "mpath": "0.8.3",
+        "mquery": "3.2.4",
         "ms": "2.1.2",
         "regexp-clone": "1.0.0",
         "safe-buffer": "5.2.1",
@@ -1786,14 +1809,14 @@
       "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
     },
     "mpath": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz",
-      "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg=="
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.3.tgz",
+      "integrity": "sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA=="
     },
     "mquery": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz",
-      "integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==",
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.4.tgz",
+      "integrity": "sha512-uOLpp7iRX0BV1Uu6YpsqJ5b42LwYnmu0WeF/f8qgD/On3g0XDaQM6pfn0m6UxO6SM8DioZ9Bk6xxbWIGHm2zHg==",
       "requires": {
         "bluebird": "3.5.1",
         "debug": "3.1.0",

programming_language: TypeScript
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,6 @@
 {
   "name": "oils",
-  "version": "7.8.6",
+  "version": "8.0.0",
   "description": "A slightly opinionated web framework built on top of Express 4.",
   "keywords": [
     "OilsJs",
@@ -41,7 +41,7 @@
     "method-override": "~3.0.0",
     "moment": "~2.24.0",
     "moment-timezone": "^0.5.27",
-    "mongoose": "^5.10.6",
+    "mongoose": "^5.12.2",
     "nanoid": "^3.1.20",
     "nomnom": "1.8.x",
     "nunjucks": "^3.2.1",

programming_language: TypeScript