Fifteen plugins on the JetBrains Marketplace, published under seven vendor accounts, accumulated roughly 70,000 installs while silently stealing every AI provider API key their users typed in. Aikido Security disclosed the campaign on June 16, 2026. BleepingComputer confirmed the credential-theft code was still active at that moment. JetBrains responded the next day: all 15 plugins removed from the Marketplace, the seven publisher accounts permanently terminated, and the plugins marked broken in the backend - deactivating them in existing installations on the next IDE relaunch. That remote containment does not retroactively protect keys already exfiltrated before June 17. Any key entered into these plugins should be treated as compromised.

Every plugin posed as a legitimate AI coding assistant - chat, commit-message generation, code review, bug detection, unit-test generation - built on DeepSeek, OpenAI, and other LLMs. Each one worked exactly as advertised while running a second job in the background.

This is not an incident at the package registry layer or a self-propagating worm moving between machines. It is a credential-theft campaign operating at the IDE marketplace layer, targeting a new and high-value payload: AI provider API keys.

The Third Vector in a Month

Developer supply chain attacks now arrive in three distinct forms, each hitting a different part of the toolchain and requiring different defenses:

LayerMechanismPayload
Package registry / CI runnerSelf-replicating npm worm; AI tool plants malicious config files at project openCloud credentials, CI tokens, package publish rights
VS Code extension (propagating worm)Self-propagating extension with blockchain C2; spreads by infecting other extensionsCredential spread across developer machines
IDE marketplace / developer workstationTrojanized AI coding plugin; steals credentials at the moment of entryAI provider API keys, sent to a plain-HTTP C2

The npm worm campaign targets build infrastructure. The GlassWorm targets the extension layer as a propagation vehicle. This campaign targets the developer’s workstation directly, using the plugin settings dialog as the theft vector. Same attack surface category, three distinct mechanisms.

How IDE Marketplace Trust Actually Works

Do JetBrains IDE plugins run in a sandbox?

JetBrains’ own security documentation is direct: “Plugins in JetBrains IDEs run as part of the IDE and have the same access rights as the IDE itself.” A plugin can “read, modify, or delete any files and data that the IDE user can access” and “connect to the internet or a local network without additional user prompts or restrictions.”

The line that explains the whole campaign: “The IDE does not restrict plugins using fine-grained permissions, nor does it isolate (sandbox) them.”

A plugin reading a key from its own settings panel and POSTing it to an external server is not exotic behavior requiring a security bypass. It is completely normal capability for any JetBrains plugin. Installing a plugin grants system-level access comparable to installing a desktop application.

How did malicious plugins bypass JetBrains marketplace review for 8 months?

JetBrains runs documented moderation. The Marketplace Approval Guidelines state: “Along with automated checks, we manually review each Plugin and Plugin update one-by-one, before it becomes publicly available.” Reviews target a two-business-day turnaround. The Plugin Verifier runs on every upload.

The concrete gap: the earliest malicious versions appeared at the end of October 2025. New malicious plugin versions were still clearing the review process and going live as recently as June 10, 2026 - over seven months later.

The Plugin Verifier checks binary compatibility between plugins and IDE versions. It does not analyze whether a plugin POST-requests user-entered credentials to an external IP. Manual review did not catch plain-HTTP exfiltration on key-entry either. This is the sourced, primary-document version of the claim that marketplace review is not a security control you can rely on.

Following the disclosure, JetBrains published a security update on June 17, 2026. Beyond the plugin removal and account terminations, the company announced plans to deploy new automated rule layers targeting plugins that contain unencrypted HTTP connections to raw IP endpoints, TLS weakening behavior, or credential-handling code without encryption. JetBrains also recommended adopting its Agent Client Protocol (ACP) as a more controlled alternative to traditional marketplace plugins. These are improvements to detection capability, not a change to the fundamental trust model: plugins will still run unsandboxed with full IDE-level access after these controls land.

What do VS Code and Open VSX marketplaces actually guarantee?

The trust models differ across IDE ecosystems. Conflating them produces the wrong defensive posture.

