// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <memory>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/strings/escape.h"
#include "base/strings/stringprintf.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "content/shell/common/shell_switches.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "url/gurl.h"

namespace content {

// WebContentsDelegate that fails to open a URL when there's a request that
// needs to be transferred between renderers.
class NoTransferRequestDelegate : public WebContentsDelegate {
 public:
  NoTransferRequestDelegate() {}

  NoTransferRequestDelegate(const NoTransferRequestDelegate&) = delete;
  NoTransferRequestDelegate& operator=(const NoTransferRequestDelegate&) =
      delete;

  bool ShouldAllowRendererInitiatedCrossProcessNavigation(
      bool is_outermost_main_frame_navigation) override {
    // Intentionally cancel the transfer.
    return false;
  }
};

class CrossSiteTransferTest : public ContentBrowserTest {
 public:
  CrossSiteTransferTest() {}

  // ContentBrowserTest implementation:
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    content::SetupCrossSiteRedirector(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());
  }

 protected:
  void NavigateToURLContentInitiated(Shell* window,
                                     const GURL& url,
                                     bool should_replace_current_entry,
                                     bool should_wait_for_navigation) {
    std::unique_ptr<TestNavigationManager> navigation_manager =
        should_wait_for_navigation ? std::make_unique<TestNavigationManager>(
                                         window->web_contents(), url)
                                   : nullptr;
    std::string script;
    if (should_replace_current_entry)
      script = JsReplace("location.replace($1)", url);
    else
      script = JsReplace("location.href = $1", url);
    EXPECT_TRUE(ExecJs(window, script));
    if (should_wait_for_navigation) {
      EXPECT_TRUE(navigation_manager->WaitForRequestStart());
      EXPECT_TRUE(navigation_manager->WaitForResponse());
      ASSERT_TRUE(navigation_manager->WaitForNavigationFinished());
      EXPECT_TRUE(navigation_manager->was_successful());
    }
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    IsolateAllSitesForTesting(command_line);
  }
};

// The following tests crash in the ThreadSanitizer runtime,
// http://crbug.com/356758.
#if defined(THREAD_SANITIZER)
#define MAYBE_ReplaceEntryCrossProcessThenTransfer \
    DISABLED_ReplaceEntryCrossProcessThenTransfer
#define MAYBE_ReplaceEntryCrossProcessTwice \
    DISABLED_ReplaceEntryCrossProcessTwice
#else
#define MAYBE_ReplaceEntryCrossProcessThenTransfer \
    ReplaceEntryCrossProcessThenTransfer
#define MAYBE_ReplaceEntryCrossProcessTwice ReplaceEntryCrossProcessTwice
#endif
// Tests that the |should_replace_current_entry| flag persists correctly across
// request transfers that began with a cross-process navigation.
IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
                       MAYBE_ReplaceEntryCrossProcessThenTransfer) {
  NavigationController& controller = shell()->web_contents()->GetController();

  // Navigate to a starting URL, so there is a history entry to replace.
  GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
  EXPECT_TRUE(NavigateToURL(shell(), url1));

  // Navigate to a page on A.com with entry replacement. This navigation is
  // cross-site, so the renderer will send it to the browser via OpenURL to give
  // to a new process. It will then be transferred into yet another process due
  // to the call above.
  GURL url2 =
      embedded_test_server()->GetURL("A.com", "/site_isolation/blank.html?2");
  NavigateToURLContentInitiated(shell(), url2, true, true);

  // There should be one history entry. url2 should have replaced url1.
  EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
  EXPECT_EQ(1, controller.GetEntryCount());
  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
  EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());

  // Now navigate as before to a page on B.com, but normally (without
  // replacement). This will still perform a double process-swap as above, via
  // OpenURL and then transfer.
  GURL url3 =
      embedded_test_server()->GetURL("B.com", "/site_isolation/blank.html?3");
  NavigateToURLContentInitiated(shell(), url3, false, true);

  // There should be two history entries. url2 should have replaced url1. url2
  // should not have replaced url3.
  EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
  EXPECT_EQ(2, controller.GetEntryCount());
  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
  EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
  EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
}

