diff --git third_party/crashpad/crashpad/client/prune_crash_reports.cc third_party/crashpad/crashpad/client/prune_crash_reports.cc
index 077694f541d57..928a520485414 100644
--- third_party/crashpad/crashpad/client/prune_crash_reports.cc
+++ third_party/crashpad/crashpad/client/prune_crash_reports.cc
@@ -75,13 +75,19 @@ size_t PruneCrashReportDatabase(CrashReportDatabase* database,
 }
 
 // static
-std::unique_ptr<PruneCondition> PruneCondition::GetDefault() {
+std::unique_ptr<PruneCondition> PruneCondition::GetDefault(
+    int max_size_in_mb,
+    int max_age_in_days) {
   // DatabaseSizePruneCondition must be the LHS so that it is always evaluated,
   // due to the short-circuting behavior of BinaryPruneCondition.
+  if (max_size_in_mb <= 0)
+    max_size_in_mb = 128;
+  if (max_age_in_days <= 0)
+    max_age_in_days = 365;
   return std::make_unique<BinaryPruneCondition>(
       BinaryPruneCondition::OR,
-      new DatabaseSizePruneCondition(1024 * 128),
-      new AgePruneCondition(365));
+      new DatabaseSizePruneCondition(1024 * max_size_in_mb),
+      new AgePruneCondition(max_age_in_days));
 }
 
 static const time_t kSecondsInDay = 60 * 60 * 24;
