bool IDNSpoofChecker::SafeToDisplayAsUnicode(base::StringPiece16 label,
                                             bool is_tld_ascii) {
  UErrorCode status = U_ZERO_ERROR;
  int32_t result =
      uspoof_check(checker_, label.data(),
                   base::checked_cast<int32_t>(label.size()), NULL, &status);
  if (U_FAILURE(status) || (result & USPOOF_ALL_CHECKS))
    return false;

  icu::UnicodeString label_string(FALSE, label.data(),
                                  base::checked_cast<int32_t>(label.size()));

  if (deviation_characters_.containsSome(label_string))
    return false;

  result &= USPOOF_RESTRICTION_LEVEL_MASK;
  if (result == USPOOF_ASCII)
    return true;
  if (result == USPOOF_SINGLE_SCRIPT_RESTRICTIVE &&
      kana_letters_exceptions_.containsNone(label_string) &&
      combining_diacritics_exceptions_.containsNone(label_string)) {
    return !is_tld_ascii || !IsMadeOfLatinAlikeCyrillic(label_string);
  }

  if (non_ascii_latin_letters_.containsSome(label_string) &&
      !lgc_letters_n_ascii_.containsAll(label_string))
    return false;

  if (!tls_index.initialized())
    tls_index.Initialize(&OnThreadTermination);
  icu::RegexMatcher* dangerous_pattern =
      reinterpret_cast<icu::RegexMatcher*>(tls_index.Get());
  if (!dangerous_pattern) {
     dangerous_pattern = new icu::RegexMatcher(
         icu::UnicodeString(
             R"([^\p{scx=kana}\p{scx=hira}\p{scx=hani}])"
            R"([\u30ce\u30f3\u30bd\u30be])"
            R"([^\p{scx=kana}\p{scx=hira}\p{scx=hani}]|)"
            R"([^\p{scx=kana}\p{scx=hira}]\u30fc|^\u30fc|)"
            R"([^\p{scx=kana}][\u30fd\u30fe]|^[\u30fd\u30fe]|)"
            R"(^[\p{scx=kana}]+[\u3078-\u307a][\p{scx=kana}]+$|)"
            R"(^[\p{scx=hira}]+[\u30d8-\u30da][\p{scx=hira}]+$|)"
            R"([a-z]\u30fb|\u30fb[a-z]|)"
            R"(^[\u0585\u0581]+[a-z]|[a-z][\u0585\u0581]+$|)"
            R"([a-z][\u0585\u0581]+[a-z]|)"
            R"(^[og]+[\p{scx=armn}]|[\p{scx=armn}][og]+$|)"
            R"([\p{scx=armn}][og]+[\p{scx=armn}]|)"
            R"([\p{sc=cans}].*[a-z]|[a-z].*[\p{sc=cans}]|)"
             R"([\p{sc=tfng}].*[a-z]|[a-z].*[\p{sc=tfng}]|)"
             R"([^\p{scx=latn}\p{scx=grek}\p{scx=cyrl}][\u0300-\u0339]|)"
             R"([^\p{scx=arab}][\u064b-\u0655\u0670]|)"
            R"([^\p{scx=hebr}]\u05b4)",
             -1, US_INV),
         0, status);
     tls_index.Set(dangerous_pattern);
  }
  dangerous_pattern->reset(label_string);
  return !dangerous_pattern->find();
}

Insufficient Policy Enforcement in Omnibox in Google Chrome prior to 62.0.3202.62 allowed a remote attacker to perform domain spoofing via IDN homographs in a crafted domain name.


bool IDNSpoofChecker::SafeToDisplayAsUnicode(base::StringPiece16 label,
                                             bool is_tld_ascii) {
  UErrorCode status = U_ZERO_ERROR;
  int32_t result =
      uspoof_check(checker_, label.data(),
                   base::checked_cast<int32_t>(label.size()), NULL, &status);
  if (U_FAILURE(status) || (result & USPOOF_ALL_CHECKS))
    return false;

  icu::UnicodeString label_string(FALSE, label.data(),
                                  base::checked_cast<int32_t>(label.size()));

  if (deviation_characters_.containsSome(label_string))
    return false;

  result &= USPOOF_RESTRICTION_LEVEL_MASK;
  if (result == USPOOF_ASCII)
    return true;
  if (result == USPOOF_SINGLE_SCRIPT_RESTRICTIVE &&
      kana_letters_exceptions_.containsNone(label_string) &&
      combining_diacritics_exceptions_.containsNone(label_string)) {
    return !is_tld_ascii || !IsMadeOfLatinAlikeCyrillic(label_string);
  }

  if (non_ascii_latin_letters_.containsSome(label_string) &&
      !lgc_letters_n_ascii_.containsAll(label_string))
    return false;

  if (!tls_index.initialized())
    tls_index.Initialize(&OnThreadTermination);
  icu::RegexMatcher* dangerous_pattern =
      reinterpret_cast<icu::RegexMatcher*>(tls_index.Get());
  if (!dangerous_pattern) {
    // - Disallow U+0307 (dot above) after 'i', 'j', 'l' or dotless i (U+0131).
    //   Dotless j (U+0237) is not in the allowed set to begin with.
     dangerous_pattern = new icu::RegexMatcher(
         icu::UnicodeString(
             R"([^\p{scx=kana}\p{scx=hira}\p{scx=hani}])"
            R"([\u30ce\u30f3\u30bd\u30be])"
            R"([^\p{scx=kana}\p{scx=hira}\p{scx=hani}]|)"
            R"([^\p{scx=kana}\p{scx=hira}]\u30fc|^\u30fc|)"
            R"([^\p{scx=kana}][\u30fd\u30fe]|^[\u30fd\u30fe]|)"
            R"(^[\p{scx=kana}]+[\u3078-\u307a][\p{scx=kana}]+$|)"
            R"(^[\p{scx=hira}]+[\u30d8-\u30da][\p{scx=hira}]+$|)"
            R"([a-z]\u30fb|\u30fb[a-z]|)"
            R"(^[\u0585\u0581]+[a-z]|[a-z][\u0585\u0581]+$|)"
            R"([a-z][\u0585\u0581]+[a-z]|)"
            R"(^[og]+[\p{scx=armn}]|[\p{scx=armn}][og]+$|)"
            R"([\p{scx=armn}][og]+[\p{scx=armn}]|)"
            R"([\p{sc=cans}].*[a-z]|[a-z].*[\p{sc=cans}]|)"
             R"([\p{sc=tfng}].*[a-z]|[a-z].*[\p{sc=tfng}]|)"
             R"([^\p{scx=latn}\p{scx=grek}\p{scx=cyrl}][\u0300-\u0339]|)"
             R"([^\p{scx=arab}][\u064b-\u0655\u0670]|)"
            R"([^\p{scx=hebr}]\u05b4|)"
            R"([ijl\u0131]\u0307)",
             -1, US_INV),
         0, status);
     tls_index.Set(dangerous_pattern);
  }
  dangerous_pattern->reset(label_string);
  return !dangerous_pattern->find();
}


WebContents* DevToolsWindow::OpenURLFromTab(
    WebContents* source,
    const content::OpenURLParams& params) {
   DCHECK(source == main_web_contents_);
   if (!params.url.SchemeIs(content::kChromeDevToolsScheme)) {
     WebContents* inspected_web_contents = GetInspectedWebContents();
    return inspected_web_contents ?
        inspected_web_contents->OpenURL(params) : NULL;
   }
   bindings_->Reload();
   return main_web_contents_;
}

Insufficient Policy Enforcement in Devtools remote debugging in Google Chrome prior to 62.0.3202.62 allowed a remote attacker to obtain access to remote debugging functionality via a crafted HTML page, aka a Referer leak.


WebContents* DevToolsWindow::OpenURLFromTab(
    WebContents* source,
    const content::OpenURLParams& params) {
   DCHECK(source == main_web_contents_);
   if (!params.url.SchemeIs(content::kChromeDevToolsScheme)) {
     WebContents* inspected_web_contents = GetInspectedWebContents();
    if (!inspected_web_contents)
      return nullptr;
    content::OpenURLParams modified = params;
    modified.referrer = content::Referrer();
    return inspected_web_contents->OpenURL(modified);
   }
   bindings_->Reload();
   return main_web_contents_;
}


