diff --git a/README.md b/README.md index 8caa85c..7ca8dad 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,12 @@ **If using Linux it is highly recommended to disable write protection** (needing root to overwrite files) for your Discord install if you have it enabled. It is not much of a security defecit as Windows has no write protection as well. This enables updating the asar and potentially host updating further on. ## Config -You can configure OpenAsar via `settings.json` (found in your Discord app data / user data), under a `openasar` object. Keep in mind most options are defaults for good reason, they may temporarily brick your client until you revert your changes. The avaliable options are: +You can configure OpenAsar via `settings.json` (found in your Discord app data / user data), under a `openasar` object. Keep in mind most options are defaults for good reason. The avaliable options are: - `quickstart` (bool, default false) - whether to use Quickstart (experimental) - `skipStartupUpdateChecks` (bool, default false) - skips startup update checking (Linux-only) - `autoupdate` (bool, default true) - whether to autoupdate OpenAsar after Discord startup - `multiInstance` (bool, default false) - whether to enable multi-instance +- `ssoeAllowlist` (bool, default true) - whether to use safer custom method of opening external urls (true) or normal Discord's method (false) An example of a settings.json with OpenAsar config: ```json diff --git a/roadmap.md b/roadmap.md index 6fbd22d..6de2071 100644 --- a/roadmap.md +++ b/roadmap.md @@ -12,5 +12,5 @@ - [X] `windowsUtils` - [X] `Settings` - [X] `Backoff` - - [ ] `securityUtils` + - [X] `securityUtils` - [ ] Compatibility / replication of original Discord splash \ No newline at end of file diff --git a/src/utils/securityUtils.js b/src/utils/securityUtils.js index 315b668..8573611 100644 --- a/src/utils/securityUtils.js +++ b/src/utils/securityUtils.js @@ -1,45 +1,36 @@ -"use strict"; +const { shell } = require('electron'); -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.saferShellOpenExternal = saferShellOpenExternal; -exports.checkUrlOriginMatches = checkUrlOriginMatches; +const BLOCKED_URL_PROTOCOLS = ['file:', 'javascript:', 'vbscript:', 'data:', 'about:', 'chrome:', 'ms-cxh:', 'ms-cxh-full:', 'ms-word:']; // From Discord +const allowedProtocols = [ 'https:', 'http:' ]; -var _electron = require("electron"); +exports.saferShellOpenExternal = (url) => { + let parsed; -var _url = _interopRequireDefault(require("url")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const BLOCKED_URL_PROTOCOLS = ['file:', 'javascript:', 'vbscript:', 'data:', 'about:', 'chrome:', 'ms-cxh:', 'ms-cxh-full:', 'ms-word:']; + try { + parsed = new URL(url); + } catch (_e) { return Promise.reject(); } -function saferShellOpenExternal(externalUrl) { - let parsedUrl; + const protocol = parsed.protocol?.toLowerCase(); - try { - parsedUrl = _url.default.parse(externalUrl); - } catch (_) { - return Promise.reject(); + let disallowed = false; + if (oaConfig.ssoeAllowlist === false) { // Allow config option to use traditional Discord check for compatibility + if (!protocol || BLOCKED_URL_PROTOCOLS.includes(protocol)) disallowed = true; + } else { + if (!allowedProtocols.includes(protocol)) disallowed = true; } - if (parsedUrl.protocol == null || BLOCKED_URL_PROTOCOLS.includes(parsedUrl.protocol.toLowerCase())) { - return Promise.reject(); - } + if (disallowed) return Promise.reject(); - return _electron.shell.openExternal(externalUrl); -} + return shell.openExternal(url); +}; -function checkUrlOriginMatches(urlA, urlB) { - let parsedUrlA; - let parsedUrlB; +exports.checkUrlOriginMatches = (url1, url2) => { + let parse1, parse2; try { - parsedUrlA = _url.default.parse(urlA); - parsedUrlB = _url.default.parse(urlB); - } catch (_) { - return false; - } + parse1 = new URL(url1); + parse2 = new URL(url2); + } catch (_e) { return Promise.reject(); } - return parsedUrlA.protocol === parsedUrlB.protocol && parsedUrlA.slashes === parsedUrlB.slashes && parsedUrlA.host === parsedUrlB.host; -} \ No newline at end of file + return parse1.protocol === parse2.protocol && parse1.host === parse2.host; +}; \ No newline at end of file