diff --git third_party/crashpad/crashpad/client/prune_crash_reports.h third_party/crashpad/crashpad/client/prune_crash_reports.h
index b362e0aadbadd..1588232a6e4d4 100644
--- third_party/crashpad/crashpad/client/prune_crash_reports.h
+++ third_party/crashpad/crashpad/client/prune_crash_reports.h
@@ -58,7 +58,8 @@ class PruneCondition {
   //! of 128 MB.
   //!
   //! \return A PruneCondition for use with PruneCrashReportDatabase().
-  static std::unique_ptr<PruneCondition> GetDefault();
+  static std::unique_ptr<PruneCondition> GetDefault(int max_size_in_mb,
+                                                    int max_age_in_days);
 
   virtual ~PruneCondition() {}
 
diff --git third_party/crashpad/crashpad/client/settings.cc third_party/crashpad/crashpad/client/settings.cc
index 68fae16afc4ec..e3004425e13cb 100644
--- third_party/crashpad/crashpad/client/settings.cc
+++ third_party/crashpad/crashpad/client/settings.cc
@@ -116,7 +116,7 @@ void ScopedLockedFileHandleTraits::Free(FileHandle handle) {
 
 struct Settings::Data {
   static constexpr uint32_t kSettingsMagic = 'CPds';
-  static constexpr uint32_t kSettingsVersion = 1;
+  static constexpr uint32_t kSettingsVersion = 2;
 
   enum Options : uint32_t {
     kUploadsEnabled = 1 << 0,
@@ -127,6 +127,9 @@ struct Settings::Data {
            options(0),
            padding_0(0),
            last_upload_attempt_time(0),
+           next_upload_attempt_time(0),
+           backoff_step(0),
+           padding_1(0),
            client_id() {}
 
   uint32_t magic;
@@ -134,6 +137,9 @@ struct Settings::Data {
   uint32_t options;
   uint32_t padding_0;
   int64_t last_upload_attempt_time;  // time_t
+  int64_t next_upload_attempt_time;  // time_t
+  uint32_t backoff_step;
+  uint32_t padding_1;
   UUID client_id;
 };
 
@@ -217,6 +223,56 @@ bool Settings::SetLastUploadAttemptTime(time_t time) {
   return WriteSettings(handle.get(), settings);
 }
 
+bool Settings::GetNextUploadAttemptTime(time_t* time) {
+  DCHECK(initialized_.is_valid());
+
+  Data settings;
+  if (!OpenAndReadSettings(&settings))
+    return false;
+
+  *time = InRangeCast<time_t>(settings.next_upload_attempt_time,
+                              std::numeric_limits<time_t>::max());
+  return true;
+}
+
+bool Settings::SetNextUploadAttemptTime(time_t time) {
+  DCHECK(initialized_.is_valid());
+
+  Data settings;
+  ScopedLockedFileHandle handle = OpenForWritingAndReadSettings(&settings);
+  if (!handle.is_valid())
+    return false;
+
+  settings.next_upload_attempt_time = InRangeCast<int64_t>(time, 0);
+
+  return WriteSettings(handle.get(), settings);
+}
+
+bool Settings::GetBackoffStep(int* step) {
+  DCHECK(initialized_.is_valid());
+
+  Data settings;
+  if (!OpenAndReadSettings(&settings))
+    return false;
+
+  *step = InRangeCast<int>(settings.backoff_step,
+                           std::numeric_limits<int>::max());
+  return true;
+}
+
+bool Settings::SetBackoffStep(int step) {
+  DCHECK(initialized_.is_valid());
+
+  Data settings;
+  ScopedLockedFileHandle handle = OpenForWritingAndReadSettings(&settings);
+  if (!handle.is_valid())
+    return false;
+
+  settings.backoff_step = InRangeCast<uint32_t>(step, 0);
+
+  return WriteSettings(handle.get(), settings);
+}
+
 // static
 Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle(
     FileHandle file,
diff --git third_party/crashpad/crashpad/client/settings.h third_party/crashpad/crashpad/client/settings.h
index 2b27474a683e9..7b5a89cea7f74 100644
--- third_party/crashpad/crashpad/client/settings.h
+++ third_party/crashpad/crashpad/client/settings.h
@@ -128,6 +128,11 @@ class Settings {
   //!     error logged.
   bool SetLastUploadAttemptTime(time_t time);
 
+  bool GetNextUploadAttemptTime(time_t* time);
+  bool SetNextUploadAttemptTime(time_t time);
+  bool GetBackoffStep(int* step);
+  bool SetBackoffStep(int step);
+
  private:
   struct Data;
 
diff --git third_party/crashpad/crashpad/handler/BUILD.gn third_party/crashpad/crashpad/handler/BUILD.gn
index e5d488e26c170..08d7c35b7cc5c 100644
--- third_party/crashpad/crashpad/handler/BUILD.gn
+++ third_party/crashpad/crashpad/handler/BUILD.gn
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("//cef/libcef/features/features.gni")
 import("../build/crashpad_buildconfig.gni")
 
 static_library("handler") {
@@ -58,6 +59,17 @@ static_library("handler") {
     ]
   }
 
+  if (enable_cef) {
+    sources += [
+      "//cef/libcef/common/cef_crash_report_upload_thread.cc",
+      "//cef/libcef/common/cef_crash_report_upload_thread.h",
+      "//cef/libcef/common/cef_crash_report_utils.cc",
+      "//cef/libcef/common/cef_crash_report_utils.h",
+    ]
+
+    configs += [ "//cef/libcef/features:config" ]
+  }
+
   public_configs = [ "..:crashpad_config" ]
 
   public_deps = [
@@ -73,6 +85,7 @@ static_library("handler") {
     "../snapshot",
     "../third_party/mini_chromium:chromeos_buildflags",
     "../tools:tool_support",
+    "//cef/libcef/features",
   ]
 
   if (crashpad_is_win) {
diff --git third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc
index 5bd2889eda975..bf3ff4bfcf5c8 100644
--- third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc
+++ third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc
@@ -297,6 +297,8 @@ CrashReportUploadThread::UploadResult CrashReportUploadThread::UploadReport(
   if (minidump_process_snapshot.Initialize(reader)) {
     parameters =
         BreakpadHTTPFormParametersFromMinidump(&minidump_process_snapshot);
+    if (!parameters.empty())
+      parameters = FilterParameters(parameters);
   }
 
   if (!reader->SeekSet(start_offset)) {
diff --git third_party/crashpad/crashpad/handler/crash_report_upload_thread.h third_party/crashpad/crashpad/handler/crash_report_upload_thread.h
index 22bb26e31893b..87c80604e5f7a 100644
--- third_party/crashpad/crashpad/handler/crash_report_upload_thread.h
+++ third_party/crashpad/crashpad/handler/crash_report_upload_thread.h
@@ -16,6 +16,7 @@
 #define CRASHPAD_HANDLER_CRASH_REPORT_UPLOAD_THREAD_H_
 
 #include <functional>
+#include <map>
 #include <memory>
 #include <string>
 #include <unordered_map>
@@ -128,7 +129,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate,
   //! \return `true` if the thread is running, `false` if it is not.
   bool is_running() const { return thread_.is_running(); }
 
- private:
+ protected:
   //! \brief The result code from UploadReport().
   enum class UploadResult {
     //! \brief The crash report was uploaded successfully.
@@ -156,7 +157,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate,
   //! object was constructed with \a watch_pending_reports, it will also scan
   //! the crash report database for other pending reports, and process those as
   //! well.
-  void ProcessPendingReports();
+  virtual void ProcessPendingReports();
 
   //! \brief Processes a single pending report from the database.
   //!
@@ -170,7 +171,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate,
   //! remain in the “pending” state. If the upload fails and no more retries are
   //! desired, or report upload is disabled, it will be marked as “completed” in
   //! the database without ever having been uploaded.
-  void ProcessPendingReport(const CrashReportDatabase::Report& report);
+  virtual void ProcessPendingReport(const CrashReportDatabase::Report& report);
 
   //! \brief Attempts to upload a crash report.
   //!
@@ -187,6 +188,11 @@ class CrashReportUploadThread : public WorkerThread::Delegate,
   UploadResult UploadReport(const CrashReportDatabase::UploadReport* report,
                             std::string* response_body);
 
+  using ParameterMap = std::map<std::string, std::string>;
+  virtual ParameterMap FilterParameters(const ParameterMap& parameters) {
+    return parameters;
+  }
+
   // WorkerThread::Delegate:
   //! \brief Calls ProcessPendingReports() in response to ReportPending() having
   //!     been called on any thread, as well as periodically on a timer.
diff --git third_party/crashpad/crashpad/handler/handler_main.cc third_party/crashpad/crashpad/handler/handler_main.cc
index b7ba6b14bb9b3..0567343c99325 100644
--- third_party/crashpad/crashpad/handler/handler_main.cc
+++ third_party/crashpad/crashpad/handler/handler_main.cc
@@ -39,6 +39,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "cef/libcef/features/features.h"
 #include "client/crash_report_database.h"
 #include "client/crashpad_client.h"
 #include "client/crashpad_info.h"
@@ -89,6 +90,10 @@
 #include "util/win/session_end_watcher.h"
 #endif  // BUILDFLAG(IS_APPLE)
 
+#if BUILDFLAG(ENABLE_CEF)
+#include "cef/libcef/common/cef_crash_report_upload_thread.h"
+#endif
+
 namespace crashpad {
 
 namespace {
@@ -248,6 +253,9 @@ struct Options {
   bool periodic_tasks;
   bool rate_limit;
   bool upload_gzip;
+  int max_uploads;
+  int max_database_size;
+  int max_database_age;
 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
   bool use_cros_crash_reporter = false;
   base::FilePath minidump_dir_for_tests;
@@ -622,6 +630,9 @@ int HandlerMain(int argc,
     kOptionTraceParentWithException,
 #endif
     kOptionURL,
+    kOptionMaxUploads,
+    kOptionMaxDatabaseSize,
+    kOptionMaxDatabaseAge,
 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
     kOptionUseCrosCrashReporter,
     kOptionMinidumpDirForTests,
@@ -722,6 +733,9 @@ int HandlerMain(int argc,
 #endif  // BUILDFLAG(IS_ANDROID)
     {"help", no_argument, nullptr, kOptionHelp},
     {"version", no_argument, nullptr, kOptionVersion},
+    {"max-uploads", required_argument, nullptr, kOptionMaxUploads},
+    {"max-db-size", required_argument, nullptr, kOptionMaxDatabaseSize},
+    {"max-db-age", required_argument, nullptr, kOptionMaxDatabaseAge},
     {nullptr, 0, nullptr, 0},
   };
 
@@ -879,6 +893,27 @@ int HandlerMain(int argc,
         options.url = optarg;
         break;
       }
+      case kOptionMaxUploads: {
+        if (base::StringToInt(optarg, &options.max_uploads)) {
+          if (options.max_uploads < 0)
+            options.max_uploads = 0;
+        }
+        break;
+      }
+      case kOptionMaxDatabaseSize: {
+        if (base::StringToInt(optarg, &options.max_database_size)) {
+          if (options.max_database_size < 0)
+            options.max_database_size = 0;
+        }
+        break;
+      }
+      case kOptionMaxDatabaseAge: {
+        if (base::StringToInt(optarg, &options.max_database_age)) {
+          if (options.max_database_age < 0)
+            options.max_database_age = 0;
+        }
+        break;
+      }
 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
       case kOptionUseCrosCrashReporter: {
         options.use_cros_crash_reporter = true;
@@ -1028,11 +1063,20 @@ int HandlerMain(int argc,
     upload_thread_options.upload_gzip = options.upload_gzip;
     upload_thread_options.watch_pending_reports = options.periodic_tasks;
 
+#if BUILDFLAG(ENABLE_CEF)
+    upload_thread.Reset(new CefCrashReportUploadThread(
+        database.get(),
+        options.url,
+        upload_thread_options,
+        CrashReportUploadThread::ProcessPendingReportsObservationCallback(),
+        options.max_uploads));
+#else
     upload_thread.Reset(new CrashReportUploadThread(
         database.get(),
         options.url,
         upload_thread_options,
         CrashReportUploadThread::ProcessPendingReportsObservationCallback()));
+#endif
     upload_thread.Get()->Start();
   }
 
@@ -1103,7 +1147,8 @@ int HandlerMain(int argc,
   ScopedStoppable prune_thread;
   if (options.periodic_tasks) {
     prune_thread.Reset(new PruneCrashReportThread(
-        database.get(), PruneCondition::GetDefault()));
+        database.get(), PruneCondition::GetDefault(options.max_database_size,
+                                                   options.max_database_age)));
     prune_thread.Get()->Start();
   }