A take-home interview project can run malware the moment you make your first commit, and reading the code first won't catch it.
// the short version
A take-home interview project can run malware the moment you make your first commit, and reading the code first won't catch it.
// what to take away
- Git hooks are scripts git runs by itself, such as pre-commit before every commit. They live in the hidden .git folder, so they never appear in a diff or in most editors, and a clone never copies them, which is why this take-home arrived as a zip: a zip carries .git along.
- The July take-home was a copy of a real FastAPI project with 22 hooks set up and tasks that asked for git work. Its pre-commit hook downloaded a script from a server and ran it in the background with its output sent to /dev/null. Atlassian has taken down hundreds of repositories built for this lure, and almost half use two or more triggers, including VS Code tasks that run when the folder opens.
- Reading the code doesn't catch it. Run take-homes on a throwaway machine with nothing worth taking, read .git/hooks before any git command, and set VS Code's task.allowAutomaticTasks to off. Binance says an engineer's fake-interview assignment ran during setup on his work computer before the 29 October theft, without saying how it ran.
What a git hook is, and why teams use them
A git hook is a script that git runs by itself when something happens in a repository. The common ones fire on your own machine during ordinary work: pre-commit runs before a commit is recorded, commit-msg checks the message you typed, post-checkout runs after you switch branches, pre-push runs before anything leaves for the remote. Teams use them for checks nobody wants to remember by hand: run the linter, run the fast tests, refuse a commit that still contains a debugging statement. If a pre-commit hook exits with an error, the commit is stopped.
Hooks live in the hooks folder inside .git, the hidden folder where git keeps the repository's history and settings. When you run git init, git fills that folder with example scripts whose names end in .sample, and those do nothing. Pro Git describes the switch: a hook runs when a file with the right name, with no extension, is in that folder and is executable. Rename pre-commit.sample to pre-commit, make it executable, and from then on git runs it before every commit.
Three properties of hooks are what the attack in the video is built on:
- They are not tracked files. Nothing under
.gitis part of the project's history, so a hook never shows up ingit status, a diff or a pull request. - Most editors hide the folder. VS Code leaves
.gitout of its file explorer by default, and many other editors and file browsers hide dot-folders too. The folder is there on disk, but a reviewer working in an editor never sees it. - Cloning does not copy them. Pro Git says it directly: client-side hooks are not copied when you clone a repository. Teams that want shared hooks install them with a setup step or a tool, on purpose.
Why the take-home came as a zip
That third property explains the delivery. If an attacker hosts a repository and asks a candidate to clone it, the candidate's fresh .git/hooks folder holds only git's own samples, and any hook the attacker planted stays on the server. A zip of a project folder is different: it packs up everything in the folder, including the hidden .git directory and every hook inside it. Unzip it and the hooks are live on your machine, ready for the first git command.
That is why repository-hosted versions of this lure use other triggers (the next section but one), and why a zip arriving as a "take-home" deserves more suspicion than a link to a public repository.
What the July take-home did, step by step
Appaji C. published this case on 23 July 2026. The account below is theirs; the reading of what the second stage was for is partly theirs and partly guesswork, as noted.
1. The lure. A recruiter on LinkedIn offered a remote, contract-to-hire Python role at $10,000 to $15,000 a month, using the name of a real startup. After a résumé, the recruiter sent a Google Drive link with a zip and a PDF. The PDF asked for improvements to an existing codebase, architectural suggestions and "some git operations". 2. The decoy. The zip held an ordinary FastAPI backend using SQLAlchemy. requirements.txt had no typosquatted or malicious packages. git log later showed it was a copy of someone's public project, with the attackers' hidden folder added on top. 3. The find. Out of habit, the developer ran tree -a, which lists hidden files. It showed 22 hooks in .git/hooks, none of them ending in .sample. 4. The hook. The pre-commit hook was a few lines of shell. It checked the operating system with uname, then for macOS, Linux or Windows downloaded a script from a server addressed by a raw IP and piped it straight into a shell (cmd on Windows). The whole thing ran in the background, with its output and errors sent to /dev/null, so a commit would look completely normal. 5. The second stage. The downloaded script fetched another script, saved it in the user's Documents folder, made it executable and started it with nohup so it would keep running after the terminal closed. That one installed Node.js, downloaded a package.json and a heavily obfuscated JavaScript file, installed the packages and ran the file in the background. 6. What it was likely for. The package.json asked for clipboard access, file-system access and Hardhat, an Ethereum development environment. The developer's reading, which they flag as a guess, was that it went looking for crypto wallets. Changing an ID in the download URL returned a different script, which suggests each candidate got a tracked, personalised payload.
The developer's conclusion about the PDF is the important one: its git tasks were there to make sure the candidate ran at least one git command, so at least one hook would fire. With 22 hooks set up, almost any git command would do.
This page leaves out the server address, the payload file names and the copied project, on purpose.
The other triggers: VS Code tasks and more
The same write-up reports variants that skip git entirely: a zip containing a .vscode folder whose tasks run as soon as the project is opened in VS Code. A VS Code task is a command defined in .vscode/tasks.json, and a task can be set to run automatically when its folder opens ("runOptions": { "runOn": "folderOpen" }). Nobody has to type anything.
Atlassian, which runs Bitbucket, found the same thing at scale. Its analysis of the campaign it tracks as Contagious Interview (attributed with high confidence to North Korean threat actors) says the attackers keep changing and combining the ways the first-stage loader gets started, and that almost half of the repositories it examined used two or more trigger techniques. Its first defensive recommendation for VS Code is to set task.allowAutomaticTasks to off.
Two more triggers worth knowing about, which are our additions rather than findings from these sources: package-manager install scripts (an npm postinstall script runs during npm install, and npm install --ignore-scripts turns those off), and VS Code's Workspace Trust prompt, where answering that you do not trust a folder's authors keeps it in Restricted Mode, in which tasks do not run.
How big this is, according to Atlassian
Atlassian's report of 21 September 2026 gives these figures and patterns:
- Hundreds of Contagious Interview repositories and their accounts had been taken down from Bitbucket by then. Atlassian gives no device count and no victim count.
- The repositories reuse themes and file structures; often only a few files differ from one fake project to the next, and those are the ones hiding the code.
- The attackers build front companies with domains, websites and well-kept LinkedIn profiles.
- Some victims became distributors: candidates were asked to record themselves walking through the assessment and upload their copy to GitHub or Bitbucket, which puts the malicious repository under a legitimate account.
The field of repositories in the video is drawn to "hundreds", not to a published count, and the share with a second trigger is drawn at about half, following Atlassian's "almost half".
What Binance said, and what it did not
Binance's initial report of 3 November 2026 describes a multi-stage campaign behind the incident of 29 October 2026, in which about $6.34 billion in digital assets were affected and about $2.85 billion had been frozen or intercepted at the time of writing. Binance says it is covering the loss.
The part the video draws on: in September, an engineer was contacted on a job-hunting platform, interviewed in two rounds by people posing as a project director, an HR representative and a CEO, and near the end was told to download an "assignment", a code repository, onto his work computer. Binance says the repository's code ran during the setup process and replaced a legitimate development tool with a malicious copy, and that its endpoint security did not detect it. From that computer, the attackers later used an internal AI tool to gain control over two colleagues on the wallet infrastructure team, and on 29 October used one colleague's container deployment token to reach the wallet signing service.
What this page does not claim, because Binance has not said it:
- That a git hook was involved. Binance says the code "executed during the setup process" and nothing about how. The video's git hook case is a separate, documented example of the same kind of lure.
- That the incident is part of Contagious Interview. Binance reports that the FBI attributes the incident to North Korea. It has not tied it to the campaign Atlassian tracks.
- That the interview was where the attack began. Binance traces the chain back to June 2026, when another engineer installed a tampered Homebrew download. The fake interview was how the attackers got onto the second engineer's machine.
How to do a take-home safely
Taken together, the sources point to one habit that covers every trigger, and two checks that catch the commonest ones.
- Run it somewhere with nothing worth taking. A spare machine, or a throwaway virtual machine you delete afterwards, with no saved passwords, SSH keys, cloud tokens or company VPN. Atlassian's wording is a dedicated, isolated environment, and never a corporate workstation with access to production credentials.
- Look before any git command. List hidden files, and read the hooks folder:
tree -a # or: ls -la ls .git/hooks | grep -v '\.sample$' # anything listed here is a script git will run cat .git/hooks/pre-commit # reading a hook does not run it
- Turn off automatic VS Code tasks (
task.allowAutomaticTasks:off), and open unfamiliar folders in Restricted Mode.
Two things that look like protection and are not enough. git commit --no-verify skips only the pre-commit and commit-msg hooks; post-checkout, post-merge and the rest still run. Setting core.hooksPath to an empty folder does stop git from running the project's hooks (our addition, not from the sources), but it does nothing about VS Code tasks or install scripts. Neither replaces running the code on a machine you can throw away.
If you already ran one, Atlassian's guidance is to disconnect the device and tell your security team, rotate passwords, tokens, SSH keys and cloud credentials from a different, clean device, move any crypto to a new wallet made on a clean device, and reimage the machine, because deleting the project or running an antivirus scan may not remove what it installed.
Terms
- Git hook
- A script git runs by itself at a set moment, such as before a commit. It lives in
.git/hooksand is not part of the project's tracked files. - Client-side hook
- A hook that runs on your own machine during local operations like committing, merging and checking out. These are the ones a clone does not copy.
- pre-commit hook
- The hook git runs before recording a commit, before you even type the message. Teams use it to lint and test; this take-home used it to download and run a script.
- .sample hooks
- The inactive examples
git initcreates. A file in.git/hooksthat does not end in.sampleand is executable is a hook git will run. - Take-home assignment
- A coding task a candidate completes on their own machine as part of a job interview.
- Second stage
- Code downloaded and run by a small first script, so the part that does the real work never sits in the project for anyone to read.
- /dev/null
- A file on Unix systems that discards anything written to it. Sending output there hides it.
- nohup
- A command that keeps a process running after you close the terminal that started it.
- VS Code task
- A command defined in
.vscode/tasks.json. A task can be set to run when the folder is opened. - task.allowAutomaticTasks
- The VS Code setting that controls whether tasks may run automatically; Atlassian recommends
off. - Contagious Interview
- The name Atlassian and others use for a long-running campaign of fake recruitment and malicious coding assessments, attributed to North Korean threat actors. BeaverTail is the first-stage loader Atlassian's analysis focuses on.
- core.hooksPath
- A git setting that tells git to look for hooks somewhere other than
.git/hooks.
Questions
Can a take-home interview project contain malware?
Yes. In the case in the video, the project's code was clean and the malware was in a git hook inside the hidden .git folder, set to run on the first commit. Other versions hide it in VS Code tasks that run when the folder opens. Atlassian has taken down hundreds of repositories built for this kind of fake assessment.
Does git clone copy hooks?
No. Client-side hooks are not copied when you clone a repository, so a cloned project starts with only git's inactive samples. That is why this attack arrived as a zip, which does carry the .git folder and its hooks.
Is reading the code before running it enough?
Not on its own. Here the code was an unmodified copy of someone's real project, and the attack sat in a folder that is not part of the code and that most editors hide. Read the hidden folders as well, and run take-homes on a throwaway machine.
Does git commit --no-verify protect me from malicious hooks?
Only partly. It skips the pre-commit and commit-msg hooks for that one commit. Other hooks, such as post-checkout and post-merge, still run on other commands.
Was Binance hacked through a git hook?
Binance has not said so. Its report says an engineer was told in a fake interview to download an "assignment" onto his work computer and that its code ran during setup, without saying how. The git hook case in the video is a separate example of the same kind of lure.
Can opening a folder in VS Code run code?
It can, if the folder's .vscode/tasks.json defines a task set to run on folder open and automatic tasks are allowed. Setting task.allowAutomaticTasks to off, and not trusting folders you do not know, stops it.
What should I do if I already ran a suspicious take-home?
Disconnect the machine and tell your security team if it is a work device, rotate every password, token and key it could reach from a different clean device, and reimage it. Deleting the project folder is not enough, because the second stage installs itself elsewhere.
// further reading
- I Inspected My Take-Home Interview Project. It Was a Whole Operation. ↗: the July case in full, with the developer's analysis of each stage.
- From fake interviews to malicious repositories: Disrupting Contagious Interview ↗: Atlassian's findings across the campaign, its defensive checklist, and a link to the full research report with indicators of compromise.
- 29 October 2026 Binance Security Incident: Initial Findings and Response Update ↗: Binance's own account of the incident and the fake interview behind it.
- Pro Git: Git Hooks ↗: what each hook does, how they are installed, and why a clone does not copy them.
// transcript
This take-home test runs malware the moment you commit. Every file you'd open is a clean copy of somebody's real FastAPI app, and the malware sits in a folder nobody reads, where git runs it for you. Git has a feature called hooks, scripts it runs by itself at moments like a commit, and teams use them to run a linter or the tests before anything gets saved. They live in the hidden .git folder, so they never show up in a diff or in most editors, and cloning a repository doesn't copy them, which is why this one came as a zip, since a zip carries the hidden folder along. In July, a developer who'd been sent one by a LinkedIn recruiter found the code clean, and only caught it because they always list hidden folders, which turned up twenty-two hooks already set up. The instructions made sure they'd run some git commands, and the pre-commit hook was a few lines that downloaded a script from a server and ran it in the background, with its output thrown away. Atlassian, which runs Bitbucket, has taken down hundreds of repositories built for this lure, and almost half hide more than one trigger, like a VS Code task that runs when you open the folder. So reading the code first, which everyone tells you to do, wouldn't have saved you, because the attack was never in the code. What does save you is where you run it, so do take-homes on a spare machine or a throwaway VM, never on a work laptop with real credentials, and before any git command, open the hooks folder and switch off VS Code's automatic tasks, so if something fires anyway, there's nothing for it to reach. A Binance engineer did the opposite in September, when a fake interviewer had him download an assignment onto his work computer, and its code ran during setup. On October twenty-ninth, working outward from that computer, attackers moved about $6.3 billion in crypto out of Binance. A take-home is a stranger's code, so give it a machine with nothing on it worth taking.
// source
This explainer is based on I Inspected My Take-Home Interview Project. It Was a Whole Operation. by Appaji C. (citizendot) ↗. The original reporting and technical work belong to its publisher.