Browse Source

Disallow launching unknown apps via browser client.

CVE-2018-1000006
Aleš Pergl 7 years ago
parent
commit
ad0f44843d

+ 1 - 1
atom/app/atom_library_main.h

@@ -10,7 +10,7 @@
 #if defined(OS_MACOSX)
 extern "C" {
 __attribute__((visibility("default")))
-int AtomMain(int argc, const char* argv[]);
+int AtomMain(int argc, char* argv[]);
 
 __attribute__((visibility("default")))
 int AtomInitializeICUandStartNode(int argc, char *argv[]);

+ 2 - 2
atom/app/atom_library_main.mm

@@ -15,11 +15,11 @@
 #include "content/public/app/content_main.h"
 
 #if defined(OS_MACOSX)
-int AtomMain(int argc, const char* argv[]) {
+int AtomMain(int argc, char* argv[]) {
   atom::AtomMainDelegate delegate;
   content::ContentMainParams params(&delegate);
   params.argc = argc;
-  params.argv = argv;
+  params.argv = const_cast<const char**>(argv);
   atom::AtomCommandLine::Init(argc, argv);
   return content::ContentMain(params);
 }

+ 54 - 46
atom/app/atom_main.cc

@@ -4,7 +4,8 @@
 
 #include "atom/app/atom_main.h"
 
-#include <stdlib.h>
+#include <cstdlib>
+#include <vector>
 
 #if defined(OS_WIN)
 #include <windows.h>  // windows.h must be included first
@@ -14,9 +15,11 @@
 #include <tchar.h>
 
 #include "atom/app/atom_main_delegate.h"
+#include "atom/app/command_line_args.h"
 #include "atom/common/crash_reporter/win/crash_service_main.h"
 #include "base/environment.h"
 #include "base/process/launch.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/win/windows_version.h"
 #include "content/public/app/sandbox_helper_win.h"
 #include "sandbox/win/src/sandbox_types.h"
@@ -51,8 +54,39 @@ bool IsEnvSet(const char* name) {
 
 #if defined(OS_WIN)
 int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
-  int argc = 0;
-  wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
+  struct Arguments {
+    int argc = 0;
+    wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
+
+    ~Arguments() { LocalFree(argv); }
+  } arguments;
+
+  if (!arguments.argv)
+    return -1;
+
+#ifdef _DEBUG
+  // Don't display assert dialog boxes in CI test runs
+  static const auto kCI = "ELECTRON_CI";
+  bool is_ci = IsEnvSet(kCI);
+  if (!is_ci) {
+    for (int i = 0; i < arguments.argc; ++i) {
+      if (!_wcsicmp(arguments.argv[i], L"--ci")) {
+        is_ci = true;
+        _putenv_s(kCI, "1");  // set flag for child processes
+        break;
+      }
+    }
+  }
+  if (is_ci) {
+    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
+    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
+
+    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
+    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+
+    _set_error_mode(_OUT_TO_STDERR);
+  }
+#endif
 
   bool run_as_node = IsEnvSet(kRunAsNode);
 
@@ -60,49 +94,24 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
   if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
     base::RouteStdioToConsole(false);
 
-  // Convert argv to to UTF8
-  char** argv = new char*[argc];
-  for (int i = 0; i < argc; i++) {
-    // Compute the size of the required buffer
-    DWORD size = WideCharToMultiByte(CP_UTF8,
-                                     0,
-                                     wargv[i],
-                                     -1,
-                                     NULL,
-                                     0,
-                                     NULL,
-                                     NULL);
-    if (size == 0) {
-      // This should never happen.
-      fprintf(stderr, "Could not convert arguments to utf8.");
-      exit(1);
-    }
-    // Do the actual conversion
-    argv[i] = new char[size];
-    DWORD result = WideCharToMultiByte(CP_UTF8,
-                                       0,
-                                       wargv[i],
-                                       -1,
-                                       argv[i],
-                                       size,
-                                       NULL,
-                                       NULL);
-    if (result == 0) {
-      // This should never happen.
-      fprintf(stderr, "Could not convert arguments to utf8.");
-      exit(1);
-    }
-  }
-
   if (run_as_node) {
-    // Now that argv conversion is done, we can finally start.
+    std::vector<char*> argv(arguments.argc);
+    std::transform(
+        arguments.argv, arguments.argv + arguments.argc, argv.begin(),
+        [](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
+
     base::AtExitManager atexit_manager;
     base::i18n::InitializeICU();
-    return atom::NodeMain(argc, argv);
+    auto ret = atom::NodeMain(argv.size(), argv.data());
+    std::for_each(argv.begin(), argv.end(), free);
+    return ret;
   } else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
     return crash_service::Main(cmd);
   }
 
+  if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
+    return -1;
+
   sandbox::SandboxInterfaceInfo sandbox_info = {0};
   content::InitializeSandboxInfo(&sandbox_info);
   atom::AtomMainDelegate delegate;
@@ -110,33 +119,32 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
   content::ContentMainParams params(&delegate);
   params.instance = instance;
   params.sandbox_info = &sandbox_info;
-  atom::AtomCommandLine::Init(argc, argv);
-  atom::AtomCommandLine::InitW(argc, wargv);
+  atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
   return content::ContentMain(params);
 }
 
 #elif defined(OS_LINUX)  // defined(OS_WIN)
 
-int main(int argc, const char* argv[]) {
+int main(int argc, char* argv[]) {
   if (IsEnvSet(kRunAsNode)) {
     base::i18n::InitializeICU();
     base::AtExitManager atexit_manager;
-    return atom::NodeMain(argc, const_cast<char**>(argv));
+    return atom::NodeMain(argc, argv);
   }
 
   atom::AtomMainDelegate delegate;
   content::ContentMainParams params(&delegate);
   params.argc = argc;
-  params.argv = argv;
+  params.argv = const_cast<const char**>(argv);
   atom::AtomCommandLine::Init(argc, argv);
   return content::ContentMain(params);
 }
 
 #else  // defined(OS_LINUX)
 
-int main(int argc, const char* argv[]) {
+int main(int argc, char* argv[]) {
   if (IsEnvSet(kRunAsNode)) {
-    return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
+    return AtomInitializeICUandStartNode(argc, argv);
   }
 
   return AtomMain(argc, argv);

+ 1411 - 0
atom/app/command_line_args.cc

@@ -0,0 +1,1411 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "atom/app/command_line_args.h"
+
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/common/content_switches.h"
+
+namespace {
+
+bool IsUrlArg(const base::CommandLine::CharType* arg) {
+  // the first character must be a letter for this to be a URL
+  auto c = *arg;
+  if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) {
+    for (auto p = arg + 1; *p; ++p) {
+      c = *p;
+
+      // colon indicates that the argument starts with a URI scheme
+      if (c == ':') {
+        // it could also be a Windows filesystem path
+        if (p == arg + 1)
+          break;
+
+        return true;
+      }
+
+      // white-space before a colon means it's not a URL
+      if (c == ' ' || (0x9 <= c && c <= 0xD))
+        break;
+    }
+  }
+
+  return false;
+}
+
+const char* blacklist[] = {
+  // node
+  "inspect",
+  "inspect-brk",
+
+  // chromium switches:
+  // find ./ -name "*switches.cc" \
+  //   | xargs grep -P --no-filename "\"\S+\";" \
+  //   | perl -pe 's|^.*?"(\S+)";|  "$1",|' \
+  //   | sort | uniq
+  "?",
+  "0",
+  "accept-resource-provider",
+  "account-consistency",
+  "adaboost",
+  "aec-refined-adaptive-filter",
+  "agc-startup-min-volume",
+  "aggressive",
+  "aggressive-cache-discard",
+  "aggressive-tab-discard",
+  "all",
+  "allarticles",
+  "allow-cross-origin-auth-prompt",
+  "allow-external-pages",
+  "allow-failed-policy-fetch-for-test",
+  "allow-file-access-from-files",
+  "allow-hidden-media-playback",
+  "allow-http-background-page",
+  "allow-http-screen-capture",
+  "allow-insecure-localhost",
+  "allow-legacy-extension-manifests",
+  "allow-loopback-in-peer-connection",
+  "allow-nacl-crxfs-api",
+  "allow-nacl-file-handle-api",
+  "allow-nacl-socket-api",
+  "allow-no-sandbox-job",
+  "allow-outdated-plugins",
+  "allow-ra-in-dev-mode",
+  "allow-running-insecure-content",
+  "allow-sandbox-debugging",
+  "allow-silent-push",
+  "all-toolchains",
+  "alsa-check-close-timeout",
+  "alsa-enable-upsampling",
+  "alsa-fixed-output-sample-rate",
+  "alsa-input-device",
+  "alsa-mute-device-name",
+  "alsa-mute-element-name",
+  "alsa-output-avail-min",
+  "alsa-output-buffer-size",
+  "alsa-output-device",
+  "alsa-output-period-size",
+  "alsa-output-start-threshold",
+  "alsa-volume-device-name",
+  "alsa-volume-element-name",
+  "also-emit-success-logs",
+  "alternative",
+  "always-authorize-plugins",
+  "always-on",
+  "alwaystrue",
+  "always-use-complex-text",
+  "amd-switchable",
+  "android-fonts-path",
+  "android-stderr-port",
+  "android-stdin-port",
+  "android-stdout-port",
+  "angle",
+  "app",
+  "app-auto-launched",
+  "app-id",
+  "apple",
+  "app-mode-auth-code",
+  "app-mode-oauth-token",
+  "app-mode-oem-manifest",
+  "apps-gallery-download-url",
+  "apps-gallery-update-url",
+  "apps-gallery-url",
+  "app-shell-allow-roaming",
+  "app-shell-host-window-size",
+  "app-shell-preferred-network",
+  "app-shell-refresh-token",
+  "app-shell-user",
+  "apps-keep-chrome-alive-in-tests",
+  "arc-availability",
+  "arc-available",
+  "arc-start-mode",
+  "arc-transition-migration-required",
+  "args",
+  "artifacts-dir",
+  "ash-constrain-pointer-to-root",
+  "ash-debug-shortcuts",
+  "ash-dev-shortcuts",
+  "ash-disable-smooth-screen-rotation",
+  "ash-disable-tablet-autohide-titlebars",
+  "ash-disable-touch-exploration-mode",
+  "ash-enable-magnifier-key-scroller",
+  "ash-enable-mirrored-screen",
+  "ash-enable-night-light",
+  "ash-enable-palette-on-all-displays",
+  "ash-enable-scale-settings-tray",
+  "ash-enable-software-mirroring",
+  "ash-enable-unified-desktop",
+  "ash-estimated-presentation-delay",
+  "ash-hide-notifications-for-factory",
+  "ash-host-window-bounds",
+  "ash-shelf-color",
+  "ash-shelf-color-scheme",
+  "ash-touch-hud",
+  "ash-webui-init",
+  "attestation-server",
+  "audio-buffer-size",
+  "audio-output-channels",
+  "aura-legacy-power-button",
+  "auth-ext-path",
+  "auth-server-whitelist",
+  "auth-spnego-account-type",
+  "auto",
+  "auto-open-devtools-for-tabs",
+  "autoplay-policy",
+  "auto-select-desktop-capture-source",
+  "blink-settings",
+  "bootstrap",
+  "browser",
+  "browser-startup-dialog",
+  "browser-subprocess-path",
+  "browser-test",
+  "bwsi",
+  "bypass-app-banner-engagement-checks",
+  "canvas-msaa-sample-count",
+  "cast-initial-screen-height",
+  "cast-initial-screen-width",
+  "cc-layer-tree-test-long-timeout",
+  "cc-layer-tree-test-no-timeout",
+  "cc-rebaseline-pixeltests",
+  "cellular-first",
+  "cellular-only",
+  "check-for-update-interval",
+  "check-layout-test-sys-deps",
+  "child-wallpaper-large",
+  "child-wallpaper-small",
+  "chrome-home-swipe-logic",
+  "ChromeOSMemoryPressureHandling",
+  "cipher-suite-blacklist",
+  "clamshell",
+  "class",
+  "clear-token-service",
+  "cloud-print-file",
+  "cloud-print-file-type",
+  "cloud-print-job-title",
+  "cloud-print-print-ticket",
+  "cloud-print-setup-proxy",
+  "cloud-print-url",
+  "cloud-print-xmpp-endpoint",
+  "color",
+  "compensate-for-unstable-pinch-zoom",
+  "compile-shader-always-succeeds",
+  "component-updater",
+  "connectivity-check-url",
+  "conservative",
+  "content-image-texture-target",
+  "content-shell-host-window-size",
+  "controller",
+  "crash-dumps-dir",
+  "crash-on-failure",
+  "crash-on-hang-threads",
+  "crashpad-handler",
+  "crash-server-url",
+  "crash-test",
+  "create-browser-on-startup-for-tests",
+  "cros-gaia-api-v1",
+  "crosh-command",
+  "cros-region",
+  "cros-regions-mode",
+  "cryptauth-http-host",
+  "custom-devtools-frontend",
+  "custom-launcher-page",
+  "custom_summary",
+  "d3d11",
+  "d3d9",
+  "d3d-support",
+  "daemon",
+  "dark_muted",
+  "dark_vibrant",
+  "data-path",
+  "data-reduction-proxy-config-url",
+  "data-reduction-proxy-experiment",
+  "data-reduction-proxy-http-proxies",
+  "data-reduction-proxy-lo-fi",
+  "data-reduction-proxy-pingback-url",
+  "data-reduction-proxy-secure-proxy-check-url",
+  "data-reduction-proxy-server-experiments-disabled",
+  "dbus-stub",
+  "debug-devtools",
+  "debug-enable-frame-toggle",
+  "debug-packed-apps",
+  "debug-print",
+  "default",
+  "default-background-color",
+  "default-tile-height",
+  "default-tile-width",
+  "default-wallpaper-is-oem",
+  "default-wallpaper-large",
+  "default-wallpaper-small",
+  "demo",
+  "derelict-detection-timeout",
+  "derelict-idle-timeout",
+  "desktop",
+  "desktop-window-1080p",
+  "deterministic-fetch",
+  "device-management-url",
+  "device-scale-factor",
+  "devtools-flags",
+  "diagnostics",
+  "diagnostics-format",
+  "diagnostics-recovery",
+  "dice",
+  "dice_fix_auth_errors",
+  "disable",
+  "disable-2d-canvas-clip-aa",
+  "disable-2d-canvas-image-chromium",
+  "disable-3d-apis",
+  "disable-accelerated-2d-canvas",
+  "disable-accelerated-jpeg-decoding",
+  "disable-accelerated-mjpeg-decode",
+  "disable-accelerated-video-decode",
+  "disable-appcontainer",
+  "disable-app-info-dialog-mac",
+  "disable-app-list-dismiss-on-blur",
+  "disable-app-window-cycling",
+  "disable-arc-data-wipe",
+  "disable-arc-opt-in-verification",
+  "disable-audio-support-for-desktop-share",
+  "disable-avfoundation-overlays",
+  "disable-backgrounding-occluded-windows",
+  "disable-background-networking",
+  "disable-background-timer-throttling",
+  "disable-backing-store-limit",
+  "disable-blink-features",
+  "disable-boot-animation",
+  "disable-breakpad",
+  "disable-browser-task-scheduler",
+  "disable-bundled-ppapi-flash",
+  "disable-canvas-aa",
+  "disable-captive-portal-bypass-proxy",
+  "disable-cast-streaming-hw-encoding",
+  "disable-checker-imaging",
+  "disable-clear-browsing-data-counters",
+  "disable-client-side-phishing-detection",
+  "disable-cloud-import",
+  "disable-component-cloud-policy",
+  "disable-component-extensions-with-background-pages",
+  "disable-component-update",
+  "disable-composited-antialiasing",
+  "disable-contextual-search",
+  "disabled",
+  "disable-d3d11",
+  "disable-databases",
+  "disable-datasaver-prompt",
+  "disable-default-apps",
+  "disable-demo-mode",
+  "disable-device-disabling",
+  "disable-device-discovery-notifications",
+  "disable-dinosaur-easter-egg",
+  "disable-direct-composition",
+  "disable-direct-composition-layers",
+  "disable-directwrite-for-ui",
+  "disable-display-list-2d-canvas",
+  "disable-distance-field-text",
+  "disabled-new-style-notification",
+  "disable-domain-blocking-for-3d-apis",
+  "disable-domain-reliability",
+  "disable-drive-search-in-app-launcher",
+  "disable-dwm-composition",
+  "disable-encryption-migration",
+  "disable-eol-notification",
+  "disable-es3-apis",
+  "disable-es3-gl-context",
+  "disable-extensions",
+  "disable-extensions-except",
+  "disable-extensions-file-access-check",
+  "disable-extensions-http-throttling",
+  "disable-features",
+  "disable-field-trial-config",
+  "disable-file-manager-touch-mode",
+  "disable-file-system",
+  "disable-flash-3d",
+  "disable-flash-stage3d",
+  "disable-fullscreen-low-power-mode",
+  "disable-fullscreen-tab-detaching",
+  "disable-gaia-services",
+  "disable-gesture-editing",
+  "disable-gesture-requirement-for-presentation",
+  "disable-gesture-typing",
+  "disable-gl-drawing-for-tests",
+  "disable-gl-error-limit",
+  "disable-gl-extensions",
+  "disable-glsl-translator",
+  "disable-gpu",
+  "disable-gpu-compositing",
+  "disable-gpu-driver-bug-workarounds",
+  "disable-gpu-early-init",
+  "disable-gpu-memory-buffer-compositor-resources",
+  "disable-gpu-memory-buffer-video-frames",
+  "disable-gpu-process-crash-limit",
+  "disable-gpu-program-cache",
+  "disable-gpu-rasterization",
+  "disable-gpu-sandbox",
+  "disable-gpu-shader-disk-cache",
+  "disable-gpu-vsync",
+  "disable-gpu-watchdog",
+  "disable-hang-monitor",
+  "disable-hid-detection-on-oobe",
+  "disable-histogram-customizer",
+  "disable-hosted-app-shim-creation",
+  "disable-hosted-apps-in-windows",
+  "disable-infobars",
+  "disable-in-process-stack-traces",
+  "disable-input-ime-api",
+  "disable-input-view",
+  "disable-ios-password-suggestions",
+  "disable-javascript-harmony-shipping",
+  "disable-kill-after-bad-ipc",
+  "disable-lcd-text",
+  "disable-legacy-window",
+  "disable-local-storage",
+  "disable-lock-screen-apps",
+  "disable-logging",
+  "disable-logging-redirect",
+  "disable-login-animations",
+  "disable-login-screen-apps",
+  "disable-low-end-device-mode",
+  "disable-low-latency-dxva",
+  "disable-low-res-tiling",
+  "disable-machine-cert-request",
+  "disable-mac-overlays",
+  "disable-mac-views-native-app-windows",
+  "disable-main-frame-before-activation",
+  "disable-md-error-screen",
+  "disable-md-oobe",
+  "disable-media-session-api",
+  "disable-media-suspend",
+  "disable-merge-key-char-events",
+  "disable-mojo-local-storage",
+  "disable-mojo-renderer",
+  "disable-mtp-write-support",
+  "disable-multi-display-layout",
+  "disable-namespace-sandbox",
+  "disable-native-gpu-memory-buffers",
+  "disable-network-portal-notification",
+  "disable-new-korean-ime",
+  "disable-new-virtual-keyboard-behavior",
+  "disable-new-zip-unpacker",
+  "disable-notifications",
+  "disable-ntp-most-likely-favicons-from-server",
+  "disable-ntp-popular-sites",
+  "disable-nv12-dxgi-video",
+  "disable-offer-store-unmasked-wallet-cards",
+  "disable-offer-upload-credit-cards",
+  "disable-office-editing-component-extension",
+  "disable-offline-auto-reload",
+  "disable-offline-auto-reload-visible-only",
+  "disable-origin-trial-controlled-blink-features",
+  "disable-overscroll-edge-effect",
+  "disable-panel-fitting",
+  "disable-partial-raster",
+  "disable-password-generation",
+  "disable-pepper-3d",
+  "disable-pepper-3d-image-chromium",
+  "disable-permission-action-reporting",
+  "disable-permissions-api",
+  "disable-per-user-timezone",
+  "disable-physical-keyboard-autocorrect",
+  "disable-pinch",
+  "disable-pnacl-crash-throttling",
+  "disable-popup-blocking",
+  "disable-prefer-compositing-to-lcd-text",
+  "disable-presentation-api",
+  "disable-print-preview",
+  "disable-prompt-on-repost",
+  "disable-proximity-auth-bluetooth-low-energy-discovery",
+  "disable-pull-to-refresh-effect",
+  "disable-push-api-background-mode",
+  "disable-reading-from-canvas",
+  "disable-remote-core-animation",
+  "disable-remote-fonts",
+  "disable-remote-playback-api",
+  "disable-renderer-accessibility",
+  "disable-renderer-backgrounding",
+  "disable-resize-lock",
+  "disable-rgba-4444-textures",
+  "disable-rollback-option",
+  "disable-rtc-smoothness-algorithm",
+  "disable-screen-orientation-lock",
+  "disable-search-geolocation-disclosure",
+  "disable-seccomp-filter-sandbox",
+  "disable-setuid-sandbox",
+  "disable-shader-name-hashing",
+  "disable-shared-workers",
+  "disable-signin-promo",
+  "disable-signin-scoped-device-id",
+  "disable-single-click-autofill",
+  "disable-skia-runtime-opts",
+  "disable-slimming-paint-invalidation",
+  "disable-slim-navigation-manager",
+  "disable-smooth-scrolling",
+  "disable-software-rasterizer",
+  "disable-speech-api",
+  "disable-suggestions-ui",
+  "disable-surface-references",
+  "disable-sync",
+  "disable-sync-app-list",
+  "disable-sync-types",
+  "disable-system-timezone-automatic-detection",
+  "disable-tab-for-desktop-share",
+  "disable-third-party-keyboard-workaround",
+  "disable-threaded-animation",
+  "disable-threaded-compositing",
+  "disable-threaded-scrolling",
+  "disable-timeouts-for-profiling",
+  "disable-touch-adjustment",
+  "disable-touch-drag-drop",
+  "disable-translate-new-ux",
+  "disable-usb-keyboard-detect",
+  "disable-v8-idle-tasks",
+  "disable-vaapi-accelerated-video-encode",
+  "disable-virtual-keyboard-overscroll",
+  "disable-voice-input",
+  "disable-volume-adjust-sound",
+  "disable-wake-on-wifi",
+  "disable-webgl",
+  "disable-webgl-image-chromium",
+  "disable-web-notification-custom-layouts",
+  "disable-webrtc-encryption",
+  "disable-webrtc-hw-decoding",
+  "disable-webrtc-hw-encoding",
+  "disable-web-security",
+  "disable-win32k-lockdown",
+  "disable-xss-auditor",
+  "disable-zero-browsers-open-for-tests",
+  "disable-zero-copy",
+  "disable-zero-copy-dxgi-video",
+  "disallow-non-exact-resource-reuse",
+  "disk-cache-dir",
+  "disk-cache-size",
+  "display",
+  "dmg-device",
+  "dns-log-details",
+  "document-user-activation-required",
+  "dom-automation",
+  "dotfile",
+  "draft",
+  "draw-view-bounds-rects",
+  "duck-flash",
+  "dump-blink-runtime-call-stats",
+  "dump-browser-histograms",
+  "dump-dom",
+  "eafe-path",
+  "eafe-url",
+  "easy-unlock-app-path",
+  "edge-touch-filtering",
+  "egl",
+  "elevate",
+  "embedded-extension-options",
+  "emphasize-titles-in-omnibox-dropdown",
+  "emulate-shader-precision",
+  "enable-accelerated-2d-canvas",
+  "enable-accelerated-vpx-decode",
+  "enable-accessibility-tab-switcher",
+  "enable-adaptive-selection-handle-orientation",
+  "enable-aggressive-domstorage-flushing",
+  "enable-android-wallpapers-app",
+  "enable-appcontainer",
+  "enable-app-info-dialog-mac",
+  "enable-app-list",
+  "enable-app-window-cycling",
+  "enable-arc",
+  "enable-arc-oobe-optin",
+  "enable-async-event-targeting",
+  "enable-audio-debug-recordings-from-extension",
+  "enable-audio-focus",
+  "enable-automation",
+  "enable-background-fetch-persistence",
+  "enable-benchmarking",
+  "enable-ble-advertising-in-apps",
+  "enable-blink-features",
+  "enable-bookmark-undo",
+  "enable-browser-side-navigation",
+  "enable-browser-task-scheduler",
+  "enable-cast-receiver",
+  "enable-checker-imaging",
+  "enable-chromevox-arc-support",
+  "enable-clear-browsing-data-counters",
+  "enable-cloud-print-proxy",
+  "enable-cloud-print-xps",
+  "enable-consumer-kiosk",
+  "enable-contextual-search",
+  "enable-crash-reporter",
+  "enable-crash-reporter-for-testing",
+  "enable-crx-hash-check",
+  "enabled",
+  "enabled-2g",
+  "enabled-3g",
+  "enable-data-reduction-proxy-bypass-warning",
+  "enable-data-reduction-proxy-force-pingback",
+  "enable-data-reduction-proxy-lite-page",
+  "enable-data-reduction-proxy-savings-promo",
+  "enable-datasaver-prompt",
+  "enable-device-discovery-notifications",
+  "enable-devtools-experiments",
+  "enable-direct-composition-layers",
+  "enable-display-list-2d-canvas",
+  "enable-distance-field-text",
+  "enable-distillability-service",
+  "enabled-new-style-notification",
+  "enable-domain-reliability",
+  "enable-dom-distiller",
+  "enable-drive-search-in-app-launcher",
+  "enable-drm-atomic",
+  "enabled-slow2g",
+  "enable-embedded-extension-options",
+  "enable-encryption-migration",
+  "enable-encryption-selection",
+  "enable-es3-apis",
+  "enable-exclusive-audio",
+  "enable-experimental-accessibility-features",
+  "enable-experimental-canvas-features",
+  "enable-experimental-extension-apis",
+  "enable-experimental-fullscreen-exit-ui",
+  "enable-experimental-input-view-features",
+  "enable-experimental-web-platform-features",
+  "enable-extension-activity-logging",
+  "enable-extension-activity-log-testing",
+  "enable-extension-assets-sharing",
+  "enable-external-drive-rename",
+  "enable-fast-unload",
+  "enable-features",
+  "enable-file-manager-touch-mode",
+  "enable-first-run-ui-transitions",
+  "enable-floating-virtual-keyboard",
+  "enable-font-antialiasing",
+  "enable-fullscreen-tab-detaching",
+  "enable-fullscreen-toolbar-reveal",
+  "enable-google-branded-context-menu",
+  "enable-gpu-async-worker-context",
+  "enable-gpu-benchmarking",
+  "enable-gpu-client-logging",
+  "enable-gpu-client-tracing",
+  "enable-gpu-command-logging",
+  "enable-gpu-debugging",
+  "enable-gpu-driver-debug-logging",
+  "enable-gpu-memory-buffer-compositor-resources",
+  "enable-gpu-memory-buffer-video-frames",
+  "enable-gpu-rasterization",
+  "enable-gpu-service-logging",
+  "enable-gpu-service-tracing",
+  "enable-hardware-overlays",
+  "enable-harfbuzz-rendertext",
+  "enable-heap-profiling",
+  "enable-hosted-app-quit-notification",
+  "enable-hosted-apps-in-windows",
+  "enable-hotword-hardware",
+  "enable-hung-renderer-infobar",
+  "enable-inband-text-tracks",
+  "enable-input-ime-api",
+  "enable-instant-tethering",
+  "enable-internal-media-session",
+  "enable-ios-handoff-to-other-devices",
+  "enable-layer-lists",
+  "enable-lcd-text",
+  "enable-leak-detection",
+  "enable-local-file-accesses",
+  "enable-local-sync-backend",
+  "enable-logging",
+  "enable-longpress-drag-selection",
+  "enable-low-end-device-mode",
+  "enable-low-res-tiling",
+  "enable-mac-views-native-app-windows",
+  "enable-main-frame-before-activation",
+  "enable-md-feedback",
+  "enable-media-suspend",
+  "enable-merge-key-char-events",
+  "enable-message-center-always-scroll-up-upon-notification-removal",
+  "enable-nacl",
+  "enable-nacl-debug",
+  "enable-nacl-nonsfi-mode",
+  "enable-native-gpu-memory-buffers",
+  "enable-natural-scroll-default",
+  "enable-navigation-tracing",
+  "enable-net-benchmarking",
+  "enable-network-information-downlink-max",
+  "enable-network-portal-notification",
+  "enable-new-app-menu-icon",
+  "enable-ntp-most-likely-favicons-from-server",
+  "enable-ntp-popular-sites",
+  "enable-ntp-search-engine-country-detection",
+  "enable-offer-store-unmasked-wallet-cards",
+  "enable-offer-upload-credit-cards",
+  "enable-offline-auto-reload",
+  "enable-offline-auto-reload-visible-only",
+  "enable-oop-rasterization",
+  "enable-osk-overscroll",
+  "enable-override-bookmarks-ui",
+  "enable-partial-raster",
+  "enable-password-generation",
+  "enable-pepper-testing",
+  "enable-permission-action-reporting",
+  "enable-physical-keyboard-autocorrect",
+  "enable-picture-in-picture",
+  "enable-pinch",
+  "enable-pixel-canvas-recording",
+  "enable-pixel-output-in-tests",
+  "enable-plugin-placeholder-testing",
+  "enable-potentially-annoying-security-features",
+  "enable-power-overlay",
+  "enable-precise-memory-info",
+  "enable-prefer-compositing-to-lcd-text",
+  "enable-print-browser",
+  "enable-print-preview-register-promos",
+  "enable-profile-shortcut-manager",
+  "enable-profiling",
+  "enable-push-api-background-mode",
+  "enable-refresh-token-annotation-request",
+  "enable-request-tablet-site",
+  "enable-rgba-4444-textures",
+  "enable-sandbox",
+  "enable-sandbox-logging",
+  "enable-screenshot-testing-with-mode",
+  "enable-scripts-require-action",
+  "enable-scroll-prediction",
+  "enable-service-manager-tracing",
+  "enable-sgi-video-sync",
+  "enable-signin-promo",
+  "enable-single-click-autofill",
+  "enable-site-settings",
+  "enable-skia-benchmarking",
+  "enable-slimming-paint-invalidation",
+  "enable-slimming-paint-v2",
+  "enable-slim-navigation-manager",
+  "enable-smooth-scrolling",
+  "enable-spatial-navigation",
+  "enable-spdy-proxy-auth",
+  "enable-speech-dispatcher",
+  "enable-spelling-feedback-field-trial",
+  "enable-spotlight-actions",
+  "enable-stats-collection-bindings",
+  "enable-stats-table",
+  "enable-strict-mixed-content-checking",
+  "enable-strict-powerful-feature-restrictions",
+  "enable-suggestions-ui",
+  "enable-suggestions-with-substring-match",
+  "enable-supervised-user-managed-bookmarks-folder",
+  "enable-surface-synchronization",
+  "enable-swap-buffers-with-bounds",
+  "enable-sync-app-list",
+  "enable-sync-articles",
+  "enable-tab-audio-muting",
+  "enable-tablet-splitview",
+  "enable-tcp-fastopen",
+  "enable-third-party-keyboard-workaround",
+  "enable-threaded-compositing",
+  "enable-threaded-texture-mailboxes",
+  "enable-tile-compression",
+  "enable-touch-calibration-setting",
+  "enable-touch-drag-drop",
+  "enable-touchpad-three-finger-click",
+  "enable-touchview",
+  "enable-trace-app-source",
+  "enable-tracing",
+  "enable-tracing-output",
+  "enable-translate-new-ux",
+  "enable-ui-devtools",
+  "enable-usermedia-screen-capturing",
+  "enable-user-metrics",
+  "enable-use-zoom-for-dsf",
+  "enable-video-player-chromecast-support",
+  "enable-viewport",
+  "enable-virtual-keyboard",
+  "enable-voice-interaction",
+  "enable-vtune-support",
+  "enable-vulkan",
+  "enable-wayland-server",
+  "enable-webfonts-intervention-trigger",
+  "enable-webfonts-intervention-v2",
+  "enable-webgl-draft-extensions",
+  "enable-webgl-image-chromium",
+  "enable-web-notification-custom-layouts",
+  "enable-webrtc-event-logging-from-extension",
+  "enable-webrtc-srtp-aes-gcm",
+  "enable-webrtc-srtp-encrypted-headers",
+  "enable-webrtc-stun-origin",
+  "enable-webview-variations",
+  "enable-webvr",
+  "enable-wifi-credential-sync",
+  "enable-win7-webrtc-hw-h264-decoding",
+  "enable-zero-copy",
+  "enable-zip-archiver-on-file-manager",
+  "encode-binary",
+  "enforce",
+  "enforce-gl-minimums",
+  "enforce_strict",
+  "enforce-webrtc-ip-permission-check",
+  "enterprise-disable-arc",
+  "enterprise-enable-forced-re-enrollment",
+  "enterprise-enable-license-type-selection",
+  "enterprise-enable-zero-touch-enrollment",
+  "enterprise-enrollment-initial-modulus",
+  "enterprise-enrollment-modulus-limit",
+  "error-console",
+  "evaluate_capability",
+  "evaluate-type",
+  "experiment",
+  "explicitly-allowed-ports",
+  "expose-internals-for-testing",
+  "extension-content-verification",
+  "extension-process",
+  "extensions-install-verification",
+  "extensions-multi-account",
+  "extensions-not-webstore",
+  "extensions-on-chrome-urls",
+  "extensions-update-frequency",
+  "extra-search-query-params",
+  "fail-on-unused-args",
+  "fake-variations-channel",
+  "false",
+  "fast",
+  "fast-start",
+  "feedback-server",
+  "field-trial-handle",
+  "first-exec-after-boot",
+  "flag-switches-begin",
+  "flag-switches-end",
+  "font-cache-shared-handle",
+  "force-android-app-mode",
+  "force-app-mode",
+  "force-clamshell-power-button",
+  "force-color-profile",
+  "force-desktop-ios-promotion",
+  "force-device-scale-factor",
+  "force-dev-mode-highlighting",
+  "force-display-list-2d-canvas",
+  "force-effective-connection-type",
+  "force-enable-metrics-reporting",
+  "force-enable-stylus-tools",
+  "force-fieldtrial-params",
+  "force-fieldtrials",
+  "force-first-run",
+  "force-first-run-ui",
+  "force-gpu-mem-available-mb",
+  "force-gpu-rasterization",
+  "force-happiness-tracking-system",
+  "force-load-easy-unlock-app-in-tests",
+  "force-local-ntp",
+  "force-login-manager-in-tests",
+  "force-mediafoundation",
+  "force-overlay-fullscreen-video",
+  "force-password-reauth",
+  "force-pnacl-subzero",
+  "force-presentation-receiver-for-testing",
+  "force-renderer-accessibility",
+  "force-show-update-menu-badge",
+  "force-show-update-menu-item",
+  "force-system-compositor-mode",
+  "force-tablet-mode",
+  "force-text-direction",
+  "force-ui-direction",
+  "force-variation-ids",
+  "force-video-overlays",
+  "force-wave-audio",
+  "force-webrtc-ip-handling-policy",
+  "full-memory-crash-report",
+  "gaia-url",
+  "gcm-checkin-url",
+  "gcm-mcs-endpoint",
+  "gcm-registration-url",
+  "generate-accessibility-test-expectations",
+  "gl",
+  "gl-composited-overlay-candidate-quad-border",
+  "gles",
+  "gl-shader-interm-output",
+  "golden-screenshots-dir",
+  "google-apis-url",
+  "google-base-url",
+  "google-doodle-url",
+  "google-url",
+  "gpu-active-device-id",
+  "gpu-active-vendor-id",
+  "gpu-device-id",
+  "gpu-driver-date",
+  "gpu-driver-vendor",
+  "gpu-driver-version",
+  "gpu-launcher",
+  "gpu-no-complete-info-collection",
+  "gpu-no-context-lost",
+  "gpu-process",
+  "gpu-program-cache-size-kb",
+  "gpu-rasterization-msaa-sample-count",
+  "gpu-sandbox-allow-sysv-shm",
+  "gpu-sandbox-failures-fatal",
+  "gpu-sandbox-start-early",
+  "gpu-secondary-device-ids",
+  "gpu-secondary-vendor-ids",
+  "gpu-startup-dialog",
+  "gpu-testing-device-id",
+  "gpu-testing-driver-date",
+  "gpu-testing-gl-renderer",
+  "gpu-testing-gl-vendor",
+  "gpu-testing-gl-version",
+  "gpu-testing-os-version",
+  "gpu-testing-secondary-device-ids",
+  "gpu-testing-secondary-vendor-ids",
+  "gpu-testing-vendor-id",
+  "gpu-vendor-id",
+  "graphics-buffer-count",
+  "guest-wallpaper-large",
+  "guest-wallpaper-small",
+  "h",
+  "has-chromeos-diamond-key",
+  "has-chromeos-keyboard",
+  "has-internal-stylus",
+  "headless",
+  "help",
+  "hide",
+  "hide-icons",
+  "hide-scrollbars",
+  "history-entry-requires-user-gesture",
+  "homedir",
+  "homepage",
+  "host",
+  "host-pairing-oobe",
+  "host-resolver-rules",
+  "icu-data-dir",
+  "ignore-autocomplete-off-autofill",
+  "ignore-autoplay-restrictions",
+  "ignore-certificate-errors",
+  "ignore-certificate-errors-spki-list",
+  "ignore-gpu-blacklist",
+  "ignore-urlfetcher-cert-requests",
+  "ignore-user-profile-mapping-for-tests",
+  "incognito",
+  "in-process-gpu",
+  "input",
+  "install-chrome-app",
+  "install-supervised-user-whitelists",
+  "instant-process",
+  "invalidation-use-gcm-channel",
+  "ipc-connection-timeout",
+  "ipc-dump-directory",
+  "ipc-fuzzer-testcase",
+  "isolate-origins",
+  "isolate-sites-for-testing",
+  "is-running-in-mash",
+  "javascript-harmony",
+  "js-flags",
+  "keep-alive-for-test",
+  "kiosk",
+  "kiosk-printing",
+  "lang",
+  "last-launched-app",
+  "layer",
+  "light_muted",
+  "light_vibrant",
+  "limit-fps",
+  "load-and-launch-app",
+  "load-apps",
+  "load-extension",
+  "load-media-router-component-extension",
+  "local-heuristics-only-for-password-generation",
+  "local-ntp-reload",
+  "local-sync-backend-dir",
+  "log-gpu-control-list-decisions",
+  "login-manager",
+  "login-profile",
+  "login-user",
+  "log-level",
+  "log-net-log",
+  "loopback-i2s-bits",
+  "loopback-i2s-bus-name",
+  "loopback-i2s-channels",
+  "loopback-i2s-rate-hz",
+  "lso-url",
+  "ltr",
+  "main-frame-resizes-are-orientation-changes",
+  "make-chrome-default",
+  "make-default-browser",
+  "managed-user-id",
+  "managed-user-sync-token",
+  "markdown",
+  "market-url-for-testing",
+  "mark-non-secure-as",
+  "mash",
+  "material",
+  "material-design-ink-drop-animation-speed",
+  "material-hybrid",
+  "max-gum-fps",
+  "max-output-volume-dba1m",
+  "max-untiled-layer-height",
+  "max-untiled-layer-width",
+  "media-cache-size",
+  "memlog",
+  "memory-pressure-off",
+  "memory-pressure-thresholds",
+  "memory-pressure-thresholds-mb",
+  "mem-pressure-system-reserved-kb",
+  "message-center-changes-while-open",
+  "method",
+  "metrics-client-id",
+  "metrics-recording-only",
+  "mhtml-generator-option",
+  "mirror",
+  "mock",
+  "mojo-local-storage",
+  "mojo-pipe-token",
+  "monitoring-destination-id",
+  "mse-audio-buffer-size-limit",
+  "mse-video-buffer-size-limit",
+  "mus",
+  "mus-config",
+  "mute-audio",
+  "nacl-broker",
+  "nacl-dangerous-no-sandbox-nonsfi",
+  "nacl-debug-mask",
+  "nacl-gdb",
+  "nacl-gdb-script",
+  "nacl-loader",
+  "nacl-loader-nonsfi",
+  "native",
+  "native-crx-bindings",
+  "need-arc-migration-policy-check",
+  "netifs-to-ignore",
+  "net-log-capture-mode",
+  "network-country-iso",
+  "network-settings-config",
+  "new-window",
+  "nocolor",
+  "no-default-browser-check",
+  "noerrdialogs",
+  "no-experiments",
+  "no-first-run",
+  "no-managed-user-acknowledgment-check",
+  "none",
+  "no-network-profile-warning",
+  "non-material",
+  "non-secure",
+  "non-secure-after-editing",
+  "non-secure-while-incognito",
+  "non-secure-while-incognito-or-editing",
+  "no-pings",
+  "no-proxy-server",
+  "no-referrers",
+  "normal_muted",
+  "normal_vibrant",
+  "no-sandbox",
+  "no-service-autorun",
+  "no-session-id",
+  "no-startup-window",
+  "note-taking-app-ids",
+  "no-user-gesture-required",
+  "no-wifi",
+  "no-zygote",
+  "ntp-snippets-add-incomplete",
+  "null",
+  "num-raster-threads",
+  "oauth2-client-id",
+  "oauth2-client-secret",
+  "off",
+  "on",
+  "oobe-bootstrapping-master",
+  "oobe-force-show-screen",
+  "oobe-guest-session",
+  "oobe-skip-postlogin",
+  "oobe-timer-interval",
+  "open-ash",
+  "opengraph",
+  "original-process-start-time",
+  "origin-trial-disabled-features",
+  "origin-trial-disabled-tokens",
+  "origin-trial-public-key",
+  "osmesa",
+  "output",
+  "override",
+  "override-metrics-upload-url",
+  "override-plugin-power-saver-for-testing",
+  "override-use-software-gl-for-tests",
+  "overscroll-history-navigation",
+  "overscroll-start-threshold",
+  "ozone-dump-file",
+  "ozone-platform",
+  "pack-extension",
+  "pack-extension-key",
+  "parent-profile",
+  "parent-window",
+  "passive-listeners-default",
+  "password-store",
+  "permission-request-api-scope",
+  "permission-request-api-url",
+  "ppapi",
+  "ppapi-antialiased-text-enabled",
+  "ppapi-broker",
+  "ppapi-flash-args",
+  "ppapi-flash-path",
+  "ppapi-flash-version",
+  "ppapi-in-process",
+  "ppapi-plugin-launcher",
+  "ppapi-startup-dialog",
+  "ppapi-subpixel-rendering-setting",
+  "/prefetch:1",
+  "/prefetch:2",
+  "/prefetch:3",
+  "/prefetch:4",
+  "/prefetch:5",
+  "/prefetch:6",
+  "/prefetch:8",
+  "previous-app",
+  "primary",
+  "print-to-pdf",
+  "privet-ipv6-only",
+  "process-per-site",
+  "process-per-tab",
+  "product-version",
+  "profile-directory",
+  "profiler-timing",
+  "profiling-at-start",
+  "profiling-file",
+  "profiling-flush",
+  "progress-bar-animation",
+  "progress-bar-completion",
+  "prompt-for-external-extensions",
+  "proxy-auto-detect",
+  "proxy-bypass-list",
+  "proxy-pac-url",
+  "proxy-server",
+  "pull-to-refresh",
+  "q",
+  "rdp_desktop_session",
+  "reader-mode-feedback",
+  "reader-mode-heuristics",
+  "rebaseline-pixel-tests",
+  "record-type",
+  "reduced-referrer-granularity",
+  "reduce-security-for-testing",
+  "register-font-files",
+  "register-pepper-plugins",
+  "relauncher",
+  "remote-debugging-address",
+  "remote-debugging-port",
+  "remote-debugging-socket-fd",
+  "remote-debugging-socket-name",
+  "remote-debugging-targets",
+  "renderer",
+  "renderer-client-id",
+  "renderer-cmd-prefix",
+  "renderer-process-limit",
+  "renderer-startup-dialog",
+  "renderer-wait-for-java-debugger",
+  "renderpass",
+  "repl",
+  "report-vp9-as-an-unsupported-mime-type",
+  "require-audio-hardware-for-testing",
+  "reset-app-list-install-state",
+  "reset-variation-state",
+  "restore-last-session",
+  "root",
+  "root-layer-scrolls",
+  "rtl",
+  "run-all-compositor-stages-before-draw",
+  "run-layout-test",
+  "runtime-deps-list-file",
+  "safebrowsing-disable-auto-update",
+  "safebrowsing-disable-download-protection",
+  "safebrowsing-disable-extension-blacklist",
+  "safebrowsing-manual-download-blacklist",
+  "SafeSites",
+  "sandbox-ipc",
+  "save-page-as-mhtml",
+  "screen-config",
+  "screenshot",
+  "script-executable",
+  "scripts-require-action",
+  "search-provider-logo-url",
+  "secondary",
+  "secondary-display-layout",
+  "secondary-ui-md",
+  "service",
+  "service-manager",
+  "service-name",
+  "service-pipe-token",
+  "service-request-channel-token",
+  "service-runner",
+  "shared-files",
+  "shill-stub",
+  "show-app-list",
+  "show-autofill-signatures",
+  "show-autofill-type-predictions",
+  "show-cert-link",
+  "show-component-extension-options",
+  "show-composited-layer-borders",
+  "show-fps-counter",
+  "show-icons",
+  "show-layer-animation-bounds",
+  "show-login-dev-overlay",
+  "show-mac-overlay-borders",
+  "show-md-login",
+  "show-non-md-login",
+  "show-overdraw-feedback",
+  "show-paint-rects",
+  "show-property-changed-rects",
+  "show-saved-copy",
+  "show-screenspace-rects",
+  "show-surface-damage-rects",
+  "silent-debugger-extension-api",
+  "silent-launch",
+  "simulate-critical-update",
+  "simulate-elevated-recovery",
+  "simulate-outdated",
+  "simulate-outdated-no-au",
+  "simulate-upgrade",
+  "single-process",
+  "site-per-process",
+  "skip-gpu-data-loading",
+  "skip-nostore-all",
+  "skip-nostore-main",
+  "skip-reencoding-on-skp-capture",
+  "slow",
+  "slow-connections-only",
+  "slow-down-compositing-scale-factor",
+  "slow-down-raster-scale-factor",
+  "sms-test-messages",
+  "spdy-proxy-auth-fallback",
+  "spdy-proxy-auth-origin",
+  "spdy-proxy-auth-value",
+  "spelling-service-feedback-interval-seconds",
+  "spelling-service-feedback-url",
+  "spurious-power-button-accel-count",
+  "spurious-power-button-keyboard-accel",
+  "spurious-power-button-lid-angle-change",
+  "spurious-power-button-screen-accel",
+  "spurious-power-button-window",
+  "ssl-key-log-file",
+  "ssl-version-max",
+  "ssl-version-min",
+  "stable-release-mode",
+  "started",
+  "start-fullscreen",
+  "start-maximized",
+  "start-stack-profiler",
+  "stub",
+  "stub-cros-settings",
+  "surface",
+  "swiftshader",
+  "swiftshader-webgl",
+  "sync-allow-insecure-xmpp-connection",
+  "sync-deferred-startup-timeout-seconds",
+  "sync-disable-deferred-startup",
+  "sync-enable-get-update-avoidance",
+  "sync-notification-host-port",
+  "sync-on-draw-hardware",
+  "sync-short-initial-retry-override",
+  "sync-short-nudge-delay-for-test",
+  "sync-url",
+  "system-developer-mode",
+  "system-log-upload-frequency",
+  "tab-management-experiment-type-disabled",
+  "tab-management-experiment-type-elderberry",
+  "task-manager-show-extra-renderers",
+  "task-profiler",
+  "team-drives",
+  "test-auto-update-ui",
+  "test-child-process",
+  "test-cros-gaia-id-migration",
+  "test-do-not-initialize-icu",
+  "test-encryption-migration-ui",
+  "test-gl-lib",
+  "testing-fixed-http-port",
+  "testing-fixed-https-port",
+  "test-launcher-batch-limit",
+  "test-launcher-bot-mode",
+  "test-launcher-debug-launcher",
+  "test-launcher-filter-file",
+  "test-launcher-force-run-broken-tests",
+  "test-launcher-jobs",
+  "test-launcher-list-tests",
+  "test-launcher-output",
+  "test-launcher-print-test-stdio",
+  "test-launcher-print-writable-path",
+  "test-launcher-retry-limit",
+  "test-launcher-shard-index",
+  "test-launcher-summary-output",
+  "test-launcher-test-part-results-limit",
+  "test-launcher-timeout",
+  "test-launcher-total-shards",
+  "test-launcher-trace",
+  "test-name",
+  "test-tiny-timeout",
+  "test-type",
+  "tether-stub",
+  "third-party-doodle-url",
+  "threads",
+  "time",
+  "timeout",
+  "tls1",
+  "tls1.1",
+  "tls1.2",
+  "tls1.3",
+  "tls13-variant",
+  "top-chrome-md",
+  "top-controls-hide-threshold",
+  "top-controls-show-threshold",
+  "touch-calibration",
+  "touch-devices",
+  "touch-events",
+  "touch-noise-filtering",
+  "touch-selection-strategy",
+  "touch_view",
+  "trace-config-file",
+  "trace-export-events-to-etw",
+  "tracelog",
+  "trace-shutdown",
+  "trace-shutdown-file",
+  "trace-startup",
+  "trace-startup-duration",
+  "trace-startup-file",
+  "trace-to-console",
+  "trace-to-file",
+  "trace-to-file-name",
+  "trace-upload-url",
+  "translate-ranker-model-url",
+  "translate-script-url",
+  "translate-security-origin",
+  "true",
+  "trusted-download-sources",
+  "try-chrome-again",
+  "try-supported-channel-layouts",
+  "type",
+  "ui-disable-partial-swap",
+  "ui-enable-layer-lists",
+  "ui-enable-rgba-4444-textures",
+  "ui-enable-zero-copy",
+  "ui-prioritize-in-gpu-process",
+  "ui-show-composited-layer-borders",
+  "ui-show-fps-counter",
+  "ui-show-layer-animation-bounds",
+  "ui-show-paint-rects",
+  "ui-show-property-changed-rects",
+  "ui-show-screenspace-rects",
+  "ui-show-surface-damage-rects",
+  "ui-slow-animations",
+  "ui-test-action-max-timeout",
+  "ui-test-action-timeout",
+  "uninstall",
+  "unlimited-storage",
+  "unsafely-allow-protected-media-identifier-for-domain",
+  "unsafely-treat-insecure-origin-as-secure",
+  "unsafe-pac-url",
+  "use-angle",
+  "use-cras",
+  "use-fake-device-for-media-stream",
+  "use-fake-jpeg-decode-accelerator",
+  "use-fake-ui-for-media-stream",
+  "use-file-for-fake-audio-capture",
+  "use-file-for-fake-video-capture",
+  "use-first-display-as-internal",
+  "use-gl",
+  "use-gpu-in-tests",
+  "use-ime-service",
+  "use-mobile-user-agent",
+  "use-mock-keychain",
+  "use-passthrough-cmd-decoder",
+  "user-agent",
+  "user-always-affiliated",
+  "user-data-dir",
+  "user-gesture-required",
+  "user-gesture-required-for-cross-origin",
+  "use-skia-renderer",
+  "use-system-default-printer",
+  "use-test-config",
+  "use-viz-hit-test",
+  "utility",
+  "utility-allowed-dir",
+  "utility-cmd-prefix",
+  "utility-run-elevated",
+  "utility-sandbox-type",
+  "utility-startup-dialog",
+  "v",
+  "v2-sandbox",
+  "v2-sandbox-enabled",
+  "v8-cache-options",
+  "v8-cache-strategies-for-cache-storage",
+  "validate-crx",
+  "validate-input-event-stream",
+  "variations-override-country",
+  "variations-server-url",
+  "version",
+  "video-image-texture-target",
+  "video-threads",
+  "video-underflow-threshold-ms",
+  "virtual-time-budget",
+  "vmodule",
+  "voice-interaction-supported-locales",
+  "wait-for-debugger",
+  "wait-for-debugger-children",
+  "wake-on-wifi-packet",
+  "wallet-service-use-sandbox",
+  "watcher",
+  "waveout-buffers",
+  "webapk-server-url",
+  "webrtc-stun-probe-trial",
+  "webview-enable-safebrowsing-support",
+  "webview-sandboxed-renderer",
+  "whitelisted-extension-id",
+  "window-position",
+  "windows10-custom-titlebar",
+  "window-size",
+  "window-workspace",
+  "winhttp-proxy-resolver",
+  "win-jumplist-action",
+  "wm-window-animations-disabled",
+  "yield-between-content-script-runs",
+  "zygote",
+  "zygote-cmd-prefix"
+};
+
+bool IsBlacklistedArg(const base::CommandLine::CharType* arg) {
+#if defined(OS_WIN)
+  const auto converted = base::WideToUTF8(arg);
+  const char* a = converted.c_str();
+#else
+  const char* a = arg;
+#endif
+
+  static const char* prefixes[] = {"--", "-", "/"};
+
+  int prefix_length = 0;
+  for (auto& prefix : prefixes) {
+    if (base::StartsWith(a, prefix, base::CompareCase::SENSITIVE)) {
+      prefix_length = strlen(prefix);
+      break;
+    }
+  }
+
+  if (prefix_length > 0) {
+    a += prefix_length;
+    std::string switch_name(a, strcspn(a, "="));
+    for (auto& item : blacklist) {
+      if (switch_name == item)
+        return true;
+    }
+  }
+
+  return false;
+}
+
+}  // namespace
+
+namespace atom {
+
+bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
+  const base::CommandLine::StringType dashdash(2, '-');
+  bool block_blacklisted_args = false;
+  for (int i = 0; i < argc; ++i) {
+    if (argv[i] == dashdash)
+      break;
+    if (block_blacklisted_args) {
+      if (IsBlacklistedArg(argv[i]))
+        return false;
+    } else if (IsUrlArg(argv[i])) {
+      block_blacklisted_args = true;
+    }
+  }
+  return true;
+}
+
+}  // namespace atom

+ 17 - 0
atom/app/command_line_args.h

@@ -0,0 +1,17 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_APP_COMMAND_LINE_ARGS_H_
+#define ATOM_APP_COMMAND_LINE_ARGS_H_
+
+#include "base/command_line.h"
+
+namespace atom {
+
+bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv);
+
+}  // namespace atom
+
+#endif  // ATOM_APP_COMMAND_LINE_ARGS_H_
+

+ 0 - 4
atom/browser/api/atom_api_app.cc

@@ -754,11 +754,7 @@ bool App::Relaunch(mate::Arguments* js_args) {
   }
 
   if (!override_argv) {
-#if defined(OS_WIN)
-    const relauncher::StringVector& argv = atom::AtomCommandLine::wargv();
-#else
     const relauncher::StringVector& argv = atom::AtomCommandLine::argv();
-#endif
     return relauncher::RelaunchApp(argv);
   }
 

+ 7 - 0
atom/browser/atom_browser_client.cc

@@ -22,6 +22,7 @@
 #include "atom/common/options_switches.h"
 #include "base/command_line.h"
 #include "base/files/file_util.h"
+#include "base/path_service.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -37,6 +38,7 @@
 #include "content/public/browser/resource_dispatcher_host.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_paths.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/web_preferences.h"
 #include "net/ssl/ssl_cert_request_info.h"
@@ -207,6 +209,11 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
 void AtomBrowserClient::AppendExtraCommandLineSwitches(
     base::CommandLine* command_line,
     int process_id) {
+  // Make sure we're about to launch a known executable
+  base::FilePath child_path;
+  PathService::Get(content::CHILD_PROCESS_EXE, &child_path);
+  CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path);
+
   std::string process_type = command_line->GetSwitchValueASCII("type");
   if (process_type != "renderer")
     return;

+ 0 - 4
atom/browser/relauncher.cc

@@ -140,11 +140,7 @@ bool RelaunchAppWithHelper(const base::FilePath& helper,
 }
 
 int RelauncherMain(const content::MainFunctionParams& main_parameters) {
-#if defined(OS_WIN)
-  const StringVector& argv = atom::AtomCommandLine::wargv();
-#else
   const StringVector& argv = atom::AtomCommandLine::argv();
-#endif
 
   if (argv.size() < 4 || argv[1] != internal::kRelauncherTypeArg) {
     LOG(ERROR) << "relauncher process invoked with unexpected arguments";

+ 9 - 18
atom/common/atom_command_line.cc

@@ -10,30 +10,21 @@
 namespace atom {
 
 // static
-std::vector<std::string> AtomCommandLine::argv_;
+base::CommandLine::StringVector AtomCommandLine::argv_;
 
-#if defined(OS_WIN)
 // static
-std::vector<std::wstring> AtomCommandLine::wargv_;
-#endif
+void AtomCommandLine::Init(int argc, base::CommandLine::CharType** argv) {
+  DCHECK(argv_.empty());
 
-// static
-void AtomCommandLine::Init(int argc, const char* const* argv) {
+  // NOTE: uv_setup_args does nothing on Windows, so we don't need to call it.
+  // Otherwise we'd have to convert the arguments from UTF16.
+#if !defined(OS_WIN)
   // Hack around with the argv pointer. Used for process.title = "blah"
-  char** new_argv = uv_setup_args(argc, const_cast<char**>(argv));
-  for (int i = 0; i < argc; ++i) {
-    argv_.push_back(new_argv[i]);
-  }
-}
+  argv = uv_setup_args(argc, argv);
+#endif
 
-#if defined(OS_WIN)
-// static
-void AtomCommandLine::InitW(int argc, const wchar_t* const* argv) {
-  for (int i = 0; i < argc; ++i) {
-    wargv_.push_back(argv[i]);
-  }
+  argv_.assign(argv, argv + argc);
 }
-#endif
 
 #if defined(OS_LINUX)
 // static

+ 4 - 11
atom/common/atom_command_line.h

@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "base/command_line.h"
 #include "base/macros.h"
 #include "build/build_config.h"
 
@@ -16,13 +17,9 @@ namespace atom {
 // Singleton to remember the original "argc" and "argv".
 class AtomCommandLine {
  public:
-  static void Init(int argc, const char* const* argv);
-  static std::vector<std::string> argv() { return argv_; }
+  static const base::CommandLine::StringVector& argv() { return argv_; }
 
-#if defined(OS_WIN)
-  static void InitW(int argc, const wchar_t* const* argv);
-  static std::vector<std::wstring> wargv() { return wargv_; }
-#endif
+  static void Init(int argc, base::CommandLine::CharType** argv);
 
 #if defined(OS_LINUX)
   // On Linux the command line has to be read from base::CommandLine since
@@ -31,11 +28,7 @@ class AtomCommandLine {
 #endif
 
  private:
-  static std::vector<std::string> argv_;
-
-#if defined(OS_WIN)
-  static std::vector<std::wstring> wargv_;
-#endif
+  static base::CommandLine::StringVector argv_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(AtomCommandLine);
 };

+ 10 - 2
atom/common/node_bindings.cc

@@ -4,6 +4,7 @@
 
 #include "atom/common/node_bindings.h"
 
+#include <algorithm>
 #include <string>
 #include <vector>
 
@@ -17,6 +18,7 @@
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 #include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/trace_event/trace_event.h"
 #include "content/public/browser/browser_thread.h"
@@ -149,7 +151,14 @@ void NodeBindings::Initialize() {
 
 node::Environment* NodeBindings::CreateEnvironment(
     v8::Handle<v8::Context> context) {
+#if defined(OS_WIN)
+  auto& atom_args = AtomCommandLine::argv();
+  std::vector<std::string> args(atom_args.size());
+  std::transform(atom_args.cbegin(), atom_args.cend(), args.begin(),
+                 [](auto& a) { return base::WideToUTF8(a); });
+#else
   auto args = AtomCommandLine::argv();
+#endif
 
   // Feed node the path to initialization script.
   base::FilePath::StringType process_type;
@@ -169,8 +178,7 @@ node::Environment* NodeBindings::CreateEnvironment(
       resources_path.Append(FILE_PATH_LITERAL("electron.asar"))
                     .Append(process_type)
                     .Append(FILE_PATH_LITERAL("init.js"));
-  std::string script_path_str = script_path.AsUTF8Unsafe();
-  args.insert(args.begin() + 1, script_path_str.c_str());
+  args.insert(args.begin() + 1, script_path.AsUTF8Unsafe());
 
   std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
   node::Environment* env = node::CreateEnvironment(

+ 2 - 0
filenames.gypi

@@ -97,6 +97,8 @@
       'atom/app/atom_main_delegate.cc',
       'atom/app/atom_main_delegate.h',
       'atom/app/atom_main_delegate_mac.mm',
+      'atom/app/command_line_args.cc',
+      'atom/app/command_line_args.h',
       'atom/app/node_main.cc',
       'atom/app/node_main.h',
       'atom/app/uv_task_runner.cc',

+ 48 - 0
spec/api-app-spec.js

@@ -469,6 +469,54 @@ describe('app module', function () {
     })
   })
 
+  describe('app launch through uri', () => {
+    before(function () {
+      if (process.platform !== 'win32') {
+        this.skip()
+      }
+    })
+
+    it('does not launch for blacklisted argument', function (done) {
+      const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
+      // App should exit with non 123 code.
+      const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher=cmd.exe /c start calc'])
+      first.once('exit', (code) => {
+        assert.notEqual(code, 123)
+        done()
+      })
+    })
+
+    it('launches successfully for multiple uris in cmd args', function (done) {
+      const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
+      // App should exit with code 123.
+      const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'http://electronjs.org', 'electron-test://testdata'])
+      first.once('exit', (code) => {
+        assert.equal(code, 123)
+        done()
+      })
+    })
+
+    it('does not launch for encoded space', function (done) {
+      const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
+      // App should exit with non 123 code.
+      const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher%20"cmd.exe /c start calc'])
+      first.once('exit', (code) => {
+        assert.notEqual(code, 123)
+        done()
+      })
+    })
+
+    it('launches successfully for argnames similar to blacklisted ones', function (done) {
+      const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
+      // inspect is blacklisted, but inspector should work, and app launch should succeed
+      const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--inspector'])
+      first.once('exit', (code) => {
+        assert.equal(code, 123)
+        done()
+      })
+    })
+  })
+
   describe('getFileIcon() API', function () {
     // FIXME Get these specs running on Linux CI
     if (process.platform === 'linux' && isCI) return