std::set<std::string> GetDistinctHosts(const URLPatternSet& host_patterns,
                                       bool include_rcd,
                                       bool exclude_file_scheme) {
  typedef base::StringPairs HostVector;
  HostVector hosts_best_rcd;
  for (const URLPattern& pattern : host_patterns) {
    if (exclude_file_scheme && pattern.scheme() == url::kFileScheme)
       continue;

     std::string host = pattern.host();

     if (pattern.match_subdomains())
      host = "*." + host;

    std::string rcd;
    size_t reg_len =
        net::registry_controlled_domains::PermissiveGetHostRegistryLength(
            host, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
            net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
    if (reg_len && reg_len != std::string::npos) {
      if (include_rcd)  // else leave rcd empty
        rcd = host.substr(host.size() - reg_len);
      host = host.substr(0, host.size() - reg_len);
    }

    HostVector::iterator it = hosts_best_rcd.begin();
    for (; it != hosts_best_rcd.end(); ++it) {
      if (it->first == host)
        break;
    }
    if (it != hosts_best_rcd.end()) {
      if (include_rcd && RcdBetterThan(rcd, it->second))
        it->second = rcd;
    } else {  // Previously unseen host, append it.
      hosts_best_rcd.push_back(std::make_pair(host, rcd));
    }
  }

  std::set<std::string> distinct_hosts;
  for (const auto& host_rcd : hosts_best_rcd)
    distinct_hosts.insert(host_rcd.first + host_rcd.second);
  return distinct_hosts;
}

Insufficient Policy Enforcement in Extensions in Google Chrome prior to 62.0.3202.62 allowed a remote attacker to perform domain spoofing in permission dialogs via IDN homographs in a crafted Chrome Extension.


std::set<std::string> GetDistinctHosts(const URLPatternSet& host_patterns,
                                       bool include_rcd,
                                       bool exclude_file_scheme) {
  typedef base::StringPairs HostVector;
  HostVector hosts_best_rcd;
  for (const URLPattern& pattern : host_patterns) {
    if (exclude_file_scheme && pattern.scheme() == url::kFileScheme)
       continue;

     std::string host = pattern.host();
    if (!host.empty()) {
      // Convert the host into a secure format. For example, an IDN domain is
      // converted to punycode.
      host = base::UTF16ToUTF8(url_formatter::FormatUrlForSecurityDisplay(
          GURL(base::StringPrintf("%s%s%s", url::kHttpScheme,
                                  url::kStandardSchemeSeparator, host.c_str())),
          url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS));
    }

     if (pattern.match_subdomains())
      host = "*." + host;

    std::string rcd;
    size_t reg_len =
        net::registry_controlled_domains::PermissiveGetHostRegistryLength(
            host, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
            net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
    if (reg_len && reg_len != std::string::npos) {
      if (include_rcd)  // else leave rcd empty
        rcd = host.substr(host.size() - reg_len);
      host = host.substr(0, host.size() - reg_len);
    }

    HostVector::iterator it = hosts_best_rcd.begin();
    for (; it != hosts_best_rcd.end(); ++it) {
      if (it->first == host)
        break;
    }
    if (it != hosts_best_rcd.end()) {
      if (include_rcd && RcdBetterThan(rcd, it->second))
        it->second = rcd;
    } else {  // Previously unseen host, append it.
      hosts_best_rcd.push_back(std::make_pair(host, rcd));
    }
  }

  std::set<std::string> distinct_hosts;
  for (const auto& host_rcd : hosts_best_rcd)
    distinct_hosts.insert(host_rcd.first + host_rcd.second);
  return distinct_hosts;
}


 void ServiceWorkerPaymentInstrument::OnPaymentAppInvoked(
     mojom::PaymentHandlerResponsePtr response) {
  DCHECK(delegate_);
   if (delegate_ != nullptr) {
     delegate_->OnInstrumentDetailsReady(response->method_name,
                                         response->stringified_details);
    delegate_ = nullptr;
  }
}

Object lifecycle issue in ServiceWorker in Google Chrome prior to 75.0.3770.80 allowed a remote attacker to potentially perform out of bounds memory access via a crafted HTML page.


 void ServiceWorkerPaymentInstrument::OnPaymentAppInvoked(
     mojom::PaymentHandlerResponsePtr response) {
   if (delegate_ != nullptr) {
     delegate_->OnInstrumentDetailsReady(response->method_name,
                                         response->stringified_details);
    delegate_ = nullptr;
  }
}


ChildProcessTerminationInfo ChildProcessLauncherHelper::GetTerminationInfo(
    const ChildProcessLauncherHelper::Process& process,
    bool known_dead) {
  ChildProcessTerminationInfo info;
   if (!java_peer_avaiable_on_client_thread_)
     return info;

  Java_ChildProcessLauncherHelperImpl_getTerminationInfo(
       AttachCurrentThread(), java_peer_, reinterpret_cast<intptr_t>(&info));

   base::android::ApplicationState app_state =
      base::android::ApplicationStatusListener::GetState();
  bool app_foreground =
      app_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES ||
      app_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;

  if (app_foreground &&
      (info.binding_state == base::android::ChildBindingState::MODERATE ||
       info.binding_state == base::android::ChildBindingState::STRONG)) {
    info.status = base::TERMINATION_STATUS_OOM_PROTECTED;
  } else {
    info.status = base::TERMINATION_STATUS_NORMAL_TERMINATION;
  }
  return info;
}

Process lifetime issue in Chrome in Google Chrome on Android prior to 74.0.3729.108 allowed a remote attacker to potentially persist an exploited process via a crafted HTML page.


ChildProcessTerminationInfo ChildProcessLauncherHelper::GetTerminationInfo(
    const ChildProcessLauncherHelper::Process& process,
    bool known_dead) {
  ChildProcessTerminationInfo info;
   if (!java_peer_avaiable_on_client_thread_)
     return info;

  Java_ChildProcessLauncherHelperImpl_getTerminationInfoAndStop(
       AttachCurrentThread(), java_peer_, reinterpret_cast<intptr_t>(&info));

   base::android::ApplicationState app_state =
      base::android::ApplicationStatusListener::GetState();
  bool app_foreground =
      app_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES ||
      app_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;

  if (app_foreground &&
      (info.binding_state == base::android::ChildBindingState::MODERATE ||
       info.binding_state == base::android::ChildBindingState::STRONG)) {
    info.status = base::TERMINATION_STATUS_OOM_PROTECTED;
  } else {
    info.status = base::TERMINATION_STATUS_NORMAL_TERMINATION;
  }
  return info;
}


OperationID FileSystemOperationRunner::BeginOperation(
     std::unique_ptr<FileSystemOperation> operation) {
   OperationID id = next_operation_id_++;

  operations_.emplace(id, std::move(operation));
   return id;
 }

An integer overflow that leads to a use-after-free in Blink Storage in Google Chrome on Linux prior to 73.0.3683.75 allowed a remote attacker who had compromised the renderer process to execute arbitrary code via a crafted HTML page.


OperationID FileSystemOperationRunner::BeginOperation(
     std::unique_ptr<FileSystemOperation> operation) {
   OperationID id = next_operation_id_++;

  operations_[id] = std::move(operation);
   return id;
 }


UseCounterPageLoadMetricsObserver::GetAllowedUkmFeatures() {
  static base::NoDestructor<UseCounterPageLoadMetricsObserver::UkmFeatureList>
      opt_in_features(std::initializer_list<WebFeature>({
          WebFeature::kNavigatorVibrate,
          WebFeature::kNavigatorVibrateSubFrame,
          WebFeature::kTouchEventPreventedNoTouchAction,
          WebFeature::kTouchEventPreventedForcedDocumentPassiveNoTouchAction,
          WebFeature::kDataUriHasOctothorpe,
          WebFeature::kApplicationCacheManifestSelectInsecureOrigin,
          WebFeature::kApplicationCacheManifestSelectSecureOrigin,
          WebFeature::kMixedContentAudio,
          WebFeature::kMixedContentImage,
          WebFeature::kMixedContentVideo,
          WebFeature::kMixedContentPlugin,
          WebFeature::kOpenerNavigationWithoutGesture,
          WebFeature::kUsbRequestDevice,
          WebFeature::kXMLHttpRequestSynchronous,
          WebFeature::kPaymentHandler,
          WebFeature::kPaymentRequestShowWithoutGesture,
          WebFeature::kHTMLImports,
          WebFeature::kHTMLImportsHasStyleSheets,
          WebFeature::kElementCreateShadowRoot,
          WebFeature::kDocumentRegisterElement,
          WebFeature::kCredentialManagerCreatePublicKeyCredential,
          WebFeature::kCredentialManagerGetPublicKeyCredential,
          WebFeature::kCredentialManagerMakePublicKeyCredentialSuccess,
          WebFeature::kCredentialManagerGetPublicKeyCredentialSuccess,
          WebFeature::kV8AudioContext_Constructor,
          WebFeature::kElementAttachShadow,
          WebFeature::kElementAttachShadowOpen,
          WebFeature::kElementAttachShadowClosed,
          WebFeature::kCustomElementRegistryDefine,
          WebFeature::kTextToSpeech_Speak,
          WebFeature::kTextToSpeech_SpeakDisallowedByAutoplay,
          WebFeature::kCSSEnvironmentVariable,
          WebFeature::kCSSEnvironmentVariable_SafeAreaInsetTop,
          WebFeature::kCSSEnvironmentVariable_SafeAreaInsetLeft,
          WebFeature::kCSSEnvironmentVariable_SafeAreaInsetRight,
          WebFeature::kCSSEnvironmentVariable_SafeAreaInsetBottom,
          WebFeature::kMediaControlsDisplayCutoutGesture,
          WebFeature::kPolymerV1Detected,
          WebFeature::kPolymerV2Detected,
          WebFeature::kFullscreenSecureOrigin,
          WebFeature::kFullscreenInsecureOrigin,
          WebFeature::kPrefixedVideoEnterFullscreen,
          WebFeature::kPrefixedVideoExitFullscreen,
          WebFeature::kPrefixedVideoEnterFullScreen,
          WebFeature::kPrefixedVideoExitFullScreen,
          WebFeature::kDocumentLevelPassiveDefaultEventListenerPreventedWheel,
          WebFeature::kDocumentDomainBlockedCrossOriginAccess,
          WebFeature::kDocumentDomainEnabledCrossOriginAccess,
          WebFeature::kSuppressHistoryEntryWithoutUserGesture,
          WebFeature::kCursorImageGT32x32,
          WebFeature::kCursorImageLE32x32,
          WebFeature::kHistoryPushState,
          WebFeature::kHistoryReplaceState,
          WebFeature::kCursorImageGT64x64,
          WebFeature::kAdClick,
          WebFeature::kUpdateWithoutShippingOptionOnShippingAddressChange,
          WebFeature::kUpdateWithoutShippingOptionOnShippingOptionChange,
          WebFeature::kSignedExchangeInnerResponseInMainFrame,
          WebFeature::kSignedExchangeInnerResponseInSubFrame,
          WebFeature::kWebShareShare,
          WebFeature::kHTMLAnchorElementDownloadInSandboxWithUserGesture,
          WebFeature::kHTMLAnchorElementDownloadInSandboxWithoutUserGesture,
          WebFeature::kNavigationDownloadInSandboxWithUserGesture,
          WebFeature::kNavigationDownloadInSandboxWithoutUserGesture,
          WebFeature::kDownloadInAdFrameWithUserGesture,
           WebFeature::kDownloadInAdFrameWithoutUserGesture,
           WebFeature::kOpenWebDatabase,
           WebFeature::kV8MediaCapabilities_DecodingInfo_Method,
       }));
   return *opt_in_features;
 }

Incorrect handling of download origins in Navigation in Google Chrome prior to 73.0.3683.75 allowed a remote attacker to perform domain spoofing via a crafted HTML page.


UseCounterPageLoadMetricsObserver::GetAllowedUkmFeatures() {
  static base::NoDestructor<UseCounterPageLoadMetricsObserver::UkmFeatureList>
      opt_in_features(std::initializer_list<WebFeature>({
          WebFeature::kNavigatorVibrate,
          WebFeature::kNavigatorVibrateSubFrame,
          WebFeature::kTouchEventPreventedNoTouchAction,
          WebFeature::kTouchEventPreventedForcedDocumentPassiveNoTouchAction,
          WebFeature::kDataUriHasOctothorpe,
          WebFeature::kApplicationCacheManifestSelectInsecureOrigin,
          WebFeature::kApplicationCacheManifestSelectSecureOrigin,
          WebFeature::kMixedContentAudio,
          WebFeature::kMixedContentImage,
          WebFeature::kMixedContentVideo,
          WebFeature::kMixedContentPlugin,
          WebFeature::kOpenerNavigationWithoutGesture,
          WebFeature::kUsbRequestDevice,
          WebFeature::kXMLHttpRequestSynchronous,
          WebFeature::kPaymentHandler,
          WebFeature::kPaymentRequestShowWithoutGesture,
          WebFeature::kHTMLImports,
          WebFeature::kHTMLImportsHasStyleSheets,
          WebFeature::kElementCreateShadowRoot,
          WebFeature::kDocumentRegisterElement,
          WebFeature::kCredentialManagerCreatePublicKeyCredential,
          WebFeature::kCredentialManagerGetPublicKeyCredential,
          WebFeature::kCredentialManagerMakePublicKeyCredentialSuccess,
          WebFeature::kCredentialManagerGetPublicKeyCredentialSuccess,
          WebFeature::kV8AudioContext_Constructor,
          WebFeature::kElementAttachShadow,
          WebFeature::kElementAttachShadowOpen,
          WebFeature::kElementAttachShadowClosed,
          WebFeature::kCustomElementRegistryDefine,
          WebFeature::kTextToSpeech_Speak,
          WebFeature::kTextToSpeech_SpeakDisallowedByAutoplay,
          WebFeature::kCSSEnvironmentVariable,
          WebFeature::kCSSEnvironmentVariable_SafeAreaInsetTop,
          WebFeature::kCSSEnvironmentVariable_SafeAreaInsetLeft,
          WebFeature::kCSSEnvironmentVariable_SafeAreaInsetRight,
          WebFeature::kCSSEnvironmentVariable_SafeAreaInsetBottom,
          WebFeature::kMediaControlsDisplayCutoutGesture,
          WebFeature::kPolymerV1Detected,
          WebFeature::kPolymerV2Detected,
          WebFeature::kFullscreenSecureOrigin,
          WebFeature::kFullscreenInsecureOrigin,
          WebFeature::kPrefixedVideoEnterFullscreen,
          WebFeature::kPrefixedVideoExitFullscreen,
          WebFeature::kPrefixedVideoEnterFullScreen,
          WebFeature::kPrefixedVideoExitFullScreen,
          WebFeature::kDocumentLevelPassiveDefaultEventListenerPreventedWheel,
          WebFeature::kDocumentDomainBlockedCrossOriginAccess,
          WebFeature::kDocumentDomainEnabledCrossOriginAccess,
          WebFeature::kSuppressHistoryEntryWithoutUserGesture,
          WebFeature::kCursorImageGT32x32,
          WebFeature::kCursorImageLE32x32,
          WebFeature::kHistoryPushState,
          WebFeature::kHistoryReplaceState,
          WebFeature::kCursorImageGT64x64,
          WebFeature::kAdClick,
          WebFeature::kUpdateWithoutShippingOptionOnShippingAddressChange,
          WebFeature::kUpdateWithoutShippingOptionOnShippingOptionChange,
          WebFeature::kSignedExchangeInnerResponseInMainFrame,
          WebFeature::kSignedExchangeInnerResponseInSubFrame,
          WebFeature::kWebShareShare,
          WebFeature::kHTMLAnchorElementDownloadInSandboxWithUserGesture,
          WebFeature::kHTMLAnchorElementDownloadInSandboxWithoutUserGesture,
          WebFeature::kNavigationDownloadInSandboxWithUserGesture,
          WebFeature::kNavigationDownloadInSandboxWithoutUserGesture,
          WebFeature::kDownloadInAdFrameWithUserGesture,
           WebFeature::kDownloadInAdFrameWithoutUserGesture,
           WebFeature::kOpenWebDatabase,
           WebFeature::kV8MediaCapabilities_DecodingInfo_Method,
          WebFeature::kOpenerNavigationDownloadCrossOriginNoGesture,
       }));
   return *opt_in_features;
 }


void Location::SetLocation(const String& url,
                           LocalDOMWindow* current_window,
                           LocalDOMWindow* entered_window,
                           ExceptionState* exception_state,
                           SetLocationPolicy set_location_policy) {
  if (!IsAttached())
    return;

  if (!current_window->GetFrame())
    return;

  Document* entered_document = entered_window->document();
  if (!entered_document)
    return;

  KURL completed_url = entered_document->CompleteURL(url);
  if (completed_url.IsNull())
    return;

  if (!current_window->GetFrame()->CanNavigate(*dom_window_->GetFrame(),
                                               completed_url)) {
    if (exception_state) {
      exception_state->ThrowSecurityError(
          "The current window does not have permission to navigate the target "
          "frame to '" +
          url + "'.");
    }
    return;
  }
  if (exception_state && !completed_url.IsValid()) {
    exception_state->ThrowDOMException(DOMExceptionCode::kSyntaxError,
                                       "'" + url + "' is not a valid URL.");
    return;
  }

   if (dom_window_->IsInsecureScriptAccess(*current_window, completed_url))
     return;

   V8DOMActivityLogger* activity_logger =
       V8DOMActivityLogger::CurrentActivityLoggerIfIsolatedWorld();
   if (activity_logger) {
    Vector<String> argv;
    argv.push_back("LocalDOMWindow");
    argv.push_back("url");
    argv.push_back(entered_document->Url());
    argv.push_back(completed_url);
    activity_logger->LogEvent("blinkSetAttribute", argv.size(), argv.data());
  }
  WebFrameLoadType frame_load_type = WebFrameLoadType::kStandard;
  if (set_location_policy == SetLocationPolicy::kReplaceThisFrame)
    frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
  dom_window_->GetFrame()->ScheduleNavigation(*current_window->document(),
                                              completed_url, frame_load_type,
                                              UserGestureStatus::kNone);
}

Insufficient policy enforcement in Content Security Policy in Google Chrome prior to 73.0.3683.75 allowed a remote attacker to bypass content security policy via a crafted HTML page.


void Location::SetLocation(const String& url,
                           LocalDOMWindow* current_window,
                           LocalDOMWindow* entered_window,
                           ExceptionState* exception_state,
                           SetLocationPolicy set_location_policy) {
  if (!IsAttached())
    return;

  if (!current_window->GetFrame())
    return;

  Document* entered_document = entered_window->document();
  if (!entered_document)
    return;

  KURL completed_url = entered_document->CompleteURL(url);
  if (completed_url.IsNull())
    return;

  if (!current_window->GetFrame()->CanNavigate(*dom_window_->GetFrame(),
                                               completed_url)) {
    if (exception_state) {
      exception_state->ThrowSecurityError(
          "The current window does not have permission to navigate the target "
          "frame to '" +
          url + "'.");
    }
    return;
  }
  if (exception_state && !completed_url.IsValid()) {
    exception_state->ThrowDOMException(DOMExceptionCode::kSyntaxError,
                                       "'" + url + "' is not a valid URL.");
    return;
  }

   if (dom_window_->IsInsecureScriptAccess(*current_window, completed_url))
     return;

  // Check the source browsing context's CSP to fulfill the CSP check
  // requirement of https://html.spec.whatwg.org/#navigate for javascript URLs.
  // Although the spec states we should perform this check on task execution,
  // we do this prior to dispatch since the parent frame's CSP may be
  // inaccessible if the target frame is out of process.
  Document* current_document = current_window->document();
  if (current_document && completed_url.ProtocolIsJavaScript() &&
      !ContentSecurityPolicy::ShouldBypassMainWorld(current_document)) {
    String script_source = DecodeURLEscapeSequences(completed_url.GetString());
    if (!current_document->GetContentSecurityPolicy()->AllowJavaScriptURLs(
            nullptr, script_source, current_document->Url(), OrdinalNumber())) {
      return;
    }
  }

   V8DOMActivityLogger* activity_logger =
       V8DOMActivityLogger::CurrentActivityLoggerIfIsolatedWorld();
   if (activity_logger) {
    Vector<String> argv;
    argv.push_back("LocalDOMWindow");
    argv.push_back("url");
    argv.push_back(entered_document->Url());
    argv.push_back(completed_url);
    activity_logger->LogEvent("blinkSetAttribute", argv.size(), argv.data());
  }
  WebFrameLoadType frame_load_type = WebFrameLoadType::kStandard;
  if (set_location_policy == SetLocationPolicy::kReplaceThisFrame)
    frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
  dom_window_->GetFrame()->ScheduleNavigation(*current_window->document(),
                                              completed_url, frame_load_type,
                                              UserGestureStatus::kNone);
}


 std::wstring GetSwitchValueFromCommandLine(const std::wstring& command_line,
                                            const std::wstring& switch_name) {
   assert(!command_line.empty());
   assert(!switch_name.empty());

   std::vector<std::wstring> as_array = TokenizeCommandLineToArray(command_line);
   std::wstring switch_with_equal = L"--" + switch_name + L"=";
  for (size_t i = 1; i < as_array.size(); ++i) {
    const std::wstring& arg = as_array[i];
     if (arg.compare(0, switch_with_equal.size(), switch_with_equal) == 0)
       return arg.substr(switch_with_equal.size());
   }

  return std::wstring();
}

Incorrect command line processing in Chrome in Google Chrome prior to 73.0.3683.75 allowed a local attacker to perform domain spoofing via a crafted domain name.


 std::wstring GetSwitchValueFromCommandLine(const std::wstring& command_line,
                                            const std::wstring& switch_name) {
  static constexpr wchar_t kSwitchTerminator[] = L"--";
   assert(!command_line.empty());
   assert(!switch_name.empty());

   std::vector<std::wstring> as_array = TokenizeCommandLineToArray(command_line);
   std::wstring switch_with_equal = L"--" + switch_name + L"=";
  auto end = std::find(as_array.cbegin(), as_array.cend(), kSwitchTerminator);
  for (auto scan = as_array.cbegin(); scan != end; ++scan) {
    const std::wstring& arg = *scan;
     if (arg.compare(0, switch_with_equal.size(), switch_with_equal) == 0)
       return arg.substr(switch_with_equal.size());
   }

  return std::wstring();
}


DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() {
  DCHECK_EQ(read_type_, kReadAsArrayBuffer);
  if (array_buffer_result_)
    return array_buffer_result_;

   if (!raw_data_ || error_code_ != FileErrorCode::kOK)
     return nullptr;

  DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer());
  if (finished_loading_) {
    array_buffer_result_ = result;
    AdjustReportedMemoryUsageToV8(
        -1 * static_cast<int64_t>(raw_data_->ByteLength()));
    raw_data_.reset();
   }
  return result;
 }

Object lifetime issue in Blink in Google Chrome prior to 72.0.3626.121 allowed a remote attacker to potentially perform out of bounds memory access via a crafted HTML page.


DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() {
  DCHECK_EQ(read_type_, kReadAsArrayBuffer);
  if (array_buffer_result_)
    return array_buffer_result_;

   if (!raw_data_ || error_code_ != FileErrorCode::kOK)
     return nullptr;

  if (!finished_loading_) {
    return DOMArrayBuffer::Create(
        ArrayBuffer::Create(raw_data_->Data(), raw_data_->ByteLength()));
   }

  array_buffer_result_ = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer());
  AdjustReportedMemoryUsageToV8(-1 *
                                static_cast<int64_t>(raw_data_->ByteLength()));
  raw_data_.reset();
  return array_buffer_result_;
 }