VS Code Marketplace signs all extensions at publish time. VS Code verifies that signature when you install an extension, confirming integrity and source. The first install of a third-party extension shows a trust-confirmation dialog. Signing proves the file has not been tampered with since publication and came from the stated publisher. It does not prove the code is benign.

Open VSX is the extension registry used by VS Code forks - Cursor, VSCodium, Gitpod, Windsurf. Creating a namespace does not automatically assign you as the verified owner; publishers must separately claim ownership for the verified mark. Open VSX also runs automated publish-time scanning: secret detection, a file-hash blocklist, and namespace-similarity checks to prevent typosquatting. Failing these blocks publication. This is a stronger automated posture than the other registries. It is still provenance and heuristic analysis, not intent analysis.

Are “Verified Vendor” badges and high download counts reliable safety signals?

JetBrains documents this limitation directly. A Verified Vendor badge “doesn’t guarantee plugin quality.” Download numbers and positive reviews “are not a firm guarantee of safety.” JetBrains says it is “working on introducing additional automated security checks” - an admission that current scanning is limited.

In this campaign, the two largest plugins had 27,727 and 25,571 installs respectively. High download counts were evidence of a successful distribution campaign, not a safe one.

graph LR
    A[IDE Marketplace Controls] --> JB[JetBrains]
    A --> VS[VS Code]
    A --> OV[Open VSX]

    JB --> JB1[Manual + automated review of every plugin and update]
    JB --> JB2[Plugin Verifier: binary compatibility]
    JB --> JB3[Verified Vendor badge: publisher identity only]
    VS --> VS1[Extension signing: integrity and publisher]
    VS --> VS2[First-install trust dialog]
    OV --> OV1[Automated: secrets scan, blocklist, typosquat check]
    OV --> OV2[Namespace claim required for verified status]

    JB1 & JB2 & JB3 & VS1 & VS2 & OV1 & OV2 --> P[Proves: provenance and integrity]
    JB1 & JB2 & JB3 & VS1 & VS2 & OV1 & OV2 --> NP[Does NOT prove: code is benign]

    style NP fill:#c0392b,color:#fff
    style P fill:#27ae60,color:#fff

Every marketplace control available today proves provenance and file integrity. None of them run the plugin code in a safe environment or verify that it does not exfiltrate credentials.

Why AI API Keys Are the Payload Now

Why are stolen AI API keys more damaging than other credential thefts?

When an attacker steals a GitHub PAT or a cloud IAM key, the scope of damage is bounded by what that specific token can access. AI provider keys have a different blast radius.

Model spend and resource abuse. The attacker bills inference directly to the victim’s account. Aikido found a resale layer in this campaign: the C2 can hand out harvested keys to paying users, making the stolen credentials the direct monetization mechanism. A single stolen key can generate thousands of dollars in inference bills before the owner notices.

Downstream agent and tool access. A developer’s provider key often backs multiple tools simultaneously: their IDE coding assistant, MCP integrations, internal automation, shell scripts. A single stolen key unlocks all of them. As AI coding agents become the primary interface between developers and their infrastructure, the value of the keys those agents carry increases with every new integration. The broader IAM attack surface this creates is examined in AI Agent Credential Crisis: The IAM Attack Surface You’re Not Watching.

Weak default scoping. Developers commonly mint one broad organizational key and paste it into every tool that asks. The same key that went into the JetBrains plugin may also be in their VS Code extension, their shell configuration, and their local agent setup. A single theft becomes a multi-tool breach.

How does the malicious plugin exfiltrate API keys silently?

The mechanism Aikido documented is precise. The theft does not happen when the plugin runs inference tasks. It happens when the user saves their settings.

The plugin’s save() handler has two jobs: store the key locally (expected behavior), and POST it to the attacker’s C2. The second job fires immediately on clicking Apply, after validating the key format (starts with sk-, meets a length requirement consistent with OpenAI key formatting) before transmitting it. No prompt. No consent screen. No indication in the plugin’s UI that anything beyond local storage has occurred.

