CVE-2022-24856 (published 2022-05-17T16:15Z)

FlyteConsole is the web user interface for the Flyte platform. FlyteConsole prior to version 0.52.0 is vulnerable to server-side request forgery (SSRF) when FlyteConsole is open to the general internet. An attacker can exploit any user of a vulnerable instance to access the internal metadata server or other unauthenticated URLs. Passing of headers to an unauthorized actor may occur. The patch for this issue deletes the entire `cors_proxy`, as this is not required for console anymore. A patch is available in FlyteConsole version 0.52.0. Disable FlyteConsole availability on the internet as a workaround.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:P/I:N/A:N)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-918
cwe_name: Server-Side Request Forgery (SSRF)
description: The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
extended_description: By providing URLs to unexpected hosts or ports, attackers can make it appear that the server is sending the request, possibly bypassing access controls such as firewalls that prevent the attackers from accessing the URLs directly. The server can be used as a proxy to conduct port scanning of hosts in internal networks, use other URLs such as that can access documents on the system (using file://), or use other protocols such as gopher:// or tftp://, which may provide greater control over the contents of requests.
         

Fix information:
repo_url: https://github.com/flyteorg/flyteconsole
commit_details: repo_url: https://github.com/flyteorg/flyteconsole
author: Carina Ursu
author_date: 2022-04-14 15:31:24-07:00
msg: feat: cleanup (#389)

Signed-off-by: Carina Ursu <carina@union.ai>

Co-authored-by: Carina Ursu <carina@union.ai>
repository: repo_url: https://github.com/flyteorg/flyteconsole
repo_name: flyteorg/flyteconsole
description: The user interface for Flyte
repo_language: TypeScript
owner: flyteorg
file_changes: filename: CONTRIBUTING.md
change_type: ModificationType.MODIFY
diff: @@ -134,25 +134,6 @@ asdf install
 yarn install
 ```
 
-## CORS Proxying: Recommended Setup
-
-In the common hosting arrangement, all API requests will be to the same origin
-serving the client application, making CORS unnecessary. However, if you would like
-to setup your local dev enviornment to target a FlyteAdmin service running on a different
-domain you will need to configure your enviornment to support CORS. One example would be
-hosting the Admin API on a different domain than the console. Another example is
-when fetching execution data from external storage such as S3.
-
-The fastest (recommended) way to setup a CORS solution is to do so within the browser.
-If you would like to handle this at the Node level you will need to disable authentication
-(see below).
-
-_NOTE:_ Do not configure for both browser and Node solutions.
-
-These instructions require using Google Chrome. You will also need to identify the
-URL of your target FlyteAdmin API instance. These instructions will use
-`https://different.admin.service.com` as an example.
-
 1. Set `ADMIN_API_URL` and `ADMIN_API_USE_SSL`
 
     ```

programming_language: Markdown
filename: Dockerfile
change_type: ModificationType.MODIFY
diff: @@ -17,7 +17,7 @@ RUN : \
   # build
   && make build_prod \
   # place the runtime application in /app
-  && mv dist corsProxy.js index.js env.js plugins.js /app
+  && mv dist index.js env.js plugins.js /app
 
 FROM gcr.io/distroless/nodejs
 LABEL org.opencontainers.image.source https://github.com/lyft/flyteconsole

programming_language: Markdown
filename: README.md
change_type: ModificationType.MODIFY
diff: @@ -88,10 +88,6 @@ For help with installing dependencies look into
     `/api/v1` and `/console` for example). For local development, this is
     usually not needed, so the default behavior is to run without a prefix.
 
-* `CORS_PROXY_PREFIX` (default: `/cors_proxy`)
-
-    Sets the local endpoint for [CORS request proxying](CONTRIBUTING.md#cors-proxying-recommended-setup).
-
 ### Running from docker image as localhost
 
 To run flyteconsole directly from your docker image as localhost you must set a
@@ -140,26 +136,6 @@ For continious development we are using:
 
 More info on each section could be found at [CONTRIBUTING.md](CONTRIBUTING.md)
 
-### CORS Proxying: Recommended setup
-
-In the common hosting arrangement, all API requests will be to the same origin
-serving the client application, making CORS unnecessary. However, if you would like
-to setup your local dev enviornment to target a FlyteAdmin service running on a different
-domain you will need to configure your enviornment support CORS. One example would be
-hosting the Admin API on a different domain than the console. Another example is
-when fetching execution data from external storage such as S3.
-
-The fastest (recommended) way to setup a CORS solution is to do so within the browser. 
-If you would like to handle this at the Node level you will need to disable authentication
-(see below)
-
-> Do not configure for both browser and Node solutions. 
-
-These instructions require using Google Chrome. You will also need to identify the 
-URL of your target FlyteAdmin API instance. These instructions will use
-`https://different.admin.service.com` as an example.
-
-
 * Set `ADMIN_API_URL` and `ADMIN_API_USE_SSL`
    
    ```bash

programming_language: Markdown
filename: corsProxy.js
change_type: ModificationType.DELETE
diff: @@ -1,49 +0,0 @@
-const http = require('http');
-const https = require('https');
-const url = require('url');
-
-/** Mounts a proxy at `basePath` such that requests of the form
- * `${basePath}/http://www.example.com?queryString=value` will be converted to
- * `http://www.example.com?queryString=value`, preserving any request headers.
- * The response is piped directly to the client with no processing.
- */
-module.exports = function corsProxy(basePath) {
-  const pathOffset = basePath.length;
-  return function (req, res, next) {
-    const pathIndex = req.url.indexOf(basePath);
-    // base path doesn't match, ignore
-    if (pathIndex < 0) {
-      return next();
-    }
-
-    const targetUrl = req.url.substring(pathIndex + pathOffset + 1);
-    const config = url.parse(targetUrl);
-    config.method = req.method;
-
-    // We need to use a different request class depending on the
-    // protocol
-    const handler = config.protocol === 'https:' ? https : http;
-
-    const proxyReq = handler.request(config, function (proxyRes) {
-      res.writeHead(proxyRes.statusCode, proxyRes.headers);
-      proxyRes.pipe(res, {
-        end: true,
-      });
-    });
-
-    proxyReq.on('error', (err) => res.status(500).send(err));
-
-    // Copy over all headers except for 'Host', since that value would
-    // point to *this* server, and not the remote server.
-    Object.keys(req.headers).forEach((key) => {
-      if (key.toLowerCase() === 'host') {
-        return;
-      }
-      proxyReq.setHeader(key, req.headers[key]);
-    });
-
-    req.pipe(proxyReq, {
-      end: true,
-    });
-  };
-};

programming_language: unknown
filename: index.js
change_type: ModificationType.MODIFY
diff: @@ -8,7 +8,6 @@ const morgan = require('morgan');
 const express = require('express');
 const env = require('./env');
 const { applyMiddleware } = require('./plugins');
-const corsProxy = require('./corsProxy.js');
 
 const app = express();
 
@@ -16,7 +15,6 @@ const app = express();
 app.use(morgan('combined'));
 app.use(express.json());
 app.get(`${env.BASE_URL}/healthz`, (_req, res) => res.status(200).send());
-app.use(corsProxy(`${env.BASE_URL}${env.CORS_PROXY_PREFIX}`));
 
 if (typeof applyMiddleware === 'function') {
   console.log('Found middleware plugins, applying...');

programming_language: JavaScript