CVE-2023-40168: Incorrect Authorization (CWE-863)
value: TurboWarp is a desktop application that compiles scratch projects to JavaScript. TurboWarp Desktop versions prior to version 1.8.0 allowed a malicious project or custom extension to read arbitrary files from disk and upload them to a remote server. The only required user interaction is opening the sb3 file or loading the extension. The web version of TurboWarp is not affected. This bug has been addressed in commit `55e07e99b59` after an initial fix which was reverted. Users are advised to upgrade to version 1.8.0 or later. Users unable to upgrade should avoid opening sb3 files or loading extensions from untrusted sources.
CWE description: The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
CVSS v3 base score: 6.5
Published: 2023-08-17T20:15Z
Repository: https://github.com/TurboWarp/desktop
Language: JavaScript
Files changed: src/main/index.js
Commit date: 2023-01-24 23:47:59 -0600
Commit message: Remove the code that broke Windows

Diff: diff --git a/src/main/index.js b/src/main/index.js
index ea20705..0b67bf9 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -20,11 +20,10 @@ import {handlePermissionRequest} from './permissions';
 import './detect-arm-translation';
 import {isBackgroundThrottlingEnabled, whenBackgroundThrottlingChanged} from './background-throttling';
 import './extensions';
 import {createAtomicWriteStream} from './atomic-file-write-stream';
 import './protocols';
-import './request-security';
 
 const readFile = util.promisify(fs.readFile);
 const brotliDecompress = util.promisify(zlib.brotliDecompress);
 
 const filesToOpen = [];
diff --git a/src/main/request-security.js b/src/main/request-security.js
deleted file mode 100644
index 0471f77..0000000
--- a/src/main/request-security.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import {app} from 'electron';
-
-const isRequestAllowed = (details) => {
-  const url = new URL(details.url);
-  if (url.protocol === 'file:') {
-    // Requests to files must be inside the application
-    return url.pathname.startsWith(__dirname);
-  }
-
-  if (details.resourceType !== 'xhr') {
-    // Immune to CORS even in standard browsers
-    return true;
-  }
-
-  if (url.protocol !== 'http:' && url.protocol !== 'https:') {
-    // Special protocols are immune to CORS
-    return true;
-  }
-
-  const allowOriginHeader = details.responseHeaders['access-control-allow-origin'];
-  if (!Array.isArray(allowOriginHeader)) {
-    // No header, not allowed
-    return false;
-  }
-
-  // Header must be set to "*"
-  // We don't have a real Origin that we can check
-  return allowOriginHeader.join(',') === '*';
-};
-
-app.on('session-created', (session) => {
-  session.webRequest.onHeadersReceived((details, callback) => {
-    callback({
-      cancel: !isRequestAllowed(details)
-    });
-  });
-});

Vulnerable code: import './request-security';
import {app} from 'electron';

const isRequestAllowed = (details) => {
  const url = new URL(details.url);
  if (url.protocol === 'file:') {
    // Requests to files must be inside the application
    return url.pathname.startsWith(__dirname);
  }

  if (details.resourceType !== 'xhr') {
    // Immune to CORS even in standard browsers
    return true;
  }

  if (url.protocol !== 'http:' && url.protocol !== 'https:') {
    // Special protocols are immune to CORS
    return true;
  }

  const allowOriginHeader = details.responseHeaders['access-control-allow-origin'];
  if (!Array.isArray(allowOriginHeader)) {
    // No header, not allowed
    return false;
  }

  // Header must be set to "*"
  // We don't have a real Origin that we can check
  return allowOriginHeader.join(',') === '*';
};

app.on('session-created', (session) => {
  session.webRequest.onHeadersReceived((details, callback) => {
    callback({
      cancel: !isRequestAllowed(details)
    });
  });
});