sequenceDiagram
    participant Dev as Developer
    participant IDE as JetBrains IDE
    participant Plugin as AI Plugin (malicious)
    participant C2 as Attacker C2 (39.107.60.51)
    participant Buyer as Paying Attacker

    Dev->>IDE: Open plugin settings panel
    Dev->>Plugin: Paste AI provider API key
    Dev->>Plugin: Click Apply
    Plugin->>IDE: Store key locally (expected)
    Plugin-->>C2: POST key in plaintext over HTTP port 80 (silent)
    Note over Plugin,C2: No prompt. No consent screen. Fires on every Apply click.
    C2-->>Plugin: 200 OK
    C2->>Buyer: Sell harvested key access to paying subscribers

The exfiltration fires the moment the developer clicks Apply. The plugin completes the expected local storage operation and simultaneously sends the key to the attacker in a separate request the user never sees.

The C2 details Aikido confirmed: IP address 39.107.60[.]51, plain HTTP (not HTTPS), a hardcoded static authentication token F48D2AA7CF341F782C1D embedded in the requests. The exact API endpoint path varies slightly across coverage; treat the Aikido report as the authoritative IoC source and do not over-specify the path. Block the IP at your egress layer and alert on any historical traffic to it.

The Platform-Team Defense Stack

No single control stops this class of attack. The defense is layered: prevent installation of untrusted plugins, remove the real credential from the plugin’s reach, detect the C2 behavior if prevention fails, and recover from any key that may have been exposed.

graph TD
    L1[Layer 1: Prevent Install] --> L2[Layer 2: Remove the Secret]
    L2 --> L3[Layer 3: Detect C2 Traffic]
    L3 --> L4[Layer 4: Scan and Rotate]

    L1 -.->|Stops most threats here| L1D[VS Code extensions.allowed\nJetBrains IDE Provisioner allowlist\nPrivate vetted plugin repository]
    L2 -.->|Defeats payload theft| L2D[Scoped project keys per tool\nLLM gateway: plugin holds only a virtual key\nor placeholder the gateway swaps on the wire]
    L3 -.->|Catches what slips through| L3D[EDR or egress proxy: flag plain-HTTP\nfrom IDE processes to bare IPs\nAlert on connections to 39.107.60.51 port 80]
    L4 -.->|Limits blast radius| L4D[GitHub secret scanning and push protection\nProvider auto-revocation program\nRotate every key that touched a third-party tool]

    style L1 fill:#155724,color:#fff
    style L2 fill:#0c3a6b,color:#fff
    style L3 fill:#6b3a0c,color:#fff
    style L4 fill:#4a0c6b,color:#fff

Each layer addresses what the previous one cannot. Allowlisting stops most threats at install time. Gateway brokering defeats the payload even if a malicious plugin installs. Egress detection catches C2 traffic if both fail. Secret scanning limits blast radius from any key that escapes.

How do platform teams control which IDE plugins developers can install?

The most direct control is preventing arbitrary plugin installation on developer machines.

VS Code enterprise (extensions.allowed): Available from VS Code 1.96, this setting - deployable via MDM or the AllowedExtensions group policy - specifies exactly which extensions can be installed:

// settings.json delivered via MDM or group policy (AllowedExtensions)
// Default-deny: only explicitly listed publishers and extensions can install.
"extensions.allowed": {
  "github": true,                              // all extensions from publisher "github"
  "ms-python.python": true,                    // a specific approved extension by ID
  "dbaeumer.vscode-eslint": ["3.0.0"],         // pinned to a reviewed version
  "github.vscode-pull-request-github": "stable", // release versions only, no pre-releases
  "*": false                                   // deny everything not explicitly listed
}

VS Code also supports a private extension marketplace so approved extensions can be served from org-controlled infrastructure rather than the public registry.

JetBrains IDE Services (IDE Provisioner): Supports both a denylist strategy (“block all plugins, then selectively allow access to required or trusted plugins using more specific scopes”) and an allowlist strategy (allow everything, then apply Block, Block (Forced), or Disable rules for specific plugins). Rules evaluate from broadest to most specific, so a blanket block-all rule followed by explicit allow rules gives you default-deny behavior. IDE Services also ships a private plugin repository so developers can only install plugins your team has vetted and hosted.

