CVE-2026-11011
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
MockPasswordManagerClientcomponents/password_manager/core/browser/password_form_filling_unittest.cc |
modified | |
TEST_Fcomponents/password_manager/core/browser/password_form_filling_unittest.cc |
modified | |
MockPasswordManagerClientcomponents/password_manager/core/browser/password_form_manager_unittest.cc |
modified |
Files Changed
chrome/browser/password_manager/actor_login/internal/actor_login_delegate_impl_unittest.cccomponents/password_manager/content/browser/content_password_manager_driver.cccomponents/password_manager/core/browser/password_form_filling.cccomponents/password_manager/core/browser/password_form_filling_unittest.cccomponents/password_manager/core/browser/password_form_manager_unittest.cc
Patch
From b17a351979abda6234f005fdccedd91d88929394 Mon Sep 17 00:00:00 2001
From: Vasilii Sukhanov <vasilii@chromium.org>
Date: Wed, 08 Apr 2026 13:05:52 -0700
Subject: [PATCH] Fix potential CPSP bypass in PasswordManager
Enforce ChildProcessSecurityPolicy in HasValidURL and strengthen origin
checks in password_form_filling.cc by comparing main frame origin with
driver origin.
Fixed: 496702621
Change-Id: Ie1932943ab234a8896a6137b3704e9032e5855c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7735124
Reviewed-by: Ioana Treib <ioanap@chromium.org>
Commit-Queue: Vasilii Sukhanov <vasilii@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1611740}
---
diff --git a/chrome/browser/password_manager/actor_login/internal/actor_login_delegate_impl_unittest.cc b/chrome/browser/password_manager/actor_login/internal/actor_login_delegate_impl_unittest.cc
index ba4813566..6f97ae3c 100644
--- a/chrome/browser/password_manager/actor_login/internal/actor_login_delegate_impl_unittest.cc
+++ b/chrome/browser/password_manager/actor_login/internal/actor_login_delegate_impl_unittest.cc
@@ -194,6 +194,9 @@
void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp();
+ ON_CALL(mock_driver_, GetLastCommittedOrigin())
+ .WillByDefault(ReturnRef(test_origin_));
+
ActorLoginPermissionServiceFactory::GetInstance()->SetTestingFactory(
profile(), base::BindRepeating([](content::BrowserContext* context)
-> std::unique_ptr<KeyedService> {
@@ -315,6 +318,7 @@
FakeFormFetcher form_fetcher_;
std::vector<std::unique_ptr<PasswordFormManager>> form_managers_;
NiceMock<MockPasswordManagerDriver> mock_driver_;
+ url::Origin test_origin_ = url::Origin::Create(GURL(kTestUrl));
autofill::test::AutofillUnitTestEnvironment autofill_test_environment_{
{.disable_server_communication = true}};
NiceMock<MockActorLoginQualityLogger> mock_mqls_logger;
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc
index 8a3eab5..542c2ab 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -60,12 +60,16 @@
if (!url.is_valid())
return false;
- return password_manager::bad_message::CheckForIllegalURL(
+ return password_manager::bad_message::CheckChildProcessSecurityPolicyForURL(
render_frame_host, url,
password_manager::BadMessageReason::CPMD_BAD_ORIGIN_FORM_SUBMITTED);
}
bool IsRenderFrameHostSupported(content::RenderFrameHost* rfh) {
+ if (rfh->GetProcess()->IsPdf()) {
+ return false;
+ }
+
// Explanation of current PasswordManagerDriver limitations:
// * Currently, PasswordManagerDriver binding has RenderFrameHost lifetime,
// not document lifetime. This can lead to premature binding in rare race
diff --git a/components/password_manager/core/browser/password_form_filling.cc b/components/password_manager/core/browser/password_form_filling.cc
index 70f0c2d..49961692 100644
--- a/components/password_manager/core/browser/password_form_filling.cc
+++ b/components/password_manager/core/browser/password_form_filling.cc
@@ -235,8 +235,8 @@
} else if (preferred_match &&
GetMatchType(*preferred_match) == GetLoginMatchType::kGrouped) {
wait_for_username_reason = WaitForUsernameReason::kGroupedMatch;
- } else if (!IsSameOrigin(client->GetLastCommittedOrigin(),
- GURL(observed_form.signon_realm))) {
+ } else if (!client->GetLastCommittedOrigin().IsSameOriginWith(
+ driver->GetLastCommittedOrigin())) {
wait_for_username_reason = WaitForUsernameReason::kCrossOriginIframe;
} else if (not_sign_in_form) {
// If the parser did not find a current password element, don't fill.
diff --git a/components/password_manager/core/browser/password_form_filling_unittest.cc b/components/password_manager/core/browser/password_form_filling_unittest.cc
index f6fbdfc..247d0a06 100644
--- a/components/password_manager/core/browser/password_form_filling_unittest.cc
+++ b/components/password_manager/core/browser/password_form_filling_unittest.cc
@@ -39,6 +39,7 @@
using autofill::PasswordFormFillData;
using testing::_;
using testing::Return;
+using testing::ReturnRef;
using testing::SaveArg;
using url::Origin;
using Store = password_manager::PasswordForm::Store;
@@ -57,6 +58,10 @@
(const PasswordFormFillData&),
(override));
MOCK_METHOD(void, InformNoSavedCredentials, (bool), (override));
+ MOCK_METHOD(const url::Origin&,
+ GetLastCommittedOrigin,
+ (),
+ (const, override));
};
class MockPasswordManagerClient : public StubPasswordManagerClient {
@@ -121,6 +126,9 @@
ON_CALL(client_, GetLastCommittedOrigin())
.WillByDefault(
Return(Origin::Create(GURL("https://accounts.google.com"))));
+ driver_origin_ = Origin::Create(GURL("https://accounts.google.com"));
+ ON_CALL(driver_, GetLastCommittedOrigin())
+ .WillByDefault(ReturnRef(driver_origin_));
observed_form_.url = GURL("https://accounts.google.com/a/LoginAuth");
observed_form_.action = GURL("https://accounts.google.com/a/Login");
@@ -172,6 +180,7 @@
const std::vector<PasswordForm> federated_matches_;
MockWebAuthnCredentialsDelegate webauthn_credentials_delegate_;
testing::NiceMock<MockPasswordFeatureManager> feature_manager_;
+ url::Origin driver_origin_;
};
TEST_F(PasswordFormFillingTest, NoSavedCredentials) {
@@ -406,6 +415,7 @@
ON_CALL(client_, GetLastCommittedOrigin)
.WillByDefault(
Return(Origin::Create(GURL(observed_http_form.signon_realm))));
+ driver_origin_ = Origin::Create(GURL(observed_http_form.signon_realm));
ASSERT_FALSE(GURL(saved_http_match.signon_realm).SchemeIsCryptographic());
std::vector<PasswordForm> best_matches = {saved_http_match};
@@ -485,6 +495,32 @@
ON_CALL(client_, GetLastCommittedOrigin)
.WillByDefault(
Return(Origin::Create(GURL("https://another_website.com"))));
+ driver_origin_ = Origin::Create(GURL("https://some_website.com"));
+
+ std::vector<PasswordForm> best_matches = {saved_match_};
+ const std::vector<PasswordForm> federated_matches = {};
+
+ LikelyFormFilling likely_form_filling = SendFillInformationToRenderer(
+ &client_, &driver_, observed_form_, best_matches, federated_matches,
+ &saved_match_, metrics_recorder_.get(),
+ /*webauthn_suggestions_available=*/false,
+ /*suggestion_banned_fields=*/{});
+ EXPECT_EQ(LikelyFormFilling::kFillOnAccountSelect, likely_form_filling);
+ histogram_tester.ExpectUniqueSample(
+ "PasswordManager.FirstWaitForUsernameReason",
+ PasswordFormMetricsRecorder::WaitForUsernameReason::kCrossOriginIframe,
+ 1);
+}
+
+TEST_F(PasswordFormFillingTest, NoFillOnPageloadForOpaqueOrigin) {
+ base::HistogramTester histogram_tester;
+
+ observed_form_.url = GURL("https://some_website.com");
+ saved_match_.url = GURL("https://some_website.com");
+
+ url::Origin opaque_origin;
+ ON_CALL(driver_, GetLastCommittedOrigin)
+ .WillByDefault(ReturnRef(opaque_origin));
std::vector<PasswordForm> best_matches = {saved_match_};
const std::vector<PasswordForm> federated_matches = {};
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index d5e86e7..268fb7c 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -204,6 +204,10 @@
(const autofill::PasswordFormGenerationData&),
(override));
MOCK_METHOD(bool, IsInPrimaryMainFrame, (), (const, override));
+ MOCK_METHOD(const url::Origin&,
+ GetLastCommittedOrigin,
+ (),
+ (const, override));
};
class MockPasswordManagerClient : public StubPasswordManagerClient {
@@ -432,6 +436,7 @@
GURL psl_action = GURL("https://myaccounts.google.com/a/ServiceLogin");
observed_form_.set_url(origin);
+ observed_origin_ = url::Origin::Create(origin);
observed_form_.set_action(action);
observed_form_.set_name(u"sign-in");
observed_form_.set_renderer_id(FormRendererId(1));
@@ -523,6 +528,8 @@
.WillByDefault(ReturnRef(observed_form_.url()));
ON_CALL(client_, GetLastCommittedOrigin)
.WillByDefault(Return(url::Origin::Create(observed_form_.url())));
+ ON_CALL(driver_, GetLastCommittedOrigin)
+ .WillByDefault(ReturnRef(observed_origin_));
ON_CALL(client_, GetWebAuthnCredentialsDelegateForDriver)
.WillByDefault(Return(&webauthn_credentials_delegate_));
ON_CALL(webauthn_credentials_delegate_, GetPasskeys)
@@ -658,6 +665,7 @@
}
FormData observed_form_;
+ url::Origin observed_origin_;
FormData submitted_form_;
FormData observed_form_only_password_fields_;
FormData non_password_form_;
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index 339864a6..53adbf3 100644
Regression Test / PoC
diff --git a/chrome/browser/password_manager/actor_login/internal/actor_login_delegate_impl_unittest.cc b/chrome/browser/password_manager/actor_login/internal/actor_login_delegate_impl_unittest.cc
index ba4813566..6f97ae3c 100644
--- a/chrome/browser/password_manager/actor_login/internal/actor_login_delegate_impl_unittest.cc
+++ b/chrome/browser/password_manager/actor_login/internal/actor_login_delegate_impl_unittest.cc
@@ -194,6 +194,9 @@
void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp();
+ ON_CALL(mock_driver_, GetLastCommittedOrigin())
+ .WillByDefault(ReturnRef(test_origin_));
+
ActorLoginPermissionServiceFactory::GetInstance()->SetTestingFactory(
profile(), base::BindRepeating([](content::BrowserContext* context)
-> std::unique_ptr<KeyedService> {
@@ -315,6 +318,7 @@
FakeFormFetcher form_fetcher_;
std::vector<std::unique_ptr<PasswordFormManager>> form_managers_;
NiceMock<MockPasswordManagerDriver> mock_driver_;
+ url::Origin test_origin_ = url::Origin::Create(GURL(kTestUrl));
autofill::test::AutofillUnitTestEnvironment autofill_test_environment_{
{.disable_server_communication = true}};
NiceMock<MockActorLoginQualityLogger> mock_mqls_logger;
diff --git a/components/password_manager/core/browser/password_form_filling_unittest.cc b/components/password_manager/core/browser/password_form_filling_unittest.cc
index f6fbdfc..247d0a06 100644
--- a/components/password_manager/core/browser/password_form_filling_unittest.cc
+++ b/components/password_manager/core/browser/password_form_filling_unittest.cc
@@ -39,6 +39,7 @@
using autofill::PasswordFormFillData;
using testing::_;
using testing::Return;
+using testing::ReturnRef;
using testing::SaveArg;
using url::Origin;
using Store = password_manager::PasswordForm::Store;
@@ -57,6 +58,10 @@
(const PasswordFormFillData&),
(override));
MOCK_METHOD(void, InformNoSavedCredentials, (bool), (override));
+ MOCK_METHOD(const url::Origin&,
+ GetLastCommittedOrigin,
+ (),
+ (const, override));
};
class MockPasswordManagerClient : public StubPasswordManagerClient {
@@ -121,6 +126,9 @@
ON_CALL(client_, GetLastCommittedOrigin())
.WillByDefault(
Return(Origin::Create(GURL("https://accounts.google.com"))));
+ driver_origin_ = Origin::Create(GURL("https://accounts.google.com"));
+ ON_CALL(driver_, GetLastCommittedOrigin())
+ .WillByDefault(ReturnRef(driver_origin_));
observed_form_.url = GURL("https://accounts.google.com/a/LoginAuth");
observed_form_.action = GURL("https://accounts.google.com/a/Login");
@@ -172,6 +180,7 @@
const std::vector<PasswordForm> federated_matches_;
MockWebAuthnCredentialsDelegate webauthn_credentials_delegate_;
testing::NiceMock<MockPasswordFeatureManager> feature_manager_;
+ url::Origin driver_origin_;
};
TEST_F(PasswordFormFillingTest, NoSavedCredentials) {
@@ -406,6 +415,7 @@
ON_CALL(client_, GetLastCommittedOrigin)
.WillByDefault(
Return(Origin::Create(GURL(observed_http_form.signon_realm))));
+ driver_origin_ = Origin::Create(GURL(observed_http_form.signon_realm));
ASSERT_FALSE(GURL(saved_http_match.signon_realm).SchemeIsCryptographic());
std::vector<PasswordForm> best_matches = {saved_http_match};
@@ -485,6 +495,32 @@
ON_CALL(client_, GetLastCommittedOrigin)
.WillByDefault(
Return(Origin::Create(GURL("https://another_website.com"))));
+ driver_origin_ = Origin::Create(GURL("https://some_website.com"));
+
+ std::vector<PasswordForm> best_matches = {saved_match_};
+ const std::vector<PasswordForm> federated_matches = {};
+
+ LikelyFormFilling likely_form_filling = SendFillInformationToRenderer(
+ &client_, &driver_, observed_form_, best_matches, federated_matches,
+ &saved_match_, metrics_recorder_.get(),
+ /*webauthn_suggestions_available=*/false,
+ /*suggestion_banned_fields=*/{});
+ EXPECT_EQ(LikelyFormFilling::kFillOnAccountSelect, likely_form_filling);
+ histogram_tester.ExpectUniqueSample(
+ "PasswordManager.FirstWaitForUsernameReason",
+ PasswordFormMetricsRecorder::WaitForUsernameReason::kCrossOriginIframe,
+ 1);
+}
+
+TEST_F(PasswordFormFillingTest, NoFillOnPageloadForOpaqueOrigin) {
+ base::HistogramTester histogram_tester;
+
+ observed_form_.url = GURL("https://some_website.com");
+ saved_match_.url = GURL("https://some_website.com");
+
+ url::Origin opaque_origin;
+ ON_CALL(driver_, GetLastCommittedOrigin)
+ .WillByDefault(ReturnRef(opaque_origin));
std::vector<PasswordForm> best_matches = {saved_match_};
const std::vector<PasswordForm> federated_matches = {};
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index d5e86e7..268fb7c 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -204,6 +204,10 @@
(const autofill::PasswordFormGenerationData&),
(override));
MOCK_METHOD(bool, IsInPrimaryMainFrame, (), (const, override));
+ MOCK_METHOD(const url::Origin&,
+ GetLastCommittedOrigin,
+ (),
+ (const, override));
};
class MockPasswordManagerClient : public StubPasswordManagerClient {
@@ -432,6 +436,7 @@
GURL psl_action = GURL("https://myaccounts.google.com/a/ServiceLogin");
observed_form_.set_url(origin);
+ observed_origin_ = url::Origin::Create(origin);
observed_form_.set_action(action);
observed_form_.set_name(u"sign-in");
observed_form_.set_renderer_id(FormRendererId(1));
@@ -523,6 +528,8 @@
.WillByDefault(ReturnRef(observed_form_.url()));
ON_CALL(client_, GetLastCommittedOrigin)
.WillByDefault(Return(url::Origin::Create(observed_form_.url())));
+ ON_CALL(driver_, GetLastCommittedOrigin)
+ .WillByDefault(ReturnRef(observed_origin_));
ON_CALL(client_, GetWebAuthnCredentialsDelegateForDriver)
.WillByDefault(Return(&webauthn_credentials_delegate_));
ON_CALL(webauthn_credentials_delegate_, GetPasskeys)
@@ -658,6 +665,7 @@
}
FormData observed_form_;
+ url::Origin observed_origin_;
FormData submitted_form_;
FormData observed_form_only_password_fields_;
FormData non_password_form_;
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index 339864a6..53adbf3 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -378,6 +378,10 @@
(override));
MOCK_METHOD(bool, IsInPrimaryMainFrame, (), (const, override));
MOCK_METHOD(const GURL&, GetLastCommittedURL, (), (const, override));
+ MOCK_METHOD(const url::Origin&,
+ GetLastCommittedOrigin,
+ (),
+ (const, override));
MOCK_METHOD(void,
GeneratedPasswordAccepted,
(const std::u16string& password),
@@ -483,6 +487,8 @@
.WillByDefault(ReturnRef(test_form_url_));
ON_CALL(client_, GetLastCommittedOrigin)
.WillByDefault(Return(url::Origin::Create(test_form_url_)));
+ ON_CALL(driver_, GetLastCommittedOrigin)
+ .WillByDefault(ReturnRef(test_form_origin_));
ON_CALL(client_, IsCommittedMainFrameSecure()).WillByDefault(Return(true));
ON_CALL(client_, IsFillingEnabled).WillByDefault(Return(true));
ON_CALL(client_, GetMetricsRecorder()).WillByDefault(Return(nullptr));
@@ -837,6 +843,7 @@
}
const GURL test_form_url_{"https://www.google.com/a/LoginAuth"};
+ const url::Origin test_form_origin_{url::Origin::Create(test_form_url_)};
const GURL test_form_action_{"https://www.google.com/a/Login"};
const std::string test_signon_realm_ = "https://www.google.com/";
base::test::SingleThreadTaskEnvironment task_environment_{
@@ -2865,6 +2872,10 @@
// Observe the form in the second frame.
MockPasswordManagerDriver driver_b;
+ url::Origin test_origin =
+ url::Origin::Create(GURL("http://www.example.com/"));
+ ON_CALL(driver_b, GetLastCommittedOrigin)
+ .WillByDefault(ReturnRef(test_origin));
EXPECT_CALL(driver_b, PropagateFillDataOnParsingCompletion);
manager()->OnPasswordFormsParsed(&driver_b, {form_data2});
task_environment_.RunUntilIdle();
Original Bug Report
Potential CPSP bypass in PasswordManager allows sandboxed iframes to leak credentials
Project Fortify, an experimental security project, has identified the following potential security issue.
Overview: A missing ChildProcessSecurityPolicy check in ContentPasswordManagerDriver::PasswordFormsParsed allows a compromised sandboxed iframe process to request password autofill data. Because the browser compares the main frame’s origin with the iframe’s precursor URL instead of its opaque origin, it treats the request as same-origin, sending plaintext credentials back to the isolated sandboxed renderer.
Affected files:
components/password_manager/content/browser/content_password_manager_driver.cccomponents/password_manager/content/browser/bad_message.cccomponents/password_manager/core/browser/password_form_filling.cccomponents/autofill/core/common/password_form_fill_data.ccchrome/browser/password_manager/chrome_password_manager_client.cccomponents/password_manager/content/browser/form_meta_data.cc
Estimated timestamp from git blame: 2024-06-25
Overview
Note: This is a potential vulnerability identified by an AI agent (Flapjack). The steps below are theoretical and have not been verified with a working proof-of-concept exploit, as the agent does not currently have code execution capabilities.
Chrome’s IsolateSandboxedIframes feature places sandboxed iframes into dedicated, isolated renderer processes. The ChildProcessSecurityPolicy (CPSP) correctly denies these opaque-origin processes access to sensitive data, such as passwords, belonging to their precursor origin.
However, a logic flaw in the Password Manager’s Mojo message handling allows a compromised sandboxed renderer to bypass this isolation and exfiltrate the precursor origin’s saved credentials.
There are two main factors contributing to this vulnerability:
- Missing CPSP Check: When the browser receives a
PasswordFormsParsedMojo message,ContentPasswordManagerDriver::PasswordFormsParsedvalidates the request usingHasValidURL(). This function only callsbad_message::CheckForIllegalURL, which merely rejectsabout:anddata:schemes. It crucially fails to callbad_message::CheckChildProcessSecurityPolicyForURL, meaning the browser never verifies if the requesting process is actually authorized to access data for the given URL. - Cross-Origin Bypass: When deciding whether to autofill credentials immediately or wait for user interaction (
wait_for_username),SendFillInformationToRenderercompares the primary main frame’s origin against the form’ssignon_realm. For a sandboxed iframe, thesignon_realmis derived from its precursor URL. If the main frame and the sandboxed iframe share the same precursor origin (e.g.,https://victim.com),IsSameOrigin()evaluates totrue. The browser incorrectly assumes the form is same-origin, bypasses the cross-origin wait requirement, and sends plaintext passwords to the renderer.
Potential Steps to Trigger
- A victim user saves their username and password for
https://victim.comin Chrome. - The victim visits
https://victim.com, which embeds a sandboxed iframe:<iframe sandbox="allow-scripts" src="/sandboxed.html"></iframe>. - The sandboxed iframe is placed in an isolated renderer process with an opaque origin.
- An attacker exploits a separate vulnerability (e.g., a V8 bug) to achieve Remote Code Execution (RCE) within the sandboxed iframe’s renderer process.
- The attacker’s code bypasses renderer-side checks (like
FrameCanAccessPasswordManager) and crafts a fakeautofill::FormDataobject mimicking a login form with a URL ofhttps://victim.com/sandboxed.html. - The compromised renderer sends a
PasswordFormsParsedMojo message to the browser process containing the fake form. ContentPasswordManagerDriver::PasswordFormsParsedvalidates the URL but misses the CPSP check, allowing the request to proceed.- The browser fetches the saved credentials for
https://victim.comfrom the Password Store. - In
SendFillInformationToRenderer, the browser compares the main frame’s origin (https://victim.com) to the form’ssignon_realm(https://victim.com/). Since they match,wait_for_usernameevaluates tofalse. autofill::MaybeClearPasswordValuesleaves the plaintext credentials intact becausewait_for_usernameisfalse.- The browser sends the plaintext username and password back to the compromised sandboxed renderer process via
ApplyFillDataOnParsingCompletion, successfully exfiltrating the credentials.
Suggested Fix
-
Enforce CPSP in
HasValidURL: Incomponents/password_manager/content/browser/content_password_manager_driver.cc, updateHasValidURLto callpassword_manager::bad_message::CheckChildProcessSecurityPolicyForURLinstead ofCheckForIllegalURL. This will immediately terminate the compromised renderer if an opaque/sandboxed process attempts to access password data. -
Strengthen Origin Checks in
password_form_filling.cc: When calculatingwait_for_username_reasoninPasswordFormFilling::SendFillInformationToRenderer, ensure that the origin comparison takes opaque origins into account. Comparing against the precursor URL’ssignon_realmis insufficient if the frame is sandboxed.
Evaluated with Chrome root at commit: False
Results from Fortify so far have been promising, but it can be wrong in its deductions. At this time, it does not produce proof of concepts or fuzzer tests. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve Fortify’s accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.