void ConfigureQuicParams(base::StringPiece quic_trial_group,
                         const VariationParameters& quic_trial_params,
                         bool is_quic_force_disabled,
                         bool is_quic_force_enabled,
                         const std::string& quic_user_agent_id,
                         net::HttpNetworkSession::Params* params) {
  params->enable_quic =
      ShouldEnableQuic(quic_trial_group, quic_trial_params,
                       is_quic_force_disabled, is_quic_force_enabled);
  params->mark_quic_broken_when_network_blackholes =
      ShouldMarkQuicBrokenWhenNetworkBlackholes(quic_trial_params);

  params->enable_server_push_cancellation =
      ShouldEnableServerPushCancelation(quic_trial_params);

  params->retry_without_alt_svc_on_quic_errors =
      ShouldRetryWithoutAltSvcOnQuicErrors(quic_trial_params);

  params->support_ietf_format_quic_altsvc =
      ShouldSupportIetfFormatQuicAltSvc(quic_trial_params);

   if (params->enable_quic) {
     params->enable_quic_proxies_for_https_urls =
         ShouldEnableQuicProxiesForHttpsUrls(quic_trial_params);
    params->enable_quic_proxies_for_https_urls = false;
     params->quic_connection_options =
         GetQuicConnectionOptions(quic_trial_params);
     params->quic_client_connection_options =
        GetQuicClientConnectionOptions(quic_trial_params);
    params->quic_close_sessions_on_ip_change =
        ShouldQuicCloseSessionsOnIpChange(quic_trial_params);
    params->quic_goaway_sessions_on_ip_change =
        ShouldQuicGoAwaySessionsOnIpChange(quic_trial_params);
    int idle_connection_timeout_seconds =
        GetQuicIdleConnectionTimeoutSeconds(quic_trial_params);
    if (idle_connection_timeout_seconds != 0) {
      params->quic_idle_connection_timeout_seconds =
          idle_connection_timeout_seconds;
    }
    int reduced_ping_timeout_seconds =
        GetQuicReducedPingTimeoutSeconds(quic_trial_params);
    if (reduced_ping_timeout_seconds > 0 &&
        reduced_ping_timeout_seconds < quic::kPingTimeoutSecs) {
      params->quic_reduced_ping_timeout_seconds = reduced_ping_timeout_seconds;
    }
    int max_time_before_crypto_handshake_seconds =
        GetQuicMaxTimeBeforeCryptoHandshakeSeconds(quic_trial_params);
    if (max_time_before_crypto_handshake_seconds > 0) {
      params->quic_max_time_before_crypto_handshake_seconds =
          max_time_before_crypto_handshake_seconds;
    }
    int max_idle_time_before_crypto_handshake_seconds =
        GetQuicMaxIdleTimeBeforeCryptoHandshakeSeconds(quic_trial_params);
    if (max_idle_time_before_crypto_handshake_seconds > 0) {
      params->quic_max_idle_time_before_crypto_handshake_seconds =
          max_idle_time_before_crypto_handshake_seconds;
    }
    params->quic_race_cert_verification =
        ShouldQuicRaceCertVerification(quic_trial_params);
    params->quic_estimate_initial_rtt =
        ShouldQuicEstimateInitialRtt(quic_trial_params);
    params->quic_headers_include_h2_stream_dependency =
        ShouldQuicHeadersIncludeH2StreamDependencies(quic_trial_params);
    params->quic_migrate_sessions_on_network_change_v2 =
        ShouldQuicMigrateSessionsOnNetworkChangeV2(quic_trial_params);
    params->quic_migrate_sessions_early_v2 =
        ShouldQuicMigrateSessionsEarlyV2(quic_trial_params);
    params->quic_retry_on_alternate_network_before_handshake =
        ShouldQuicRetryOnAlternateNetworkBeforeHandshake(quic_trial_params);
    params->quic_go_away_on_path_degrading =
        ShouldQuicGoawayOnPathDegrading(quic_trial_params);
    params->quic_race_stale_dns_on_connection =
        ShouldQuicRaceStaleDNSOnConnection(quic_trial_params);
    int max_time_on_non_default_network_seconds =
        GetQuicMaxTimeOnNonDefaultNetworkSeconds(quic_trial_params);
    if (max_time_on_non_default_network_seconds > 0) {
      params->quic_max_time_on_non_default_network =
          base::TimeDelta::FromSeconds(max_time_on_non_default_network_seconds);
    }
    int max_migrations_to_non_default_network_on_write_error =
        GetQuicMaxNumMigrationsToNonDefaultNetworkOnWriteError(
            quic_trial_params);
    if (max_migrations_to_non_default_network_on_write_error > 0) {
      params->quic_max_migrations_to_non_default_network_on_write_error =
          max_migrations_to_non_default_network_on_write_error;
    }
    int max_migrations_to_non_default_network_on_path_degrading =
        GetQuicMaxNumMigrationsToNonDefaultNetworkOnPathDegrading(
            quic_trial_params);
    if (max_migrations_to_non_default_network_on_path_degrading > 0) {
      params->quic_max_migrations_to_non_default_network_on_path_degrading =
          max_migrations_to_non_default_network_on_path_degrading;
    }
    params->quic_allow_server_migration =
        ShouldQuicAllowServerMigration(quic_trial_params);
    params->quic_host_whitelist = GetQuicHostWhitelist(quic_trial_params);
  }

  size_t max_packet_length = GetQuicMaxPacketLength(quic_trial_params);
  if (max_packet_length != 0) {
    params->quic_max_packet_length = max_packet_length;
  }

  params->quic_user_agent_id = quic_user_agent_id;

  quic::QuicTransportVersionVector supported_versions =
      GetQuicVersions(quic_trial_params);
  if (!supported_versions.empty())
    params->quic_supported_versions = supported_versions;
}

