CVE-2026-87540
Overview
Background
- Isolated Web App (IWA)
- a packaged web application served from an
isolated-app://origin whose pages run in a dedicated, isolated context with elevated capabilities. - Scope extension
- an additional external origin that an IWA declares (via
AddScopeExtension/ a validated origin association) so that origin’s pages are treated as belonging to the app’s scope, distinct from the app’s own primary origin. - `FindBestAppWithUrlInScope`
- a
WebAppRegistrarlookup that, given a URL and aWebAppFilter, returns the app whose scope best matches the URL; it can optionally count or exclude scope extensions when matching. - `NavigationCapturingProcess`
- the browser-side logic that decides how a navigation/window-open is attributed to a web app, including whether an IWA should be treated as the opener of a new tab.
Root Cause Analysis
The changed call site in chrome/browser/ui/web_applications/navigation_capturing_process.cc computed iwa_opener_app_id by calling FindBestAppWithUrlInScope(initiator_origin->GetURL(), WebAppFilter::IsIsolatedApp()) without any option controlling scope-extension matching. Because the default match includes scope extensions, an initiator_origin that merely matched an IWA’s declared scope extension (not the IWA’s own isolated-app:// origin) resolved to that IWA, so a window opened from an ordinary web origin was incorrectly attributed to the IWA as the opener. This violates the invariant that IWA-as-opener attribution should reflect only the IWA itself acting, not any external origin that happens to be inside the app’s extended scope.
The fix passes {.exclude_scope_extensions = true} to the same lookup, so extension origins no longer resolve to the IWA and the attribution is only made when the initiator truly belongs to the app’s own scope. The added browser test NoNotificationForTabOpenedFromScopeExtensionOrigin confirms that opening a tab from a scope-extension origin now emits no IWA notification.
FindBestAppWithUrlInScope with scope-extension matching left enabled when resolving the IWA opener, which let a non-IWA scope-extension origin be authorized as the IWA opener; the fix addresses it by explicitly excluding scope extensions ({.exclude_scope_extensions = true}) from that resolution.Attack Path
- Set up an IWA with a scope extension An IWA is installed that declares a scope extension for an attacker-reachable external origin, so that origin is validated as part of the app’s extended scope.
- Navigate the scope-extension origin outside the IWA
A user (or the attacker’s page) loads the scope-extension origin in a regular browser tab, not inside the IWA itself, as the test does via
NavigateToURLto that origin. - Trigger a window-open from that origin
The scope-extension page initiates a new tab/window (the test uses a renderer-initiated
OpenURLwithinitiator_originset to the scope-extension origin), drivingNavigationCapturingProcessto resolve the IWA opener. - Incorrect opener attribution
FindBestAppWithUrlInScopematches the initiator against the IWA’s scope extension and returns the IWA’siwa_opener_app_id, so the navigation is authorized/attributed as though the IWA opened it even though the IWA never did — evidenced by the pre-fix code emitting the IWA notification the test now asserts must be absent. - Downstream escalation
Any capability or trust granted on the basis of being an IWA opener would then be exposed to the external origin
(inferred); the diff itself only demonstrates the erroneous attribution/notification, not a further primitive.
Impact Assessment
AuthorizationError — “Incorrect authorization in Isolated” — with the precondition that an IWA declaring that scope extension is installed; the diff concretely demonstrates only the misattribution (an unwarranted IWA opener notification). Any privilege or window-management capability an attacker gains from being treated as the IWA opener is (inferred), as the patch does not itself demonstrate escalation beyond the incorrect attribution, and no exploited-in-the-wild status is stated in the advisory.Changed Functions
| Function | Change | Notes |
|---|---|---|
Browserchrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc |
modified | |
IsolatedWebAppsWindowOpenPermissionServiceScopeExtensionBrowserTestchrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc |
modified |
Files Changed
chrome/browser/web_applications/isolated_web_apps/window_management/BUILD.gnchrome/browser/ui/web_applications/navigation_capturing_process.ccchrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc
Audit Directions
- Default scope-extension inclusionAudit every other caller of
FindBestAppWithUrlInScope(and similar scope-lookup APIs) that omitsexclude_scope_extensions, since the permissive default silently treats extension origins as the app for authorization decisions. - Opener/initiator attributionReview code that maps an
initiator_originorsource_site_instanceto an app identity for authorization or notification, ensuring the mapping distinguishes the app’s own origin from externally-controlled scope-extension origins. - Scope-extension trust boundariesLook for places where being “in scope” (including extended scope) is conflated with “being the app,” especially for IWAs where scope extensions bring in origins outside the isolated
isolated-app://origin.
Patch
From 964c5f9e3beddaeb5c1accb7166dc6bc153e9819 Mon Sep 17 00:00:00 2001 From: Magdalena Skarbinska <[email protected]> Date: Mon, 03 Aug 2026 03:25:17 -0700 Subject: [PATCH] [IWA] Fix IWA scope extension check in NavigationCapturingProcess NavigationCapturingProcess::MaybeNotifyIwaTabCounterService previously called FindBestAppWithUrlInScope for the initiator origin without excluding scope extensions. As a result, when a window was opened from an origin matching an IWA's scope extension, the navigation was incorrectly attributed to the IWA as the opener. This change passes {.exclude_scope_extensions = true} to FindBestAppWithUrlInScope in NavigationCapturingProcess so that scope extensions are excluded when resolving whether an IWA is the opener. Adds a browser test NoNotificationForTabOpenedFromScopeExtensionOrigin verifying no notification is emitted when opening a tab from a scope extension origin. Bug: 517721914 Change-Id: I9e3dd945d9452d0a76326e7e50b24785409185f6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8159009 Reviewed-by: Mike Wasserman <[email protected]> Reviewed-by: Andrew Rayskiy <[email protected]> Commit-Queue: Magdalena Skarbińska <[email protected]> Cr-Commit-Position: refs/heads/main@{#1672550} --- diff --git a/chrome/browser/ui/web_applications/navigation_capturing_process.cc b/chrome/browser/ui/web_applications/navigation_capturing_process.cc index a81948d..86341075 100644 --- a/chrome/browser/ui/web_applications/navigation_capturing_process.cc +++ b/chrome/browser/ui/web_applications/navigation_capturing_process.cc @@ -1057,7 +1057,8 @@ } iwa_opener_app_id = provider->registrar_unsafe().FindBestAppWithUrlInScope( - initiator_origin->GetURL(), WebAppFilter::IsIsolatedApp()); + initiator_origin->GetURL(), WebAppFilter::IsIsolatedApp(), + {.exclude_scope_extensions = true}); } // If the "iwa_opener_app_id" is still not found, then there is a chance that diff --git a/chrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc index 06e8e66..2006fbb2 100644 --- a/chrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc +++ b/chrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc @@ -9,6 +9,8 @@ #include <vector> #include "base/i18n/message_formatter.h" +#include "base/json/json_writer.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/simple_test_clock.h" #include "base/test/test_future.h" @@ -26,16 +28,24 @@ #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/test/web_app_test_utils.h" #include "chrome/browser/web_applications/web_app_command_scheduler.h" +#include "chrome/browser/web_applications/web_app_origin_association_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "components/webapps/common/web_app_id.h" #include "components/webapps/isolated_web_apps/test_support/signing_keys.h" +#include "components/webapps/services/web_app_origin_association/test/test_web_app_origin_association_fetcher.h" +#include "content/public/browser/page_navigator.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #include "ui/base/l10n/l10n_util.h" +#include "url/origin.h" class Browser; @@ -502,4 +512,97 @@ GURL("https://example.com/child1")); EXPECT_EQ(0u, GetNotificationCount()); } + +class IsolatedWebAppsWindowOpenPermissionServiceScopeExtensionBrowserTest + : public IsolatedWebAppsWindowOpenPermissionServiceBrowserTest { + public: + void SetUpOnMainThread() override { + IsolatedWebAppsWindowOpenPermissionServiceBrowserTest::SetUpOnMainThread(); + + auto fetcher = + std::make_unique<webapps::TestWebAppOriginAssociationFetcher>(); + origin_association_fetcher_ = fetcher.get(); + provider().origin_association_manager().SetFetcherForTest( + std::move(fetcher)); + } + + void TearDownOnMainThread() override { + origin_association_fetcher_ = nullptr; + IsolatedWebAppsWindowOpenPermissionServiceBrowserTest:: + TearDownOnMainThread(); + } + + protected: + webapps::AppId InstallIsolatedWebAppWithScopeExtension( + const url::Origin& scope_extension_origin) { + origin_association_fetcher_->SetData( + {{scope_extension_origin, + *base::WriteJson(base::DictValue().Set( + base::StringPrintf( + "isolated-app://%s/", + web_package::test::GetDefaultEd25519WebBundleId() + .id() + .c_str()), + base::DictValue().Set("scope", "/")))}}); + + webapps::AppId app_id = + IsolatedWebAppBuilder( + ManifestBuilder() + .SetName(kIsolatedApp1DefaultName) + .SetVersion(kIsolatedAppVersion) + .AddScopeExtension(scope_extension_origin, + /*has_origin_wildcard=*/false)) + .BuildBundle(web_package::test::GetDefaultEd25519KeyPair()) + ->InstallChecked(profile()) + .app_id(); + EXPECT_EQ(1u, provider() + .registrar_unsafe() + .GetValidatedScopeExtensions(app_id) + .size()); + return app_id; + } + + private: + raw_ptr<webapps::TestWebAppOriginAssociationFetcher> + origin_association_fetcher_ = nullptr; +}; + +IN_PROC_BROWSER_TEST_F( + IsolatedWebAppsWindowOpenPermissionServiceScopeExtensionBrowserTest, + NoNotificationForTabOpenedFromScopeExtensionOrigin) { + url::Origin scope_extension_origin = embedded_https_test_server().GetOrigin(); + webapps::AppId app_id = + InstallIsolatedWebAppWithScopeExtension(scope_extension_origin); + + // Open the scope-extension origin in a regular browser tab (not in the IWA). + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_https_test_server().GetURL("/simple.html"))); + content::WebContents* opener_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_EQ(scope_extension_origin, + opener_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin()); + + // Open a new background tab from the scope-extension page, as the renderer + // does for e.g. a middle-click on a link. + content::OpenURLParams params( + GURL("https://example.com/destination"), content::Referrer(), + WindowOpenDisposition::NEW_BACKGROUND_TAB, ui::PAGE_TRANSITION_LINK, + /*is_renderer_initiated=*/true); + params.initiator_origin = scope_extension_origin; + params.source_site_instance = + opener_contents->GetPrimaryMainFrame()->GetSiteInstance(); + params.user_gesture = true; + + content::WebContentsAddedObserver new_contents_observer; + opener_contents->OpenURL(params, /*navigation_handle_callback=*/{}); + content::WebContents* new_contents = new_contents_observer.GetWebContents(); + WaitForLoadStopWithoutSuccessCheck(new_contents); + + // The IWA itself never opened a window, so it must not be attributed as the + // opener. + EXPECT_EQ(0u, GetNotificationCount()); + EXPECT_FALSE( + display_service_tester_->GetNotification(GetNotificationIdForApp(app_id)) + .has_value()); +} } // namespace web_app diff --git a/chrome/browser/web_applications/isolated_web_apps/window_management/BUILD.gn b/chrome/browser/web_applications/isolated_web_apps/window_management/BUILD.gn index 09931fe0..b5841ccf 100644 --- a/chrome/browser/web_applications/isolated_web_apps/window_management/BUILD.gn +++ b/chrome/browser/web_applications/isolated_web_apps/window_management/BUILD.gn @@ -68,6 +68,7 @@ "//components/permissions", "//components/webapps/common", "//components/webapps/isolated_web_apps/test_support", + "//components/webapps/services/web_app_origin_association/test:test_support", "//content/public/browser", "//content/test:test_support", "//ui/base",
Regression Test / PoC
diff --git a/chrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc
index 06e8e66..2006fbb2 100644
--- a/chrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service_browsertest.cc
@@ -9,6 +9,8 @@
#include <vector>
#include "base/i18n/message_formatter.h"
+#include "base/json/json_writer.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/simple_test_clock.h"
#include "base/test/test_future.h"
@@ -26,16 +28,24 @@
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_test_utils.h"
#include "chrome/browser/web_applications/web_app_command_scheduler.h"
+#include "chrome/browser/web_applications/web_app_origin_association_manager.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
#include "components/webapps/common/web_app_id.h"
#include "components/webapps/isolated_web_apps/test_support/signing_keys.h"
+#include "components/webapps/services/web_app_origin_association/test/test_web_app_origin_association_fetcher.h"
+#include "content/public/browser/page_navigator.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "ui/base/l10n/l10n_util.h"
+#include "url/origin.h"
class Browser;
@@ -502,4 +512,97 @@
GURL("https://example.com/child1"));
EXPECT_EQ(0u, GetNotificationCount());
}
+
+class IsolatedWebAppsWindowOpenPermissionServiceScopeExtensionBrowserTest
+ : public IsolatedWebAppsWindowOpenPermissionServiceBrowserTest {
+ public:
+ void SetUpOnMainThread() override {
+ IsolatedWebAppsWindowOpenPermissionServiceBrowserTest::SetUpOnMainThread();
+
+ auto fetcher =
+ std::make_unique<webapps::TestWebAppOriginAssociationFetcher>();
+ origin_association_fetcher_ = fetcher.get();
+ provider().origin_association_manager().SetFetcherForTest(
+ std::move(fetcher));
+ }
+
+ void TearDownOnMainThread() override {
+ origin_association_fetcher_ = nullptr;
+ IsolatedWebAppsWindowOpenPermissionServiceBrowserTest::
+ TearDownOnMainThread();
+ }
+
+ protected:
+ webapps::AppId InstallIsolatedWebAppWithScopeExtension(
+ const url::Origin& scope_extension_origin) {
+ origin_association_fetcher_->SetData(
+ {{scope_extension_origin,
+ *base::WriteJson(base::DictValue().Set(
+ base::StringPrintf(
+ "isolated-app://%s/",
+ web_package::test::GetDefaultEd25519WebBundleId()
+ .id()
+ .c_str()),
+ base::DictValue().Set("scope", "/")))}});
+
+ webapps::AppId app_id =
+ IsolatedWebAppBuilder(
+ ManifestBuilder()
+ .SetName(kIsolatedApp1DefaultName)
+ .SetVersion(kIsolatedAppVersion)
+ .AddScopeExtension(scope_extension_origin,
+ /*has_origin_wildcard=*/false))
+ .BuildBundle(web_package::test::GetDefaultEd25519KeyPair())
+ ->InstallChecked(profile())
+ .app_id();
+ EXPECT_EQ(1u, provider()
+ .registrar_unsafe()
+ .GetValidatedScopeExtensions(app_id)
+ .size());
+ return app_id;
+ }
+
+ private:
+ raw_ptr<webapps::TestWebAppOriginAssociationFetcher>
+ origin_association_fetcher_ = nullptr;
+};
+
+IN_PROC_BROWSER_TEST_F(
+ IsolatedWebAppsWindowOpenPermissionServiceScopeExtensionBrowserTest,
+ NoNotificationForTabOpenedFromScopeExtensionOrigin) {
+ url::Origin scope_extension_origin = embedded_https_test_server().GetOrigin();
+ webapps::AppId app_id =
+ InstallIsolatedWebAppWithScopeExtension(scope_extension_origin);
+
+ // Open the scope-extension origin in a regular browser tab (not in the IWA).
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(
+ browser(), embedded_https_test_server().GetURL("/simple.html")));
+ content::WebContents* opener_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+ ASSERT_EQ(scope_extension_origin,
+ opener_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+
+ // Open a new background tab from the scope-extension page, as the renderer
+ // does for e.g. a middle-click on a link.
+ content::OpenURLParams params(
+ GURL("https://example.com/destination"), content::Referrer(),
+ WindowOpenDisposition::NEW_BACKGROUND_TAB, ui::PAGE_TRANSITION_LINK,
+ /*is_renderer_initiated=*/true);
+ params.initiator_origin = scope_extension_origin;
+ params.source_site_instance =
+ opener_contents->GetPrimaryMainFrame()->GetSiteInstance();
+ params.user_gesture = true;
+
+ content::WebContentsAddedObserver new_contents_observer;
+ opener_contents->OpenURL(params, /*navigation_handle_callback=*/{});
+ content::WebContents* new_contents = new_contents_observer.GetWebContents();
+ WaitForLoadStopWithoutSuccessCheck(new_contents);
+
+ // The IWA itself never opened a window, so it must not be attributed as the
+ // opener.
+ EXPECT_EQ(0u, GetNotificationCount());
+ EXPECT_FALSE(
+ display_service_tester_->GetNotification(GetNotificationIdForApp(app_id))
+ .has_value());
+}
} // namespace web_app
Original Bug Report
Potential IWA warning quota exhaustion via initiator fallback scope extension mismatch
Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: In NavigationCapturingProcess::MaybeNotifyIwaTabCounterService, resolving an IWA opener via the initiator-origin fallback fails to exclude scope extensions. As a result, an ordinary HTTPS origin listed in an IWA’s validated scope extensions can falsely match as the IWA itself. This allows a regular website to trigger misleading system notifications and exhaust the safety warning quota for the associated IWA.
Affected files:
chrome/browser/ui/web_applications/navigation_capturing_process.ccchrome/browser/web_applications/isolated_web_apps/window_management/isolated_web_apps_window_open_permission_service.cc
Estimated timestamp from git blame: 2025-10-30
Potential Security Mitigation Bypass and UI Spoofing in IWA Tab Counter Service
Root Cause Analysis
In NavigationCapturingProcess::MaybeNotifyIwaTabCounterService (chrome/browser/ui/web_applications/navigation_capturing_process.cc), the potential IWA opener is resolved via an initiator-origin fallback when an opener-chain app ID is not present:
// chrome/browser/ui/web_applications/navigation_capturing_process.cc
if (!iwa_opener_app_id) {
if (!navigation_handle) {
return;
}
const auto& initiator_origin = navigation_handle->GetInitiatorOrigin();
if (!initiator_origin) {
return;
}
iwa_opener_app_id = provider->registrar_unsafe().FindBestAppWithUrlInScope(
initiator_origin->GetURL(), WebAppFilter::IsIsolatedApp());
}
However, the call to FindBestAppWithUrlInScope uses the 2-argument overload (defined in chrome/browser/web_applications/web_app_registrar.h), which defaults scope_score_options to {}. Consequently, exclude_scope_extensions is false during the scope resolution.
This causes GetScopeScore to walk the target app’s validated_scope_extensions. If a regular HTTPS origin (e.g., https://ext.example) is listed in a user-installed Isolated Web App’s (IWA) validated_scope_extensions, the IWA wins the scope match. Since the post-match check only tests the resolved app’s isolation properties rather than the initiator’s scheme, the initiator is incorrectly treated as the IWA.
This is an anti-pattern that has previously been fixed at other security-sensitive sites, such as:
DeviceServiceImpl::IsTrustedContext(chrome/browser/device_api/device_service_impl.cc:112)WebAppTabHelper::FindAppIdForUrl(chrome/browser/web_applications/web_app_tab_helper.cc:60)
In both cases, {.exclude_scope_extensions = true} is explicitly passed to ensure regular HTTPS origins in scope extensions cannot pretend to be the trusted IWA.
Potential Trigger Path
Note: These are potential steps for a proof of concept; our tooling agent does not have the ability to run code.
- A user-installed IWA (matching
IsIsolatedWebAppWithOnlyUserManagement) declareshttps://ext.examplein itsscope_extensions, and the origin has opted in via.well-known/web-app-origin-association(successfully registered invalidated_scope_extensions). - The user has
https://ext.exampleopen in an ordinary browser tab and clicks an<a target="_blank" rel="noopener">link or executeswindow.openwithout keeping an opener reference. - This is routed to
MaybeNotifyIwaTabCounterServicewith the initiator origin set tohttps://ext.examplebut no live opener chain. - The initiator-origin fallback invokes
FindBestAppWithUrlInScopewithout excluding scope extensions, potentially resolvingiwa_opener_app_idto the IWA. IsolatedWebAppsWindowOpenPermissionService::OnWebContentsCreatedis notified with this App ID.
Potential Impact
An HTTPS origin listed in an IWA’s scope_extensions can potentially cause the following security issues:
- False Attribution UI Notification: It triggers a trusted ChromeOS system notification ("
<IWA name>is opening tabs") with a settings button pointing to the IWA’s popup-permission page. This presents a trusted UI misattribution/spoofing vector. - Safety Warning Quota Exhaustion: It silently increments and persists the IWA’s
opened_tabs_counter_notification_state().times_shownup tokMaxNotificationShowCount = 3in the WebApp database. Once this safety quota is exhausted, the user is never again warned when the IWA itself actually spawns many tabs or windows in the future, effectively bypassing a built-in safety boundary.
Suggested Fix
Update the fallback logic in NavigationCapturingProcess::MaybeNotifyIwaTabCounterService to explicitly exclude scope extensions during resolution:
iwa_opener_app_id = provider->registrar_unsafe().FindBestAppWithUrlInScope(
initiator_origin->GetURL(), WebAppFilter::IsIsolatedApp(),
{.exclude_scope_extensions = true});
Evaluated with Chrome root at commit: 5133b93d189b383c37805b1cf3a9d2dbfe8d7379
Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:
- If you are familiar with the severity guidelines, you may adjust the severity.
- If this is a false positive, and there’s no work to be done, please close as WAI.
- If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.
Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.