// Tests that the |should_replace_current_entry| flag persists correctly across
// request transfers that began with a content-initiated in-process
// navigation. This test is the same as the test above, except transfering from
// in-process.
IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
                       ReplaceEntryInProcessThenTransfer) {
  NavigationController& controller = shell()->web_contents()->GetController();

  // Navigate to a starting URL, so there is a history entry to replace.
  GURL url = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  // Navigate in-process with entry replacement. It will then be transferred
  // into a new one due to the call above.
  GURL url2 = embedded_test_server()->GetURL("/site_isolation/blank.html?2");
  NavigateToURLContentInitiated(shell(), url2, true, true);

  // There should be one history entry. url2 should have replaced url1.
  EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
  EXPECT_EQ(1, controller.GetEntryCount());
  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
  EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());

  // Now navigate as before, but without replacement.
  GURL url3 = embedded_test_server()->GetURL("/site_isolation/blank.html?3");
  NavigateToURLContentInitiated(shell(), url3, false, true);

  // There should be two history entries. url2 should have replaced url1. url2
  // should not have replaced url3.
  EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
  EXPECT_EQ(2, controller.GetEntryCount());
  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
  EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
  EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
}

// Tests that the |should_replace_current_entry| flag persists correctly across
// request transfers that cross processes twice from renderer policy.
IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
                       MAYBE_ReplaceEntryCrossProcessTwice) {
  NavigationController& controller = shell()->web_contents()->GetController();

  // Navigate to a starting URL, so there is a history entry to replace.
  GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
  EXPECT_TRUE(NavigateToURL(shell(), url1));

  // Navigate to a page on A.com which redirects to B.com with entry
  // replacement. This will switch processes via OpenURL twice. First to A.com,
  // and second in response to the server redirect to B.com. The second swap is
  // also renderer-initiated via OpenURL because decidePolicyForNavigation is
  // currently applied on redirects.
  GURL::Replacements replace_host;
  GURL url2b =
      embedded_test_server()->GetURL("B.com", "/site_isolation/blank.html?2");
  GURL url2a = embedded_test_server()->GetURL(
      "A.com", "/cross-site/" + url2b.host() + url2b.PathForRequest());
  NavigateToURLContentInitiated(shell(), url2a, true, true);

  // There should be one history entry. url2b should have replaced url1.
  EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
  EXPECT_EQ(1, controller.GetEntryCount());
  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
  EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());

  // Now repeat without replacement.
  GURL url3b =
      embedded_test_server()->GetURL("B.com", "/site_isolation/blank.html?3");
  GURL url3a = embedded_test_server()->GetURL(
      "A.com", "/cross-site/" + url3b.host() + url3b.PathForRequest());
  NavigateToURLContentInitiated(shell(), url3a, false, true);

  // There should be two history entries. url2b should have replaced url1. url3b
  // should not have replaced url2b.
  EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
  EXPECT_EQ(2, controller.GetEntryCount());
  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
  EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());
  EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL());
}

// Tests that the request is destroyed when a cross process navigation is
// cancelled.
IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, NoLeakOnCrossSiteCancel) {
  NavigationController& controller = shell()->web_contents()->GetController();

  // Navigate to a starting URL, so there is a history entry to replace.
  GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
  EXPECT_TRUE(NavigateToURL(shell(), url1));

  NoTransferRequestDelegate no_transfer_request_delegate;
  WebContentsDelegate* old_delegate = shell()->web_contents()->GetDelegate();
  shell()->web_contents()->SetDelegate(&no_transfer_request_delegate);

  // Navigate to a page on A.com with entry replacement. This navigation is
  // cross-site, so the renderer will send it to the browser via OpenURL to give
  // to a new process. It will then be transferred into yet another process due
  // to the call above.
  GURL url2 =
      embedded_test_server()->GetURL("A.com", "/site_isolation/blank.html?2");
  TestNavigationManager navigation_manager(shell()->web_contents(), url2);

  NavigationHandleObserver handle_observer(shell()->web_contents(), url2);
  // Don't wait for the navigation to complete, since that never happens in
  // this case.
  NavigateToURLContentInitiated(shell(), url2, false, false);

  // Make sure the request for url2 did not complete.
  EXPECT_FALSE(navigation_manager.WaitForResponse());

  // There should be one history entry, with url1.
  EXPECT_EQ(1, controller.GetEntryCount());
  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
  EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());

  EXPECT_EQ(net::ERR_ABORTED, handle_observer.net_error_code());
  shell()->web_contents()->SetDelegate(old_delegate);
}