Implementation error in QUIC Networking in Google Chrome prior to 72.0.3626.81 allowed an attacker running or able to cause use of a proxy server to obtain cleartext of transport encryption via malicious network proxy.


void ConfigureQuicParams(base::StringPiece quic_trial_group,
                         const VariationParameters& quic_trial_params,
                         bool is_quic_force_disabled,
                         bool is_quic_force_enabled,
                         const std::string& quic_user_agent_id,
                         net::HttpNetworkSession::Params* params) {
  params->enable_quic =
      ShouldEnableQuic(quic_trial_group, quic_trial_params,
                       is_quic_force_disabled, is_quic_force_enabled);
  params->mark_quic_broken_when_network_blackholes =
      ShouldMarkQuicBrokenWhenNetworkBlackholes(quic_trial_params);

  params->enable_server_push_cancellation =
      ShouldEnableServerPushCancelation(quic_trial_params);

  params->retry_without_alt_svc_on_quic_errors =
      ShouldRetryWithoutAltSvcOnQuicErrors(quic_trial_params);

  params->support_ietf_format_quic_altsvc =
      ShouldSupportIetfFormatQuicAltSvc(quic_trial_params);

   if (params->enable_quic) {
     params->enable_quic_proxies_for_https_urls =
         ShouldEnableQuicProxiesForHttpsUrls(quic_trial_params);
     params->quic_connection_options =
         GetQuicConnectionOptions(quic_trial_params);
     params->quic_client_connection_options =
        GetQuicClientConnectionOptions(quic_trial_params);
    params->quic_close_sessions_on_ip_change =
        ShouldQuicCloseSessionsOnIpChange(quic_trial_params);
    params->quic_goaway_sessions_on_ip_change =
        ShouldQuicGoAwaySessionsOnIpChange(quic_trial_params);
    int idle_connection_timeout_seconds =
        GetQuicIdleConnectionTimeoutSeconds(quic_trial_params);
    if (idle_connection_timeout_seconds != 0) {
      params->quic_idle_connection_timeout_seconds =
          idle_connection_timeout_seconds;
    }
    int reduced_ping_timeout_seconds =
        GetQuicReducedPingTimeoutSeconds(quic_trial_params);
    if (reduced_ping_timeout_seconds > 0 &&
        reduced_ping_timeout_seconds < quic::kPingTimeoutSecs) {
      params->quic_reduced_ping_timeout_seconds = reduced_ping_timeout_seconds;
    }
    int max_time_before_crypto_handshake_seconds =
        GetQuicMaxTimeBeforeCryptoHandshakeSeconds(quic_trial_params);
    if (max_time_before_crypto_handshake_seconds > 0) {
      params->quic_max_time_before_crypto_handshake_seconds =
          max_time_before_crypto_handshake_seconds;
    }
    int max_idle_time_before_crypto_handshake_seconds =
        GetQuicMaxIdleTimeBeforeCryptoHandshakeSeconds(quic_trial_params);
    if (max_idle_time_before_crypto_handshake_seconds > 0) {
      params->quic_max_idle_time_before_crypto_handshake_seconds =
          max_idle_time_before_crypto_handshake_seconds;
    }
    params->quic_race_cert_verification =
        ShouldQuicRaceCertVerification(quic_trial_params);
    params->quic_estimate_initial_rtt =
        ShouldQuicEstimateInitialRtt(quic_trial_params);
    params->quic_headers_include_h2_stream_dependency =
        ShouldQuicHeadersIncludeH2StreamDependencies(quic_trial_params);
    params->quic_migrate_sessions_on_network_change_v2 =
        ShouldQuicMigrateSessionsOnNetworkChangeV2(quic_trial_params);
    params->quic_migrate_sessions_early_v2 =
        ShouldQuicMigrateSessionsEarlyV2(quic_trial_params);
    params->quic_retry_on_alternate_network_before_handshake =
        ShouldQuicRetryOnAlternateNetworkBeforeHandshake(quic_trial_params);
    params->quic_go_away_on_path_degrading =
        ShouldQuicGoawayOnPathDegrading(quic_trial_params);
    params->quic_race_stale_dns_on_connection =
        ShouldQuicRaceStaleDNSOnConnection(quic_trial_params);
    int max_time_on_non_default_network_seconds =
        GetQuicMaxTimeOnNonDefaultNetworkSeconds(quic_trial_params);
    if (max_time_on_non_default_network_seconds > 0) {
      params->quic_max_time_on_non_default_network =
          base::TimeDelta::FromSeconds(max_time_on_non_default_network_seconds);
    }
    int max_migrations_to_non_default_network_on_write_error =
        GetQuicMaxNumMigrationsToNonDefaultNetworkOnWriteError(
            quic_trial_params);
    if (max_migrations_to_non_default_network_on_write_error > 0) {
      params->quic_max_migrations_to_non_default_network_on_write_error =
          max_migrations_to_non_default_network_on_write_error;
    }
    int max_migrations_to_non_default_network_on_path_degrading =
        GetQuicMaxNumMigrationsToNonDefaultNetworkOnPathDegrading(
            quic_trial_params);
    if (max_migrations_to_non_default_network_on_path_degrading > 0) {
      params->quic_max_migrations_to_non_default_network_on_path_degrading =
          max_migrations_to_non_default_network_on_path_degrading;
    }
    params->quic_allow_server_migration =
        ShouldQuicAllowServerMigration(quic_trial_params);
    params->quic_host_whitelist = GetQuicHostWhitelist(quic_trial_params);
  }

  size_t max_packet_length = GetQuicMaxPacketLength(quic_trial_params);
  if (max_packet_length != 0) {
    params->quic_max_packet_length = max_packet_length;
  }

  params->quic_user_agent_id = quic_user_agent_id;

  quic::QuicTransportVersionVector supported_versions =
      GetQuicVersions(quic_trial_params);
  if (!supported_versions.empty())
    params->quic_supported_versions = supported_versions;
}


 bool SVGElement::HasSVGParent() const {
  return ParentOrShadowHostElement() &&
         ParentOrShadowHostElement()->IsSVGElement();
 }

An incorrect object type assumption in SVG in Google Chrome prior to 72.0.3626.81 allowed a remote attacker to potentially exploit object corruption via a crafted HTML page.


 bool SVGElement::HasSVGParent() const {
  Element* parent = FlatTreeTraversal::ParentElement(*this);
  return parent && parent->IsSVGElement();
 }


void FileSystemManagerImpl::CreateWriter(const GURL& file_path,
                                          CreateWriterCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);

   FileSystemURL url(context_->CrackURL(file_path));
   base::Optional<base::File::Error> opt_error = ValidateFileSystemURL(url);
   if (opt_error) {
    std::move(callback).Run(opt_error.value(), nullptr);
    return;
  }
  if (!security_policy_->CanWriteFileSystemFile(process_id_, url)) {
    std::move(callback).Run(base::File::FILE_ERROR_SECURITY, nullptr);
    return;
  }

  blink::mojom::FileWriterPtr writer;
  mojo::MakeStrongBinding(std::make_unique<storage::FileWriterImpl>(
                              url, context_->CreateFileSystemOperationRunner(),
                              blob_storage_context_->context()->AsWeakPtr()),
                          MakeRequest(&writer));
  std::move(callback).Run(base::File::FILE_OK, std::move(writer));
}

Incorrect handling of negative zero in V8 in Google Chrome prior to 72.0.3626.81 allowed a remote attacker to perform arbitrary read/write via a crafted HTML page.


void FileSystemManagerImpl::CreateWriter(const GURL& file_path,
                                          CreateWriterCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);

  if (!base::FeatureList::IsEnabled(blink::features::kWritableFilesAPI)) {
    bindings_.ReportBadMessage("FileSystemManager.CreateWriter");
    return;
  }

   FileSystemURL url(context_->CrackURL(file_path));
   base::Optional<base::File::Error> opt_error = ValidateFileSystemURL(url);
   if (opt_error) {
    std::move(callback).Run(opt_error.value(), nullptr);
    return;
  }
  if (!security_policy_->CanWriteFileSystemFile(process_id_, url)) {
    std::move(callback).Run(base::File::FILE_ERROR_SECURITY, nullptr);
    return;
  }

  blink::mojom::FileWriterPtr writer;
  mojo::MakeStrongBinding(std::make_unique<storage::FileWriterImpl>(
                              url, context_->CreateFileSystemOperationRunner(),
                              blob_storage_context_->context()->AsWeakPtr()),
                          MakeRequest(&writer));
  std::move(callback).Run(base::File::FILE_OK, std::move(writer));
}


bool SetExtendedFileAttribute(const char* path,
                              const char* name,
                               const char* value,
                               size_t value_size,
                               int flags) {
//// On Chrome OS, there is no component that can validate these extended
//// attributes so there is no need to set them.
   base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
   int result = setxattr(path, name, value, value_size, flags);
   if (result) {
     DPLOG(ERROR) << "Could not set extended attribute " << name << " on file "
                  << path;
     return false;
   }
   return true;
 }

Use of extended attributes in downloads in Google Chrome prior to 72.0.3626.81 allowed a local attacker to read download URLs via the filesystem.


bool SetExtendedFileAttribute(const char* path,
                              const char* name,
                               const char* value,
                               size_t value_size,
                               int flags) {
//// On Chrome OS, there is no component that can validate these extended
//// attributes so there is no need to set them.
#if !defined(OS_CHROMEOS)
   base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
   int result = setxattr(path, name, value, value_size, flags);
   if (result) {
     DPLOG(ERROR) << "Could not set extended attribute " << name << " on file "
                  << path;
     return false;
   }
#endif  // !defined(OS_CHROMEOS)
   return true;
 }


bool Performance::PassesTimingAllowCheck(
    const ResourceResponse& response,
     const SecurityOrigin& initiator_security_origin,
     const AtomicString& original_timing_allow_origin,
     ExecutionContext* context) {
   scoped_refptr<const SecurityOrigin> resource_origin =
      SecurityOrigin::Create(response.Url());
   if (resource_origin->IsSameSchemeHostPort(&initiator_security_origin))
     return true;

  const AtomicString& timing_allow_origin_string =
      original_timing_allow_origin.IsEmpty()
          ? response.HttpHeaderField(HTTPNames::Timing_Allow_Origin)
          : original_timing_allow_origin;
  if (timing_allow_origin_string.IsEmpty() ||
      EqualIgnoringASCIICase(timing_allow_origin_string, "null"))
    return false;

  if (timing_allow_origin_string == "*") {
    UseCounter::Count(context, WebFeature::kStarInTimingAllowOrigin);
    return true;
  }

  const String& security_origin = initiator_security_origin.ToString();
  Vector<String> timing_allow_origins;
  timing_allow_origin_string.GetString().Split(',', timing_allow_origins);
  if (timing_allow_origins.size() > 1) {
    UseCounter::Count(context, WebFeature::kMultipleOriginsInTimingAllowOrigin);
  } else if (timing_allow_origins.size() == 1 &&
             timing_allow_origin_string != "*") {
    UseCounter::Count(context, WebFeature::kSingleOriginInTimingAllowOrigin);
  }
  for (const String& allow_origin : timing_allow_origins) {
    const String allow_origin_stripped = allow_origin.StripWhiteSpace();
    if (allow_origin_stripped == security_origin ||
        allow_origin_stripped == "*") {
      return true;
    }
  }

  return false;
}

Insufficient policy enforcement in ServiceWorker in Google Chrome prior to 68.0.3440.75 allowed a remote attacker to obtain potentially sensitive information from process memory via a crafted HTML page.