Both platforms replace the default-allow model with explicit opt-in. A plugin that has not been reviewed and approved cannot install.

How do you prevent IDE plugins from holding real API credentials?

Allowlisting controls what can install. Gateway brokering controls what a plugin can steal even if it does install.

The invariant: the IDE plugin should never hold your real provider credential. Mint a project-scoped API key with restricted per-endpoint permissions - OpenAI’s API key management supports restricting keys to specific endpoints with granular read/write controls per operation type. Then do not give that key to the plugin directly.

Instead, route the provider key through an LLM gateway. The plugin receives a virtual key: revocable, spend-capped, scoped to one tool. The gateway injects the real credential on the wire as the request leaves. A malicious plugin that reads and exfiltrates the virtual key gives the attacker something you can revoke immediately with no credential-rotation overhead for the rest of your tooling.

LiteLLM’s virtual keys implement this pattern at the lighter-weight end: per-tool keys tied to budget limits, revocable independently, with model-access controls. The credential-holding gateway design covered in Agent Egress Control: Credential-Holding Gateways on Kubernetes applies the same structural invariant at the agent level. The Deno Claw Patrol project describes the invariant precisely: “Credentials live on the gateway, not the agent. The agent sends a placeholder like {{github_pat}} and the gateway swaps in the real token on the wire.” A malicious IDE plugin is the same problem as a compromised agent: it can only exfiltrate what it holds.

How do you detect malicious IDE plugin C2 traffic?

If prevention fails and a malicious plugin installs, this campaign’s mechanism has a detectable signature on managed workstations: a plain-HTTP POST to a bare IP address from an IDE process.

On an EDR or egress proxy, the hunt query shape is:

# Pattern to hunt in EDR, SIEM, or proxy logs:
# - Source process: idea, pycharm, goland, webstorm, code (or their equivalents)
# - Destination: bare IPv4 with no preceding DNS resolution
# - Port: 80 (plain HTTP, not 443)
# - Method: POST
#
# Known IoC from the June 2026 JetBrains campaign:
#   IP:    39.107.60[.]51  (block at egress and alert on historical hits)
#   Proto: HTTP (port 80, not HTTPS)
#   Token: F48D2AA7CF341F782C1D (hardcoded in POST body)
#
# See the Aikido report for the full authoritative IoC list before deploying rules.

The exact query syntax depends on your EDR or SIEM platform. The shape is consistent: outbound plain HTTP from IDE processes to bare IPs is anomalous in any well-configured environment. This detection does not require knowing which plugin is malicious in advance - it targets the behavior, not the plugin identity.

Outbound plain HTTP from developer workstations is suppressible at the network layer. Requiring TLS for all egress from IDE processes closes this gap without requiring EDR coverage on every machine.

How should you respond if developers used a malicious IDE plugin?

Any key that may have touched a third-party plugin is a burned key. Rotation is not optional, and it is not sufficient by itself.

GitHub’s secret scanning partner program notifies providers when recognized secrets appear in public repositories: “When a partner secret is detected, we notify the provider so they can take action, such as revoking the credential.” Push protection blocks recognized secrets before they enter a commit. OpenAI participates in automated detection and revocation for sk- key formats found in public repositories.

Platform-team actions:

  1. Enable secret scanning and push protection across all org repositories if not already active.
  2. Treat rotation of any key that has touched a third-party AI plugin as mandatory - not dependent on confirmed evidence of theft.
  3. Audit provider usage dashboards for anomalous inference spend or unusual API call patterns after a suspected incident.
  4. Set spend alerts on all provider accounts so unauthorized inference billing surfaces quickly, before it compounds.

What to Do This Quarter

Immediate (this week):

  • Pull the Aikido IoC list and block 39.107.60[.]51 at your egress proxy. Search historical traffic for any connections to that IP from developer workstations.
  • Inventory JetBrains plugin installations across your developer fleet. Check for DeepSeek AI Assist, CodeGPT AI Assistant, and the other 13 plugins named in the Aikido report.
  • Treat any AI provider key a developer has entered into an AI-themed third-party JetBrains plugin as compromised. Rotate it and audit provider spend for that key.

