Chrome · WebAppInstalls
CVE-2026-14131
Logic Error in WebAppInstalls
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
forchrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job.cc |
modified | |
TEST_Fchrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc |
modified |
Files Changed
chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.ccchrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job.ccchrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc
Patch
From 83acaeae804d4ad86a71a6e5e786cdd51c327951 Mon Sep 17 00:00:00 2001 From: Edman Anjos <[email protected]> Date: Mon, 01 Jun 2026 10:56:39 -0700 Subject: [PATCH] Ignore unframed display override in install job when the flag is disabled Fixed: 514020982 Test: testing/xvfb.py tools/autotest.py -C out_/Default chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.cc Change-Id: I86539fe197f2ffb7d9e4fb991190b88ad73ab90a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7867923 Reviewed-by: Eshwar Stalin <[email protected]> Commit-Queue: Edman Anjos <[email protected]> Cr-Commit-Position: refs/heads/main@{#1639520} --- diff --git a/chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.cc index 4fbb5184..5fb9b5c 100644 --- a/chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.cc +++ b/chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.cc @@ -3,10 +3,13 @@ // found in the LICENSE file. #include <memory> +#include <optional> #include <string_view> #include <vector> +#include "base/auto_reset.h" #include "base/check_deref.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/time/time.h" #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h" @@ -32,6 +35,7 @@ #include "components/webapps/isolated_web_apps/types/update_channel.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/safe_url_pattern.h" #include "third_party/liburlpattern/part.h" @@ -100,6 +104,7 @@ public: ManifestUpdateTest() : IsolatedWebAppTest(base::test::TaskEnvironment::TimeSource::MOCK_TIME) { + scoped_feature_list_.InitAndEnableFeature(blink::features::kUnframedIwa); } ~ManifestUpdateTest() override = default; @@ -162,6 +167,7 @@ ASSERT_THAT(TestIwa(), HasVersion("2.0.0")); } + base::test::ScopedFeatureList scoped_feature_list_; FakeIwaRuntimeDataProvider data_provider_; std::optional<base::AutoReset<ChromeIwaRuntimeDataProvider*>> resetter_; }; diff --git a/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job.cc b/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job.cc index 1e64842..5744abc0 100644 --- a/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job.cc +++ b/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job.cc @@ -813,10 +813,15 @@ install_info().display_mode = manifest_->display; } for (const auto& override_item : manifest_->display_override) { - install_info().display_override.push_back( - override_item.display() == DisplayMode::kUnframed - ? DisplayOverride::CreateUnframed(override_item.url_patterns()) - : DisplayOverride::Create(override_item.display())); + if (override_item.display() == DisplayMode::kUnframed) { + if (base::FeatureList::IsEnabled(blink::features::kUnframedIwa)) { + install_info().display_override.push_back( + DisplayOverride::CreateUnframed(override_item.url_patterns())); + } + } else { + install_info().display_override.push_back( + DisplayOverride::Create(override_item.display())); + } } const std::vector<blink::Manifest::ImageResource>& icons = diff --git a/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc b/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc index b0c0cce..fef5eb6 100644 --- a/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc +++ b/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc @@ -12,6 +12,7 @@ #include <utility> #include <vector> +#include "base/feature_list.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" @@ -167,7 +168,8 @@ TEST_F(ManifestToWebAppInstallInfoJobTest, BasicFieldsPopulated) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures({blink::features::kFileHandlingIcons, - blink::features::kWebAppManifestLockScreen}, + blink::features::kWebAppManifestLockScreen, + blink::features::kUnframedIwa}, /*disabled_features=*/{}); SetupBasicPageState(); @@ -2213,6 +2215,37 @@ EXPECT_EQ(default_icon_url, icons[0].url); } +TEST_F(ManifestToWebAppInstallInfoJobTest, + AcceptsUnframedDisplayOverrideWhenTheFeatureIsEnabled) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(blink::features::kUnframedIwa); + + ASSERT_TRUE(base::FeatureList::IsEnabled(blink::features::kUnframedIwa)); + + SetupBasicPageState(); + blink::mojom::ManifestPtr& manifest = GetPageManifest(); + manifest->display_override.push_back( + blink::Manifest::DisplayOverride::CreateUnframed({FooUrlPattern()})); + + auto web_app_info = GetWebAppInstallInfoFromJob(*manifest); + EXPECT_THAT( + web_app_info->display_override, + testing::ElementsAre(DisplayOverride::CreateUnframed({FooUrlPattern()}))); +} + +TEST_F(ManifestToWebAppInstallInfoJobTest, + IgnoresUnframedDisplayOverrideWhenTheFeatureIsDisabled) { + ASSERT_FALSE(base::FeatureList::IsEnabled(blink::features::kUnframedIwa)); + + SetupBasicPageState(); + blink::mojom::ManifestPtr& manifest = GetPageManifest(); + manifest->display_override.push_back( + blink::Manifest::DisplayOverride::CreateUnframed()); + + auto web_app_info = GetWebAppInstallInfoFromJob(*manifest); + EXPECT_THAT(web_app_info->display_override, testing::IsEmpty()); +} + } // namespace } // namespace web_app
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.cc
index 4fbb5184..5fb9b5c 100644
--- a/chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/manifest_update_unittest.cc
@@ -3,10 +3,13 @@
// found in the LICENSE file.
#include <memory>
+#include <optional>
#include <string_view>
#include <vector>
+#include "base/auto_reset.h"
#include "base/check_deref.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
@@ -32,6 +35,7 @@
#include "components/webapps/isolated_web_apps/types/update_channel.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/safe_url_pattern.h"
#include "third_party/liburlpattern/part.h"
@@ -100,6 +104,7 @@
public:
ManifestUpdateTest()
: IsolatedWebAppTest(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
+ scoped_feature_list_.InitAndEnableFeature(blink::features::kUnframedIwa);
}
~ManifestUpdateTest() override = default;
@@ -162,6 +167,7 @@
ASSERT_THAT(TestIwa(), HasVersion("2.0.0"));
}
+ base::test::ScopedFeatureList scoped_feature_list_;
FakeIwaRuntimeDataProvider data_provider_;
std::optional<base::AutoReset<ChromeIwaRuntimeDataProvider*>> resetter_;
};
diff --git a/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc b/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc
index b0c0cce..fef5eb6 100644
--- a/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc
+++ b/chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job_unittest.cc
@@ -12,6 +12,7 @@
#include <utility>
#include <vector>
+#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
@@ -167,7 +168,8 @@
TEST_F(ManifestToWebAppInstallInfoJobTest, BasicFieldsPopulated) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures({blink::features::kFileHandlingIcons,
- blink::features::kWebAppManifestLockScreen},
+ blink::features::kWebAppManifestLockScreen,
+ blink::features::kUnframedIwa},
/*disabled_features=*/{});
SetupBasicPageState();
@@ -2213,6 +2215,37 @@
EXPECT_EQ(default_icon_url, icons[0].url);
}
+TEST_F(ManifestToWebAppInstallInfoJobTest,
+ AcceptsUnframedDisplayOverrideWhenTheFeatureIsEnabled) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(blink::features::kUnframedIwa);
+
+ ASSERT_TRUE(base::FeatureList::IsEnabled(blink::features::kUnframedIwa));
+
+ SetupBasicPageState();
+ blink::mojom::ManifestPtr& manifest = GetPageManifest();
+ manifest->display_override.push_back(
+ blink::Manifest::DisplayOverride::CreateUnframed({FooUrlPattern()}));
+
+ auto web_app_info = GetWebAppInstallInfoFromJob(*manifest);
+ EXPECT_THAT(
+ web_app_info->display_override,
+ testing::ElementsAre(DisplayOverride::CreateUnframed({FooUrlPattern()})));
+}
+
+TEST_F(ManifestToWebAppInstallInfoJobTest,
+ IgnoresUnframedDisplayOverrideWhenTheFeatureIsDisabled) {
+ ASSERT_FALSE(base::FeatureList::IsEnabled(blink::features::kUnframedIwa));
+
+ SetupBasicPageState();
+ blink::mojom::ManifestPtr& manifest = GetPageManifest();
+ manifest->display_override.push_back(
+ blink::Manifest::DisplayOverride::CreateUnframed());
+
+ auto web_app_info = GetWebAppInstallInfoFromJob(*manifest);
+ EXPECT_THAT(web_app_info->display_override, testing::IsEmpty());
+}
+
} // namespace
} // namespace web_app
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page