bool Performance::PassesTimingAllowCheck(
    const ResourceResponse& response,
     const SecurityOrigin& initiator_security_origin,
     const AtomicString& original_timing_allow_origin,
     ExecutionContext* context) {
  const KURL& response_url = response.WasFetchedViaServiceWorker()
                                 ? response.OriginalURLViaServiceWorker()
                                 : response.Url();
   scoped_refptr<const SecurityOrigin> resource_origin =
      SecurityOrigin::Create(response_url);
   if (resource_origin->IsSameSchemeHostPort(&initiator_security_origin))
     return true;

  const AtomicString& timing_allow_origin_string =
      original_timing_allow_origin.IsEmpty()
          ? response.HttpHeaderField(HTTPNames::Timing_Allow_Origin)
          : original_timing_allow_origin;
  if (timing_allow_origin_string.IsEmpty() ||
      EqualIgnoringASCIICase(timing_allow_origin_string, "null"))
    return false;

  if (timing_allow_origin_string == "*") {
    UseCounter::Count(context, WebFeature::kStarInTimingAllowOrigin);
    return true;
  }

  const String& security_origin = initiator_security_origin.ToString();
  Vector<String> timing_allow_origins;
  timing_allow_origin_string.GetString().Split(',', timing_allow_origins);
  if (timing_allow_origins.size() > 1) {
    UseCounter::Count(context, WebFeature::kMultipleOriginsInTimingAllowOrigin);
  } else if (timing_allow_origins.size() == 1 &&
             timing_allow_origin_string != "*") {
    UseCounter::Count(context, WebFeature::kSingleOriginInTimingAllowOrigin);
  }
  for (const String& allow_origin : timing_allow_origins) {
    const String allow_origin_stripped = allow_origin.StripWhiteSpace();
    if (allow_origin_stripped == security_origin ||
        allow_origin_stripped == "*") {
      return true;
    }
  }

  return false;
}


ExtensionInstallDialogView::ExtensionInstallDialogView(
    Profile* profile,
    content::PageNavigator* navigator,
    const ExtensionInstallPrompt::DoneCallback& done_callback,
    std::unique_ptr<ExtensionInstallPrompt::Prompt> prompt)
    : profile_(profile),
      navigator_(navigator),
      done_callback_(done_callback),
       prompt_(std::move(prompt)),
       container_(NULL),
       scroll_view_(NULL),
      handled_result_(false) {
   InitView();
 }

Lack of timeout on extension install prompt in Extensions in Google Chrome prior to 68.0.3440.75 allowed a remote attacker to trigger installation of an unwanted extension via a crafted HTML page.


ExtensionInstallDialogView::ExtensionInstallDialogView(
    Profile* profile,
    content::PageNavigator* navigator,
    const ExtensionInstallPrompt::DoneCallback& done_callback,
    std::unique_ptr<ExtensionInstallPrompt::Prompt> prompt)
    : profile_(profile),
      navigator_(navigator),
      done_callback_(done_callback),
       prompt_(std::move(prompt)),
       container_(NULL),
       scroll_view_(NULL),
      handled_result_(false),
      install_button_enabled_(false) {
   InitView();
 }


 ExtensionFunction::ResponseAction BluetoothSocketSendFunction::Run() {
   DCHECK_CURRENTLY_ON(work_thread_id());

  auto params = bluetooth_socket::Send::Params::Create(*args_);
  EXTENSION_FUNCTION_VALIDATE(params.get());

  io_buffer_size_ = params->data.size();
  io_buffer_ = new net::WrappedIOBuffer(params->data.data());

  BluetoothApiSocket* socket = GetSocket(params->socket_id);
   if (!socket)
     return RespondNow(Error(kSocketNotFoundError));

  socket->Send(io_buffer_,
               io_buffer_size_,
               base::Bind(&BluetoothSocketSendFunction::OnSuccess, this),
               base::Bind(&BluetoothSocketSendFunction::OnError, this));
  return did_respond() ? AlreadyResponded() : RespondLater();
}

Use after free in Bluetooth in Google Chrome prior to 68.0.3440.75 allowed an attacker who convinced a user to install a malicious extension to obtain potentially sensitive information from process memory via a crafted Chrome Extension.


 ExtensionFunction::ResponseAction BluetoothSocketSendFunction::Run() {
   DCHECK_CURRENTLY_ON(work_thread_id());

  params_ = bluetooth_socket::Send::Params::Create(*args_);
  EXTENSION_FUNCTION_VALIDATE(params_.get());

  io_buffer_size_ = params_->data.size();
  io_buffer_ = new net::WrappedIOBuffer(params_->data.data());

  BluetoothApiSocket* socket = GetSocket(params_->socket_id);
   if (!socket)
     return RespondNow(Error(kSocketNotFoundError));

  socket->Send(io_buffer_,
               io_buffer_size_,
               base::Bind(&BluetoothSocketSendFunction::OnSuccess, this),
               base::Bind(&BluetoothSocketSendFunction::OnError, this));
  return did_respond() ? AlreadyResponded() : RespondLater();
}


ConfirmInfoBar::ConfirmInfoBar(std::unique_ptr<ConfirmInfoBarDelegate> delegate)
     : InfoBarView(std::move(delegate)) {
   auto* delegate_ptr = GetDelegate();
   label_ = CreateLabel(delegate_ptr->GetMessageText());
   AddChildView(label_);

   const auto buttons = delegate_ptr->GetButtons();
  if (buttons & ConfirmInfoBarDelegate::BUTTON_OK) {
    ok_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_OK);
    ok_button_->SetProminent(true);
    if (delegate_ptr->OKButtonTriggersUACPrompt()) {
      elevation_icon_setter_.reset(new ElevationIconSetter(
          ok_button_,
          base::BindOnce(&ConfirmInfoBar::Layout, base::Unretained(this))));
    }
  }

  if (buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
    cancel_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_CANCEL);
    if (buttons == ConfirmInfoBarDelegate::BUTTON_CANCEL)
      cancel_button_->SetProminent(true);
  }

  link_ = CreateLink(delegate_ptr->GetLinkText(), this);
  AddChildView(link_);
}

Eliding from the wrong side in an infobar in DevTools in Google Chrome prior to 68.0.3440.75 allowed an attacker who convinced a user to install a malicious extension to Hide Chrome Security UI via a crafted Chrome Extension.


ConfirmInfoBar::ConfirmInfoBar(std::unique_ptr<ConfirmInfoBarDelegate> delegate)
     : InfoBarView(std::move(delegate)) {
   auto* delegate_ptr = GetDelegate();
   label_ = CreateLabel(delegate_ptr->GetMessageText());
  label_->SetElideBehavior(delegate_ptr->GetMessageElideBehavior());
   AddChildView(label_);

   const auto buttons = delegate_ptr->GetButtons();
  if (buttons & ConfirmInfoBarDelegate::BUTTON_OK) {
    ok_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_OK);
    ok_button_->SetProminent(true);
    if (delegate_ptr->OKButtonTriggersUACPrompt()) {
      elevation_icon_setter_.reset(new ElevationIconSetter(
          ok_button_,
          base::BindOnce(&ConfirmInfoBar::Layout, base::Unretained(this))));
    }
  }

  if (buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
    cancel_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_CANCEL);
    if (buttons == ConfirmInfoBarDelegate::BUTTON_CANCEL)
      cancel_button_->SetProminent(true);
  }

  link_ = CreateLink(delegate_ptr->GetLinkText(), this);
  AddChildView(link_);
}


void FetchManager::Loader::Start() {

  if (!ContentSecurityPolicy::ShouldBypassMainWorld(execution_context_) &&
      !execution_context_->GetContentSecurityPolicy()->AllowConnectToSource(
          fetch_request_data_->Url())) {
    PerformNetworkError(
        "Refused to connect to '" + fetch_request_data_->Url().ElidedString() +
        "' because it violates the document's Content Security Policy.");
    return;
  }

  if ((SecurityOrigin::Create(fetch_request_data_->Url())
           ->IsSameSchemeHostPort(fetch_request_data_->Origin().get())) ||
      (fetch_request_data_->Url().ProtocolIsData() &&
       fetch_request_data_->SameOriginDataURLFlag()) ||
      (fetch_request_data_->Mode() == FetchRequestMode::kNavigate)) {
    PerformSchemeFetch();
    return;
  }

  if (fetch_request_data_->Mode() == FetchRequestMode::kSameOrigin) {
    PerformNetworkError("Fetch API cannot load " +
                        fetch_request_data_->Url().GetString() +
                        ". Request mode is \"same-origin\" but the URL\'s "
                        "origin is not same as the request origin " +
                        fetch_request_data_->Origin()->ToString() + ".");
    return;
  }

   if (fetch_request_data_->Mode() == FetchRequestMode::kNoCORS) {
     fetch_request_data_->SetResponseTainting(FetchRequestData::kOpaqueTainting);
    PerformSchemeFetch();
    return;
  }

  if (!SchemeRegistry::ShouldTreatURLSchemeAsSupportingFetchAPI(
          fetch_request_data_->Url().Protocol())) {
    PerformNetworkError(
        "Fetch API cannot load " + fetch_request_data_->Url().GetString() +
        ". URL scheme must be \"http\" or \"https\" for CORS request.");
    return;
  }

  fetch_request_data_->SetResponseTainting(FetchRequestData::kCORSTainting);

  PerformHTTPFetch();
}

An issue was discovered in certain Apple products. iOS before 11.3 is affected. Safari before 11.1 is affected. iCloud before 7.4 on Windows is affected. iTunes before 12.7.4 on Windows is affected. watchOS before 4.3 is affected. The issue involves the fetch API in the "WebKit" component. It allows remote attackers to bypass the Same Origin Policy and obtain sensitive information via a crafted web site.


void FetchManager::Loader::Start() {

  if (!ContentSecurityPolicy::ShouldBypassMainWorld(execution_context_) &&
      !execution_context_->GetContentSecurityPolicy()->AllowConnectToSource(
          fetch_request_data_->Url())) {
    PerformNetworkError(
        "Refused to connect to '" + fetch_request_data_->Url().ElidedString() +
        "' because it violates the document's Content Security Policy.");
    return;
  }

  if ((SecurityOrigin::Create(fetch_request_data_->Url())
           ->IsSameSchemeHostPort(fetch_request_data_->Origin().get())) ||
      (fetch_request_data_->Url().ProtocolIsData() &&
       fetch_request_data_->SameOriginDataURLFlag()) ||
      (fetch_request_data_->Mode() == FetchRequestMode::kNavigate)) {
    PerformSchemeFetch();
    return;
  }

  if (fetch_request_data_->Mode() == FetchRequestMode::kSameOrigin) {
    PerformNetworkError("Fetch API cannot load " +
                        fetch_request_data_->Url().GetString() +
                        ". Request mode is \"same-origin\" but the URL\'s "
                        "origin is not same as the request origin " +
                        fetch_request_data_->Origin()->ToString() + ".");
    return;
  }

   if (fetch_request_data_->Mode() == FetchRequestMode::kNoCORS) {
    // "If |request|'s redirect mode is not |follow|, then return a network
    // error.
    if (fetch_request_data_->Redirect() != FetchRedirectMode::kFollow) {
      PerformNetworkError("Fetch API cannot load " +
                          fetch_request_data_->Url().GetString() +
                          ". Request mode is \"no-cors\" but the redirect mode "
                          " is not \"follow\".");
      return;
    }

     fetch_request_data_->SetResponseTainting(FetchRequestData::kOpaqueTainting);
    PerformSchemeFetch();
    return;
  }

  if (!SchemeRegistry::ShouldTreatURLSchemeAsSupportingFetchAPI(
          fetch_request_data_->Url().Protocol())) {
    PerformNetworkError(
        "Fetch API cannot load " + fetch_request_data_->Url().GetString() +
        ". URL scheme must be \"http\" or \"https\" for CORS request.");
    return;
  }

  fetch_request_data_->SetResponseTainting(FetchRequestData::kCORSTainting);

  PerformHTTPFetch();
}


void BaseAudioContext::Initialize() {
  if (IsDestinationInitialized())
    return;

  FFTFrame::Initialize();

  audio_worklet_ = AudioWorklet::Create(this);

   if (destination_node_) {
     destination_node_->Handler().Initialize();
     listener_ = AudioListener::Create(*this);
  }
}

A use after free in WebAudio in Google Chrome prior to 69.0.3497.81 allowed a remote attacker to potentially exploit heap corruption via a crafted HTML page.


void BaseAudioContext::Initialize() {
  if (IsDestinationInitialized())
    return;

  FFTFrame::Initialize();

  audio_worklet_ = AudioWorklet::Create(this);

   if (destination_node_) {
     destination_node_->Handler().Initialize();
    // TODO(crbug.com/863951).  The audio thread needs some things from the
    // destination handler like the currentTime.  But the audio thread
    // shouldn't access the |destination_node_| since it's an Oilpan object.
    // Thus, get the destination handler, a non-oilpan object, so we can get
    // the items directly from the handler instead of through the destination
    // node.
    destination_handler_ = &destination_node_->GetAudioDestinationHandler();

     listener_ = AudioListener::Create(*this);
  }
}


GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
                                 const GURL& real_url) {
  if (real_url.SchemeIs(kGuestScheme))
    return real_url;

  GURL url = SiteInstanceImpl::GetEffectiveURL(browser_context, real_url);
  url::Origin origin = url::Origin::Create(url);

  auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
  url::Origin isolated_origin;
  if (policy->GetMatchingIsolatedOrigin(origin, &isolated_origin))
    return isolated_origin.GetURL();

  if (!origin.host().empty() && origin.scheme() != url::kFileScheme) {
    std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
        origin.host(),
        net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
    std::string site = origin.scheme();
    site += url::kStandardSchemeSeparator;
    site += domain.empty() ? origin.host() : domain;
    return GURL(site);
  }

   if (!origin.unique()) {
     DCHECK(!origin.scheme().empty());
     return GURL(origin.scheme() + ":");
   } else if (url.has_scheme()) {
     DCHECK(!url.scheme().empty());
     return GURL(url.scheme() + ":");
   }

  DCHECK(!url.is_valid()) << url;
  return GURL();
}

Insufficient policy enforcement in site isolation in Google Chrome prior to 69.0.3497.81 allowed a remote attacker to bypass site isolation via a crafted HTML page.


GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
                                 const GURL& real_url) {
  if (real_url.SchemeIs(kGuestScheme))
    return real_url;

  GURL url = SiteInstanceImpl::GetEffectiveURL(browser_context, real_url);
  url::Origin origin = url::Origin::Create(url);

  auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
  url::Origin isolated_origin;
  if (policy->GetMatchingIsolatedOrigin(origin, &isolated_origin))
    return isolated_origin.GetURL();

  if (!origin.host().empty() && origin.scheme() != url::kFileScheme) {
    std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
        origin.host(),
        net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
    std::string site = origin.scheme();
    site += url::kStandardSchemeSeparator;
    site += domain.empty() ? origin.host() : domain;
    return GURL(site);
  }

   if (!origin.unique()) {
    // cover blob:file: and filesystem:file: URIs (see also
    // https://crbug.com/697111).
     DCHECK(!origin.scheme().empty());
     return GURL(origin.scheme() + ":");
   } else if (url.has_scheme()) {
    // In some cases, it is not safe to use just the scheme as a site URL, as
    // that might allow two URLs created by different sites to to share a
    // process.  See https://crbug.com/863623.
    //
    // TODO(alexmos,creis): This should eventually be expanded to certain other
    // schemes, such as data: and file:.
    if (url.SchemeIsBlob()) {
      // We get here for blob URLs of form blob:null/guid.  Use the full URL
      // with the guid in that case, which isolates all blob URLs with unique
      // origins from each other.  Remove hash from the URL, since
      // same-document navigations shouldn't use a different site URL.
      if (url.has_ref()) {
        GURL::Replacements replacements;
        replacements.ClearRef();
        url = url.ReplaceComponents(replacements);
      }
      return url;
    }

     DCHECK(!url.scheme().empty());
     return GURL(url.scheme() + ":");
   }

  DCHECK(!url.is_valid()) << url;
  return GURL();
}


bool PlatformFontSkia::InitDefaultFont() {
  if (g_default_font.Get())
    return true;

   bool success = false;
   std::string family = kFallbackFontFamilyName;
  int size_pixels = 12;
   int style = Font::NORMAL;
   Font::Weight weight = Font::Weight::NORMAL;
   FontRenderParams params;

  const SkiaFontDelegate* delegate = SkiaFontDelegate::instance();
  if (delegate) {
    delegate->GetDefaultFontDescription(&family, &size_pixels, &style, &weight,
                                        &params);
  } else if (default_font_description_) {
#if defined(OS_CHROMEOS)
    FontRenderParamsQuery query;
    CHECK(FontList::ParseDescription(*default_font_description_,
                                     &query.families, &query.style,
                                     &query.pixel_size, &query.weight))
        << "Failed to parse font description " << *default_font_description_;
    params = gfx::GetFontRenderParams(query, &family);
    size_pixels = query.pixel_size;
    style = query.style;
    weight = query.weight;
#else
    NOTREACHED();
#endif
  }

  sk_sp<SkTypeface> typeface =
      CreateSkTypeface(style & Font::ITALIC, weight, &family, &success);
  if (!success)
    return false;
  g_default_font.Get() = new PlatformFontSkia(
      std::move(typeface), family, size_pixels, style, weight, params);
  return true;
}

Allowing the chrome.debugger API to run on file:// URLs in DevTools in Google Chrome prior to 69.0.3497.81 allowed an attacker who convinced a user to install a malicious extension to access files on the local file system without file access permission via a crafted Chrome Extension.


bool PlatformFontSkia::InitDefaultFont() {
  if (g_default_font.Get())
    return true;

   bool success = false;
   std::string family = kFallbackFontFamilyName;
  int size_pixels = PlatformFont::kDefaultBaseFontSize;
   int style = Font::NORMAL;
   Font::Weight weight = Font::Weight::NORMAL;
   FontRenderParams params;

  const SkiaFontDelegate* delegate = SkiaFontDelegate::instance();
  if (delegate) {
    delegate->GetDefaultFontDescription(&family, &size_pixels, &style, &weight,
                                        &params);
  } else if (default_font_description_) {
#if defined(OS_CHROMEOS)
    FontRenderParamsQuery query;
    CHECK(FontList::ParseDescription(*default_font_description_,
                                     &query.families, &query.style,
                                     &query.pixel_size, &query.weight))
        << "Failed to parse font description " << *default_font_description_;
    params = gfx::GetFontRenderParams(query, &family);
    size_pixels = query.pixel_size;
    style = query.style;
    weight = query.weight;
#else
    NOTREACHED();
#endif
  }

  sk_sp<SkTypeface> typeface =
      CreateSkTypeface(style & Font::ITALIC, weight, &family, &success);
  if (!success)
    return false;
  g_default_font.Get() = new PlatformFontSkia(
      std::move(typeface), family, size_pixels, style, weight, params);
  return true;
}


bool RendererPermissionsPolicyDelegate::IsRestrictedUrl(
    const GURL& document_url,
    std::string* error) {
  if (dispatcher_->IsExtensionActive(kWebStoreAppId)) {
    if (error)
      *error = errors::kCannotScriptGallery;
     return true;
   }

  if (SearchBouncer::GetInstance()->IsNewTabPage(document_url)) {
     if (error)
       *error = errors::kCannotScriptNtp;
     return true;
  }

  return false;
}

Insufficient policy enforcement in extensions API in Google Chrome prior to 69.0.3497.81 allowed an attacker who convinced a user to install a malicious extension to bypass navigation restrictions via a crafted Chrome Extension.


bool RendererPermissionsPolicyDelegate::IsRestrictedUrl(
    const GURL& document_url,
    std::string* error) {
  if (dispatcher_->IsExtensionActive(kWebStoreAppId)) {
    if (error)
      *error = errors::kCannotScriptGallery;
     return true;
   }

  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          ::switches::kInstantProcess)) {
     if (error)
       *error = errors::kCannotScriptNtp;
     return true;
  }

  return false;
}


void OnSuggestionModelAdded(UiScene* scene,
                            UiBrowserInterface* browser,
                            Model* model,
                            SuggestionBinding* element_binding) {
  auto icon = base::MakeUnique<VectorIcon>(100);
  icon->SetDrawPhase(kPhaseForeground);
  icon->SetType(kTypeOmniboxSuggestionIcon);
  icon->set_hit_testable(false);
  icon->SetSize(kSuggestionIconSizeDMM, kSuggestionIconSizeDMM);
  BindColor(model, icon.get(), &ColorScheme::omnibox_icon,
            &VectorIcon::SetColor);
  VectorIcon* p_icon = icon.get();

  auto icon_box = base::MakeUnique<UiElement>();
  icon_box->SetDrawPhase(kPhaseNone);
  icon_box->SetType(kTypeOmniboxSuggestionIconField);
  icon_box->SetSize(kSuggestionIconFieldWidthDMM, kSuggestionHeightDMM);
  icon_box->AddChild(std::move(icon));

  auto content_text = base::MakeUnique<Text>(kSuggestionContentTextHeightDMM);
  content_text->SetDrawPhase(kPhaseForeground);
  content_text->SetType(kTypeOmniboxSuggestionContentText);
  content_text->set_hit_testable(false);
  content_text->SetTextLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
  content_text->SetSize(kSuggestionTextFieldWidthDMM, 0);
  content_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
  BindColor(model, content_text.get(), &ColorScheme::omnibox_suggestion_content,
            &Text::SetColor);
  Text* p_content_text = content_text.get();

  auto description_text =
      base::MakeUnique<Text>(kSuggestionDescriptionTextHeightDMM);
   description_text->SetDrawPhase(kPhaseForeground);
   description_text->SetType(kTypeOmniboxSuggestionDescriptionText);
   description_text->set_hit_testable(false);
  content_text->SetTextLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
   description_text->SetSize(kSuggestionTextFieldWidthDMM, 0);
   description_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
   BindColor(model, description_text.get(),
            &ColorScheme::omnibox_suggestion_description, &Text::SetColor);
  Text* p_description_text = description_text.get();

  auto text_layout = base::MakeUnique<LinearLayout>(LinearLayout::kDown);
  text_layout->SetType(kTypeOmniboxSuggestionTextLayout);
  text_layout->set_hit_testable(false);
  text_layout->set_margin(kSuggestionLineGapDMM);
  text_layout->AddChild(std::move(content_text));
  text_layout->AddChild(std::move(description_text));

  auto right_margin = base::MakeUnique<UiElement>();
  right_margin->SetDrawPhase(kPhaseNone);
  right_margin->SetSize(kSuggestionRightMarginDMM, kSuggestionHeightDMM);

  auto suggestion_layout = base::MakeUnique<LinearLayout>(LinearLayout::kRight);
  suggestion_layout->SetType(kTypeOmniboxSuggestionLayout);
  suggestion_layout->set_hit_testable(false);
  suggestion_layout->AddChild(std::move(icon_box));
  suggestion_layout->AddChild(std::move(text_layout));
  suggestion_layout->AddChild(std::move(right_margin));

  auto background = Create<Button>(
      kNone, kPhaseForeground,
      base::BindRepeating(
          [](UiBrowserInterface* b, Model* m, SuggestionBinding* e) {
            b->Navigate(e->model()->destination);
            m->omnibox_input_active = false;
          },
          base::Unretained(browser), base::Unretained(model),
          base::Unretained(element_binding)));

  background->SetType(kTypeOmniboxSuggestionBackground);
  background->set_hit_testable(true);
  background->set_bubble_events(true);
  background->set_bounds_contain_children(true);
  background->set_hover_offset(0.0);
  BindButtonColors(model, background.get(),
                   &ColorScheme::suggestion_button_colors,
                   &Button::SetButtonColors);
  background->AddChild(std::move(suggestion_layout));

  element_binding->bindings().push_back(
      VR_BIND_FUNC(base::string16, SuggestionBinding, element_binding,
                   model()->content, Text, p_content_text, SetText));
  element_binding->bindings().push_back(
      base::MakeUnique<Binding<base::string16>>(
          base::BindRepeating(
              [](SuggestionBinding* m) { return m->model()->description; },
              base::Unretained(element_binding)),
          base::BindRepeating(
              [](Text* v, const base::string16& text) {
                v->SetVisibleImmediately(!text.empty());
                v->set_requires_layout(!text.empty());
                if (!text.empty()) {
                  v->SetText(text);
                }
              },
              base::Unretained(p_description_text))));
  element_binding->bindings().push_back(
      VR_BIND(AutocompleteMatch::Type, SuggestionBinding, element_binding,
              model()->type, VectorIcon, p_icon,
              SetIcon(AutocompleteMatch::TypeToVectorIcon(value))));
  element_binding->set_view(background.get());
  scene->AddUiElement(kOmniboxSuggestions, std::move(background));
}

Uninitialized data in WebRTC in Google Chrome prior to 67.0.3396.62 allowed a remote attacker to obtain potentially sensitive information from process memory via a crafted video file.