This month:

  • Deploy extensions.allowed in VS Code via group policy (VS Code 1.96+). Enable IDE Provisioner allowlist rules for JetBrains shops.
  • Stand up a vetted private plugin repository as the approved source for both ecosystems.
  • Enable GitHub secret scanning and push protection across all org repositories.

This quarter:

  • Move AI provider keys behind an LLM gateway. Developers get virtual keys; the gateway injects real credentials on the wire.
  • Scope all provider keys to the minimum permissions and specific projects each tool requires.
  • Add IDE-process egress monitoring to your EDR or proxy configuration. Alert on plain-HTTP connections from idea, pycharm, goland, webstorm, code, and related processes to bare IP addresses.

Campaign status as of June 17, 2026: JetBrains has contained the active campaign. All 15 plugins are removed from the Marketplace, the seven publisher accounts are permanently terminated, and the broken-plugin backend mechanism has deactivated the installed copies in affected IDEs on relaunch. That containment closes the forward-exfiltration window. It does not protect keys that were already stolen. The guidance above - rotate any exposed key, block the C2 IP, deploy allowlists, move provider credentials behind a gateway - applies in full to anyone whose developers used these plugins before June 17.

Frequently asked questions

Are marketplace plugins safe if they have a verified publisher and lots of downloads?

No. JetBrains’ own documentation states that a Verified Vendor badge “doesn’t guarantee plugin quality” and that download numbers and positive reviews “are not a firm guarantee of safety.” In this campaign, the two largest plugins - DeepSeek AI Assist (27,727 installs) and CodeGPT AI Assistant (25,571 installs) - were actively stealing credentials while accumulating those numbers. High install counts proved the campaign’s distribution worked, not that the plugins were safe. Verification establishes publisher identity, not code intent.

Do JetBrains IDE plugins run in a sandbox?

No. Per JetBrains documentation, “Plugins in JetBrains IDEs run as part of the IDE and have the same access rights as the IDE itself,” and “the IDE does not restrict plugins using fine-grained permissions, nor does it isolate (sandbox) them.” A plugin can read your files, reach any network endpoint without triggering a user prompt, and exfiltrate anything the IDE can access. Reading a key from its own settings panel and POSTing it to an external server required no security boundary crossing - it is standard plugin capability.

My developers need AI coding assistants. How do I let them use one without exposing our provider keys?

Don’t let the plugin hold the real key. Mint a project-scoped API key with restricted per-endpoint permissions and route it through an LLM gateway. The plugin receives a revocable, spend-capped virtual key or a placeholder the gateway swaps for the real credential on the wire. A compromised plugin can then exfiltrate only the virtual key, which you can revoke in seconds without rotating the underlying provider credential or disrupting other tooling. LiteLLM virtual keys and credential-holding gateway patterns implement this at different scales.

How do I stop developers from installing risky extensions in the first place?

Use managed allowlists. In VS Code, the extensions.allowed setting (available from VS Code 1.96) and the AllowedExtensions group policy let you specify exactly which publishers, extension IDs, or versions can install and deny everything else. In JetBrains, IDE Services (IDE Provisioner) supports both allowlist and denylist plugin rules plus a private plugin repository so developers can only install plugins your team has vetted and hosted. Both ecosystems support default-deny posture backed by an explicit approved list.

One of my developers may have used a malicious plugin. What do I do now?

Treat any AI provider key entered into a third-party plugin as compromised and rotate it immediately. Then audit provider dashboards for anomalous inference spend or API call patterns. Search your EDR and network proxy logs for plain-HTTP POST connections from IDE processes to raw IP addresses - this campaign’s C2 was 39.107.60[.]51 over port 80 with a hardcoded token in the POST body. Enable GitHub secret scanning and push protection across your org repositories so any leaked key formats trigger automatic provider notification and revocation. Rotate first, investigate second.