// Test that verifies that a cross-process transfer retains ability to read
// files encapsulated by HTTP POST body that is forwarded to the new renderer.
// Invalid handling of this scenario has been suspected as the cause of at least
// some of the renderer kills tracked in https://crbug.com/613260.
IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, PostWithFileData) {
  // Navigate to the page with form that posts via 307 redirection to
  // |redirect_target_url| (cross-site from |form_url|).  Using 307 (rather than
  // 302) redirection is important to preserve the HTTP method and POST body.
  GURL form_url(embedded_test_server()->GetURL(
      "a.com", "/form_that_posts_cross_site.html"));
  GURL redirect_target_url(embedded_test_server()->GetURL("x.com", "/echoall"));
  EXPECT_TRUE(NavigateToURL(shell(), form_url));

  // Prepare a file to upload.
  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir temp_dir;
  base::FilePath file_path;
  std::string file_content("test-file-content");
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &file_path));
  ASSERT_TRUE(base::WriteFile(file_path, file_content));

  base::RunLoop run_loop;
  // Fill out the form to refer to the test file.
  std::unique_ptr<FileChooserDelegate> delegate(
      new FileChooserDelegate(file_path, run_loop.QuitClosure()));
  shell()->web_contents()->SetDelegate(delegate.get());
  EXPECT_TRUE(ExecJs(shell()->web_contents(),
                     "document.getElementById('file').click();"));
  run_loop.Run();

  // Remember the old process id for a sanity check below.
  int old_process_id =
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();

  // Submit the form.
  TestNavigationObserver form_post_observer(shell()->web_contents(), 1);
  EXPECT_TRUE(
      ExecJs(shell(), "document.getElementById('file-form').submit();"));
  form_post_observer.Wait();

  // Verify that we arrived at the expected, redirected location.
  EXPECT_EQ(redirect_target_url,
            shell()->web_contents()->GetLastCommittedURL());

  // Verify that the test really verifies access of a *new* renderer process.
  int new_process_id =
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
  ASSERT_NE(new_process_id, old_process_id);

  // MAIN VERIFICATION: Check if the new renderer process is able to read the
  // file.
  EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
      new_process_id, file_path));

  // Verify that POST body got preserved by 307 redirect.  This expectation
  // comes from: https://tools.ietf.org/html/rfc7231#section-6.4.7
  std::string actual_page_body =
      EvalJs(shell()->web_contents(),
             "document.getElementsByTagName('pre')[0].innerText;")
          .ExtractString();
  EXPECT_THAT(actual_page_body, ::testing::HasSubstr(file_content));
  EXPECT_THAT(actual_page_body,
              ::testing::HasSubstr(file_path.BaseName().AsUTF8Unsafe()));
  EXPECT_THAT(actual_page_body,
              ::testing::HasSubstr("form-data; name=\"file\""));
}