void OnSuggestionModelAdded(UiScene* scene,
                            UiBrowserInterface* browser,
                            Model* model,
                            SuggestionBinding* element_binding) {
  auto icon = base::MakeUnique<VectorIcon>(100);
  icon->SetDrawPhase(kPhaseForeground);
  icon->SetType(kTypeOmniboxSuggestionIcon);
  icon->set_hit_testable(false);
  icon->SetSize(kSuggestionIconSizeDMM, kSuggestionIconSizeDMM);
  BindColor(model, icon.get(), &ColorScheme::omnibox_icon,
            &VectorIcon::SetColor);
  VectorIcon* p_icon = icon.get();

  auto icon_box = base::MakeUnique<UiElement>();
  icon_box->SetDrawPhase(kPhaseNone);
  icon_box->SetType(kTypeOmniboxSuggestionIconField);
  icon_box->SetSize(kSuggestionIconFieldWidthDMM, kSuggestionHeightDMM);
  icon_box->AddChild(std::move(icon));

  auto content_text = base::MakeUnique<Text>(kSuggestionContentTextHeightDMM);
  content_text->SetDrawPhase(kPhaseForeground);
  content_text->SetType(kTypeOmniboxSuggestionContentText);
  content_text->set_hit_testable(false);
  content_text->SetTextLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
  content_text->SetSize(kSuggestionTextFieldWidthDMM, 0);
  content_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
  BindColor(model, content_text.get(), &ColorScheme::omnibox_suggestion_content,
            &Text::SetColor);
  Text* p_content_text = content_text.get();

  auto description_text =
      base::MakeUnique<Text>(kSuggestionDescriptionTextHeightDMM);
   description_text->SetDrawPhase(kPhaseForeground);
   description_text->SetType(kTypeOmniboxSuggestionDescriptionText);
   description_text->set_hit_testable(false);
  description_text->SetTextLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
   description_text->SetSize(kSuggestionTextFieldWidthDMM, 0);
   description_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
   BindColor(model, description_text.get(),
            &ColorScheme::omnibox_suggestion_description, &Text::SetColor);
  Text* p_description_text = description_text.get();

  auto text_layout = base::MakeUnique<LinearLayout>(LinearLayout::kDown);
  text_layout->SetType(kTypeOmniboxSuggestionTextLayout);
  text_layout->set_hit_testable(false);
  text_layout->set_margin(kSuggestionLineGapDMM);
  text_layout->AddChild(std::move(content_text));
  text_layout->AddChild(std::move(description_text));

  auto right_margin = base::MakeUnique<UiElement>();
  right_margin->SetDrawPhase(kPhaseNone);
  right_margin->SetSize(kSuggestionRightMarginDMM, kSuggestionHeightDMM);

  auto suggestion_layout = base::MakeUnique<LinearLayout>(LinearLayout::kRight);
  suggestion_layout->SetType(kTypeOmniboxSuggestionLayout);
  suggestion_layout->set_hit_testable(false);
  suggestion_layout->AddChild(std::move(icon_box));
  suggestion_layout->AddChild(std::move(text_layout));
  suggestion_layout->AddChild(std::move(right_margin));

  auto background = Create<Button>(
      kNone, kPhaseForeground,
      base::BindRepeating(
          [](UiBrowserInterface* b, Model* m, SuggestionBinding* e) {
            b->Navigate(e->model()->destination);
            m->omnibox_input_active = false;
          },
          base::Unretained(browser), base::Unretained(model),
          base::Unretained(element_binding)));

  background->SetType(kTypeOmniboxSuggestionBackground);
  background->set_hit_testable(true);
  background->set_bubble_events(true);
  background->set_bounds_contain_children(true);
  background->set_hover_offset(0.0);
  BindButtonColors(model, background.get(),
                   &ColorScheme::suggestion_button_colors,
                   &Button::SetButtonColors);
  background->AddChild(std::move(suggestion_layout));

  element_binding->bindings().push_back(
      VR_BIND_FUNC(base::string16, SuggestionBinding, element_binding,
                   model()->content, Text, p_content_text, SetText));
  element_binding->bindings().push_back(
      base::MakeUnique<Binding<base::string16>>(
          base::BindRepeating(
              [](SuggestionBinding* m) { return m->model()->description; },
              base::Unretained(element_binding)),
          base::BindRepeating(
              [](Text* v, const base::string16& text) {
                v->SetVisibleImmediately(!text.empty());
                v->set_requires_layout(!text.empty());
                if (!text.empty()) {
                  v->SetText(text);
                }
              },
              base::Unretained(p_description_text))));
  element_binding->bindings().push_back(
      VR_BIND(AutocompleteMatch::Type, SuggestionBinding, element_binding,
              model()->type, VectorIcon, p_icon,
              SetIcon(AutocompleteMatch::TypeToVectorIcon(value))));
  element_binding->set_view(background.get());
  scene->AddUiElement(kOmniboxSuggestions, std::move(background));
}


PerformanceNavigationTiming::PerformanceNavigationTiming(
    LocalFrame* frame,
     ResourceTimingInfo* info,
     TimeTicks time_origin,
     const WebVector<WebServerTimingInfo>& server_timing)
    : PerformanceResourceTiming(info ? info->InitialURL().GetString() : "",
                                "navigation",
                                time_origin,
                                server_timing),
       ContextClient(frame),
       resource_timing_info_(info) {
   DCHECK(frame);
  DCHECK(info);
}

Information leak in Blink in Google Chrome prior to 67.0.3396.62 allowed a remote attacker to bypass no-referrer policy via a crafted HTML page.


PerformanceNavigationTiming::PerformanceNavigationTiming(
    LocalFrame* frame,
     ResourceTimingInfo* info,
     TimeTicks time_origin,
     const WebVector<WebServerTimingInfo>& server_timing)
    : PerformanceResourceTiming(
          info ? info->FinalResponse().Url().GetString() : "",
          "navigation",
          time_origin,
          server_timing),
       ContextClient(frame),
       resource_timing_info_(info) {
   DCHECK(frame);
  DCHECK(info);
}


 scoped_refptr<Image> CSSPaintValue::GetImage(
     const ImageResourceObserver& client,
     const Document& document,
    const ComputedStyle&,
     const FloatSize& target_size) {
   if (!generator_) {
     generator_ = CSSPaintImageGenerator::Create(
         GetName(), document, paint_image_generator_observer_);
  }

  if (!ParseInputArguments(document))
    return nullptr;

  return generator_->Paint(client, RoundedIntSize(target_size),
                           parsed_input_arguments_);
}

CSS Paint API in Blink in Google Chrome prior to 67.0.3396.62 allowed a remote attacker to leak cross-origin data via a crafted HTML page.


 scoped_refptr<Image> CSSPaintValue::GetImage(
     const ImageResourceObserver& client,
     const Document& document,
    const ComputedStyle& style,
     const FloatSize& target_size) {
  // https://crbug.com/835589: early exit when paint target is associated with
  // a link.
  if (style.InsideLink() != EInsideLink::kNotInsideLink)
    return nullptr;

   if (!generator_) {
     generator_ = CSSPaintImageGenerator::Create(
         GetName(), document, paint_image_generator_observer_);
  }

  if (!ParseInputArguments(document))
    return nullptr;

  return generator_->Paint(client, RoundedIntSize(target_size),
                           parsed_input_arguments_);
}


bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) {
  if (session->restricted() && !IsFrameHostAllowedForRestrictedSessions())
    return false;
  session->SetRenderer(frame_host_ ? frame_host_->GetProcess()->GetID()
                                   : ChildProcessHost::kInvalidUniqueID,
                       frame_host_);

  protocol::EmulationHandler* emulation_handler =
      new protocol::EmulationHandler();
  session->AddHandler(base::WrapUnique(new protocol::BrowserHandler()));
  session->AddHandler(base::WrapUnique(new protocol::DOMHandler()));
  session->AddHandler(base::WrapUnique(emulation_handler));
  session->AddHandler(base::WrapUnique(new protocol::InputHandler()));
  session->AddHandler(base::WrapUnique(new protocol::InspectorHandler()));
  session->AddHandler(base::WrapUnique(new protocol::IOHandler(
      GetIOContext())));
  session->AddHandler(base::WrapUnique(new protocol::MemoryHandler()));
  session->AddHandler(base::WrapUnique(new protocol::NetworkHandler(GetId())));
   session->AddHandler(base::WrapUnique(new protocol::SchemaHandler()));
   session->AddHandler(base::WrapUnique(new protocol::ServiceWorkerHandler()));
   session->AddHandler(base::WrapUnique(new protocol::StorageHandler()));
  session->AddHandler(
      base::WrapUnique(new protocol::TargetHandler(false /* browser_only */)));
   session->AddHandler(base::WrapUnique(new protocol::TracingHandler(
       protocol::TracingHandler::Renderer,
       frame_tree_node_ ? frame_tree_node_->frame_tree_node_id() : 0,
      GetIOContext())));
  session->AddHandler(
      base::WrapUnique(new protocol::PageHandler(emulation_handler)));
  session->AddHandler(base::WrapUnique(new protocol::SecurityHandler()));

  if (EnsureAgent())
    session->AttachToAgent(agent_ptr_);

  if (sessions().size() == 1) {
    if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor) &&
        !base::FeatureList::IsEnabled(
            features::kUseVideoCaptureApiForDevToolsSnapshots)) {
      frame_trace_recorder_.reset(new DevToolsFrameTraceRecorder());
    }
    GrantPolicy();
#if defined(OS_ANDROID)
    GetWakeLock()->RequestWakeLock();
#endif
  }
  return true;
}

Insufficient target checks on the chrome.debugger API in DevTools in Google Chrome prior to 67.0.3396.62 allowed an attacker who convinced a user to install a malicious extension to execute arbitrary code via a crafted Chrome Extension.


bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) {
  if (session->restricted() && !IsFrameHostAllowedForRestrictedSessions())
    return false;
  session->SetRenderer(frame_host_ ? frame_host_->GetProcess()->GetID()
                                   : ChildProcessHost::kInvalidUniqueID,
                       frame_host_);

  protocol::EmulationHandler* emulation_handler =
      new protocol::EmulationHandler();
  session->AddHandler(base::WrapUnique(new protocol::BrowserHandler()));
  session->AddHandler(base::WrapUnique(new protocol::DOMHandler()));
  session->AddHandler(base::WrapUnique(emulation_handler));
  session->AddHandler(base::WrapUnique(new protocol::InputHandler()));
  session->AddHandler(base::WrapUnique(new protocol::InspectorHandler()));
  session->AddHandler(base::WrapUnique(new protocol::IOHandler(
      GetIOContext())));
  session->AddHandler(base::WrapUnique(new protocol::MemoryHandler()));
  session->AddHandler(base::WrapUnique(new protocol::NetworkHandler(GetId())));
   session->AddHandler(base::WrapUnique(new protocol::SchemaHandler()));
   session->AddHandler(base::WrapUnique(new protocol::ServiceWorkerHandler()));
   session->AddHandler(base::WrapUnique(new protocol::StorageHandler()));
  if (!session->restricted()) {
    session->AddHandler(base::WrapUnique(
        new protocol::TargetHandler(false /* browser_only */)));
  }
   session->AddHandler(base::WrapUnique(new protocol::TracingHandler(
       protocol::TracingHandler::Renderer,
       frame_tree_node_ ? frame_tree_node_->frame_tree_node_id() : 0,
      GetIOContext())));
  session->AddHandler(
      base::WrapUnique(new protocol::PageHandler(emulation_handler)));
  session->AddHandler(base::WrapUnique(new protocol::SecurityHandler()));

  if (EnsureAgent())
    session->AttachToAgent(agent_ptr_);

  if (sessions().size() == 1) {
    if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor) &&
        !base::FeatureList::IsEnabled(
            features::kUseVideoCaptureApiForDevToolsSnapshots)) {
      frame_trace_recorder_.reset(new DevToolsFrameTraceRecorder());
    }
    GrantPolicy();
#if defined(OS_ANDROID)
    GetWakeLock()->RequestWakeLock();
#endif
  }
  return true;
}


void CredentialManagerImpl::OnProvisionalSaveComplete() {
  DCHECK(form_manager_);
  DCHECK(client_->IsSavingAndFillingEnabledForCurrentPage());
  const autofill::PasswordForm& form = form_manager_->pending_credentials();

  if (form_manager_->IsPendingCredentialsPublicSuffixMatch()) {
    form_manager_->Save();
    return;
  }

  if (!form.federation_origin.unique()) {
    for (auto* match : form_manager_->form_fetcher()->GetFederatedMatches()) {
      if (match->username_value == form.username_value &&
          match->federation_origin.IsSameOriginWith(form.federation_origin)) {
        form_manager_->Update(*match);
        return;
      }
    }
  } else if (!form_manager_->IsNewLogin()) {
    form_manager_->Update(*form_manager_->preferred_match());
     return;
   }

  client_->PromptUserToSaveOrUpdatePassword(std::move(form_manager_), false);
}

Insufficient validation in V8 in Google Chrome prior to 67.0.3396.62 allowed a remote attacker to perform an out of bounds memory read via a crafted HTML page.