// Test that verifies that if navigation originator doesn't have access to a
// file, then no access is granted after a cross-process transfer of POST data.
// This is a regression test for https://crbug.com/726067.
//
// This test is somewhat similar to
// http/tests/navigation/form-targets-cross-site-frame-post.html web test
// except that it 1) tests with files, 2) simulates a malicious scenario and 3)
// verifies file access (all of these 3 things are not possible with web
// tests).
//
// This test is very similar to CrossSiteTransferTest.PostWithFileData above,
// except that it simulates a malicious form / POST originator.
IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, MaliciousPostWithFileData) {
  // The initial test window is a named form target.
  GURL initial_target_url(
      embedded_test_server()->GetURL("initial-target.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), initial_target_url));
  WebContents* target_contents = shell()->web_contents();
  EXPECT_TRUE(ExecJs(target_contents, "window.name = 'form-target';"));

  // Create a new window containing a form targeting |target_contents|.
  GURL form_url(embedded_test_server()->GetURL(
      "main.com", "/form_that_posts_cross_site.html"));
  Shell* other_window = OpenPopup(target_contents, form_url, "form-window");
  WebContents* form_contents = other_window->web_contents();
  EXPECT_TRUE(
      ExecJs(form_contents,
             "document.getElementById('file-form').target = 'form-target';"));

  // Verify the current locations and process placement of |target_contents|
  // and |form_contents|.
  EXPECT_EQ(initial_target_url, target_contents->GetLastCommittedURL());
  EXPECT_EQ(form_url, form_contents->GetLastCommittedURL());
  EXPECT_NE(target_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
            form_contents->GetPrimaryMainFrame()->GetProcess()->GetID());

  // Prepare a file to upload.
  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir temp_dir;
  base::FilePath file_path;
  std::string file_content("test-file-content");
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &file_path));
  ASSERT_TRUE(base::WriteFile(file_path, file_content));

  base::RunLoop run_loop;
  // Fill out the form to refer to the test file.
  std::unique_ptr<FileChooserDelegate> delegate(
      new FileChooserDelegate(file_path, run_loop.QuitClosure()));
  form_contents->Focus();
  form_contents->SetDelegate(delegate.get());
  EXPECT_TRUE(
      ExecJs(form_contents, "document.getElementById('file').click();"));
  run_loop.Run();
  ChildProcessSecurityPolicyImpl* security_policy =
      ChildProcessSecurityPolicyImpl::GetInstance();
  EXPECT_TRUE(security_policy->CanReadFile(
      form_contents->GetPrimaryMainFrame()->GetProcess()->GetID(), file_path));

  // Simulate a malicious situation, where the renderer doesn't really have
  // access to the file.
  security_policy->RevokeAllPermissionsForFile(
      form_contents->GetPrimaryMainFrame()->GetProcess()->GetID(), file_path);
  EXPECT_FALSE(security_policy->CanReadFile(
      form_contents->GetPrimaryMainFrame()->GetProcess()->GetID(), file_path));
  EXPECT_FALSE(security_policy->CanReadFile(
      target_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
      file_path));

  // Submit the form and wait until the malicious renderer gets killed.
  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      form_contents->GetPrimaryMainFrame()->GetProcess());
  EXPECT_TRUE(ExecJs(
      form_contents,
      "setTimeout(\n"
      "  function() { document.getElementById('file-form').submit(); },\n"
      "  0);"));
  EXPECT_EQ(bad_message::ILLEGAL_UPLOAD_PARAMS, kill_waiter.Wait());

  // The target frame should still be at the original location - the malicious
  // navigation should have been stopped.
  EXPECT_EQ(initial_target_url, target_contents->GetLastCommittedURL());

  // Both processes still shouldn't have access.
  EXPECT_FALSE(security_policy->CanReadFile(
      form_contents->GetPrimaryMainFrame()->GetProcess()->GetID(), file_path));
  EXPECT_FALSE(security_policy->CanReadFile(
      target_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
      file_path));
}

// Regression test for https://crbug.com/538784 -- ensures that one can't
// sidestep cross-process navigation by detaching a frame mid-request.
IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, NoDeliveryToDetachedFrame) {
  GURL attacker_page = embedded_test_server()->GetURL(
      "evil.com", "/cross_site_iframe_factory.html?evil(evil)");
  EXPECT_TRUE(NavigateToURL(shell(), attacker_page));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  RenderFrameHostImpl* child_frame = root->child_at(0)->current_frame_host();

  // Attacker initiates a navigation to a cross-site document. Under --site-per-
  // process, these bytes must not be sent to the attacker process.
  GURL target_resource =
      embedded_test_server()->GetURL("a.com", "/title1.html");
  TestNavigationManager target_navigation(shell()->web_contents(),
                                          target_resource);
  EXPECT_TRUE(
      ExecJs(shell()->web_contents()->GetPrimaryMainFrame(),
             base::StringPrintf("document.getElementById('child-0').src='%s'",
                                target_resource.spec().c_str())));

  // Wait for the navigation to start.
  EXPECT_TRUE(target_navigation.WaitForRequestStart());
  target_navigation.ResumeNavigation();

  // Call a frame detach. An attacker-controlled renderer could do this without
  // also cancelling the pending navigation (as blink would, if you removed the
  // iframe from the document via js).
  child_frame->DetachForTesting();

  // This should cancel the navigation.
  EXPECT_FALSE(target_navigation.WaitForResponse())
      << "Request should have been cancelled before reaching the renderer.";
}

}  // namespace content