void CredentialManagerImpl::OnProvisionalSaveComplete() {
  DCHECK(form_manager_);
  DCHECK(client_->IsSavingAndFillingEnabledForCurrentPage());
  const autofill::PasswordForm& form = form_manager_->pending_credentials();

  if (form_manager_->IsPendingCredentialsPublicSuffixMatch()) {
    form_manager_->Save();
    return;
  }

  if (!form.federation_origin.unique()) {
    for (auto* match : form_manager_->form_fetcher()->GetFederatedMatches()) {
      if (match->username_value == form.username_value &&
          match->federation_origin.IsSameOriginWith(form.federation_origin)) {
        form_manager_->Update(*match);
        return;
      }
    }
  } else if (!form_manager_->IsNewLogin()) {
    auto best_match = form_manager_->best_matches().find(form.username_value);
    // NOTE: We can't use DCHECK_NE here, since std::map<>::iterator does not
    // support operator<<.
    DCHECK(best_match != form_manager_->best_matches().end());
    form_manager_->Update(*best_match->second);
     return;
   }

  client_->PromptUserToSaveOrUpdatePassword(std::move(form_manager_), false);
}


ExtensionNavigationThrottle::WillStartOrRedirectRequest() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  content::WebContents* web_contents = navigation_handle()->GetWebContents();
  ExtensionRegistry* registry =
      ExtensionRegistry::Get(web_contents->GetBrowserContext());

  const GURL& url = navigation_handle()->GetURL();
  bool url_has_extension_scheme = url.SchemeIs(kExtensionScheme);
  url::Origin target_origin = url::Origin::Create(url);
  const Extension* target_extension = nullptr;
  if (url_has_extension_scheme) {
    target_extension =
        registry->enabled_extensions().GetExtensionOrAppByURL(url);
  } else if (target_origin.scheme() == kExtensionScheme) {
    DCHECK(url.SchemeIsFileSystem() || url.SchemeIsBlob());
    target_extension =
        registry->enabled_extensions().GetByID(target_origin.host());
  } else {
    return content::NavigationThrottle::PROCEED;
  }

  if (!target_extension) {
    return content::NavigationThrottle::BLOCK_REQUEST;
  }

  if (target_extension->is_hosted_app()) {
    base::StringPiece resource_root_relative_path =
        url.path_piece().empty() ? base::StringPiece()
                                 : url.path_piece().substr(1);
    if (!IconsInfo::GetIcons(target_extension)
             .ContainsPath(resource_root_relative_path)) {
      return content::NavigationThrottle::BLOCK_REQUEST;
     }
   }

  if (navigation_handle()->IsInMainFrame()) {
    bool current_frame_is_extension_process =
        !!registry->enabled_extensions().GetExtensionOrAppByURL(
            navigation_handle()->GetStartingSiteInstance()->GetSiteURL());
    if (!url_has_extension_scheme && !current_frame_is_extension_process) {
      if (target_origin.scheme() == kExtensionScheme &&
          navigation_handle()->GetSuggestedFilename().has_value()) {
        return content::NavigationThrottle::PROCEED;
      }
      bool has_webview_permission =
          target_extension->permissions_data()->HasAPIPermission(
              APIPermission::kWebView);
      if (!has_webview_permission)
        return content::NavigationThrottle::CANCEL;
     }

     guest_view::GuestViewBase* guest =
         guest_view::GuestViewBase::FromWebContents(web_contents);
     if (url_has_extension_scheme && guest) {
      const std::string& owner_extension_id = guest->owner_host();
      const Extension* owner_extension =
          registry->enabled_extensions().GetByID(owner_extension_id);

      std::string partition_domain;
      std::string partition_id;
      bool in_memory = false;
      bool is_guest = WebViewGuest::GetGuestPartitionConfigForSite(
          navigation_handle()->GetStartingSiteInstance()->GetSiteURL(),
          &partition_domain, &partition_id, &in_memory);

      bool allowed = true;
      url_request_util::AllowCrossRendererResourceLoadHelper(
          is_guest, target_extension, owner_extension, partition_id, url.path(),
          navigation_handle()->GetPageTransition(), &allowed);
      if (!allowed)
        return content::NavigationThrottle::BLOCK_REQUEST;
    }

    return content::NavigationThrottle::PROCEED;
  }

  content::RenderFrameHost* parent = navigation_handle()->GetParentFrame();

  bool external_ancestor = false;
  for (auto* ancestor = parent; ancestor; ancestor = ancestor->GetParent()) {
    if (ancestor->GetLastCommittedOrigin() == target_origin)
      continue;
    if (url::Origin::Create(ancestor->GetLastCommittedURL()) == target_origin)
      continue;
    if (ancestor->GetLastCommittedURL().SchemeIs(
            content::kChromeDevToolsScheme))
      continue;

    external_ancestor = true;
    break;
  }

  if (external_ancestor) {
    if (!url_has_extension_scheme)
      return content::NavigationThrottle::CANCEL;

    if (!WebAccessibleResourcesInfo::IsResourceWebAccessible(target_extension,
                                                             url.path()))
      return content::NavigationThrottle::BLOCK_REQUEST;

    if (target_extension->is_platform_app())
      return content::NavigationThrottle::CANCEL;

    const Extension* parent_extension =
        registry->enabled_extensions().GetExtensionOrAppByURL(
            parent->GetSiteInstance()->GetSiteURL());
    if (parent_extension && parent_extension->is_platform_app())
      return content::NavigationThrottle::BLOCK_REQUEST;
  }

  return content::NavigationThrottle::PROCEED;
}

Insufficient validation of input in Blink in Google Chrome prior to 66.0.3359.170 allowed a remote attacker to perform privilege escalation via a crafted HTML page.


ExtensionNavigationThrottle::WillStartOrRedirectRequest() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  content::WebContents* web_contents = navigation_handle()->GetWebContents();
  ExtensionRegistry* registry =
      ExtensionRegistry::Get(web_contents->GetBrowserContext());

  const GURL& url = navigation_handle()->GetURL();
  bool url_has_extension_scheme = url.SchemeIs(kExtensionScheme);
  url::Origin target_origin = url::Origin::Create(url);
  const Extension* target_extension = nullptr;
  if (url_has_extension_scheme) {
    target_extension =
        registry->enabled_extensions().GetExtensionOrAppByURL(url);
  } else if (target_origin.scheme() == kExtensionScheme) {
    DCHECK(url.SchemeIsFileSystem() || url.SchemeIsBlob());
    target_extension =
        registry->enabled_extensions().GetByID(target_origin.host());
  } else {
    return content::NavigationThrottle::PROCEED;
  }

  if (!target_extension) {
    return content::NavigationThrottle::BLOCK_REQUEST;
  }

  if (target_extension->is_hosted_app()) {
    base::StringPiece resource_root_relative_path =
        url.path_piece().empty() ? base::StringPiece()
                                 : url.path_piece().substr(1);
    if (!IconsInfo::GetIcons(target_extension)
             .ContainsPath(resource_root_relative_path)) {
      return content::NavigationThrottle::BLOCK_REQUEST;
     }
   }

  // Block all navigations to blob: or filesystem: URLs with extension
  // origin from non-extension processes.  See https://crbug.com/645028 and
  // https://crbug.com/836858.
  bool current_frame_is_extension_process =
      !!registry->enabled_extensions().GetExtensionOrAppByURL(
          navigation_handle()->GetStartingSiteInstance()->GetSiteURL());

  if (!url_has_extension_scheme && !current_frame_is_extension_process) {
    // Relax this restriction for navigations that will result in downloads.
    // See https://crbug.com/714373.
    if (target_origin.scheme() == kExtensionScheme &&
        navigation_handle()->GetSuggestedFilename().has_value()) {
      return content::NavigationThrottle::PROCEED;
     }

    // Relax this restriction for apps that use <webview>.  See
    // https://crbug.com/652077.
    bool has_webview_permission =
        target_extension->permissions_data()->HasAPIPermission(
            APIPermission::kWebView);
    if (!has_webview_permission)
      return content::NavigationThrottle::CANCEL;
  }

  if (navigation_handle()->IsInMainFrame()) {
     guest_view::GuestViewBase* guest =
         guest_view::GuestViewBase::FromWebContents(web_contents);
     if (url_has_extension_scheme && guest) {
      const std::string& owner_extension_id = guest->owner_host();
      const Extension* owner_extension =
          registry->enabled_extensions().GetByID(owner_extension_id);

      std::string partition_domain;
      std::string partition_id;
      bool in_memory = false;
      bool is_guest = WebViewGuest::GetGuestPartitionConfigForSite(
          navigation_handle()->GetStartingSiteInstance()->GetSiteURL(),
          &partition_domain, &partition_id, &in_memory);

      bool allowed = true;
      url_request_util::AllowCrossRendererResourceLoadHelper(
          is_guest, target_extension, owner_extension, partition_id, url.path(),
          navigation_handle()->GetPageTransition(), &allowed);
      if (!allowed)
        return content::NavigationThrottle::BLOCK_REQUEST;
    }

    return content::NavigationThrottle::PROCEED;
  }

  content::RenderFrameHost* parent = navigation_handle()->GetParentFrame();

  bool external_ancestor = false;
  for (auto* ancestor = parent; ancestor; ancestor = ancestor->GetParent()) {
    if (ancestor->GetLastCommittedOrigin() == target_origin)
      continue;
    if (url::Origin::Create(ancestor->GetLastCommittedURL()) == target_origin)
      continue;
    if (ancestor->GetLastCommittedURL().SchemeIs(
            content::kChromeDevToolsScheme))
      continue;

    external_ancestor = true;
    break;
  }

  if (external_ancestor) {
    if (!url_has_extension_scheme)
      return content::NavigationThrottle::CANCEL;

    if (!WebAccessibleResourcesInfo::IsResourceWebAccessible(target_extension,
                                                             url.path()))
      return content::NavigationThrottle::BLOCK_REQUEST;

    if (target_extension->is_platform_app())
      return content::NavigationThrottle::CANCEL;

    const Extension* parent_extension =
        registry->enabled_extensions().GetExtensionOrAppByURL(
            parent->GetSiteInstance()->GetSiteURL());
    if (parent_extension && parent_extension->is_platform_app())
      return content::NavigationThrottle::BLOCK_REQUEST;
  }

  return content::NavigationThrottle::PROCEED;
}


v8::Local<v8::Value> ModuleSystem::RequireForJsInner(
    v8::Local<v8::String> module_name) {
  v8::EscapableHandleScope handle_scope(GetIsolate());
  v8::Local<v8::Context> v8_context = context()->v8_context();
  v8::Context::Scope context_scope(v8_context);

  v8::Local<v8::Object> global(context()->v8_context()->Global());

  v8::Local<v8::Value> modules_value;
  if (!GetPrivate(global, kModulesField, &modules_value) ||
      modules_value->IsUndefined()) {
    Warn(GetIsolate(), "Extension view no longer exists");
    return v8::Undefined(GetIsolate());
  }

   v8::Local<v8::Object> modules(v8::Local<v8::Object>::Cast(modules_value));
   v8::Local<v8::Value> exports;
  if (!GetProperty(v8_context, modules, module_name, &exports) ||
       !exports->IsUndefined())
     return handle_scope.Escape(exports);

   exports = LoadModule(*v8::String::Utf8Value(module_name));
  SetProperty(v8_context, modules, module_name, exports);
   return handle_scope.Escape(exports);
 }

The ModuleSystem::RequireForJsInner function in extensions/renderer/module_system.cc in the extension bindings in Google Chrome before 51.0.2704.63 mishandles properties, which allows remote attackers to conduct bindings-interception attacks and bypass the Same Origin Policy via unspecified vectors.


v8::Local<v8::Value> ModuleSystem::RequireForJsInner(
    v8::Local<v8::String> module_name) {
  v8::EscapableHandleScope handle_scope(GetIsolate());
  v8::Local<v8::Context> v8_context = context()->v8_context();
  v8::Context::Scope context_scope(v8_context);

  v8::Local<v8::Object> global(context()->v8_context()->Global());

  v8::Local<v8::Value> modules_value;
  if (!GetPrivate(global, kModulesField, &modules_value) ||
      modules_value->IsUndefined()) {
    Warn(GetIsolate(), "Extension view no longer exists");
    return v8::Undefined(GetIsolate());
  }

   v8::Local<v8::Object> modules(v8::Local<v8::Object>::Cast(modules_value));
   v8::Local<v8::Value> exports;
  if (!GetPrivateProperty(v8_context, modules, module_name, &exports) ||
       !exports->IsUndefined())
     return handle_scope.Escape(exports);

   exports = LoadModule(*v8::String::Utf8Value(module_name));
  SetPrivateProperty(v8_context, modules, module_name, exports);
   return handle_scope.Escape(exports);
 }