Researchers say they’ve discovered a supply-chain attack flooding repositories with malicious packages that contain invisible code, a technique that’s flummoxing traditional defenses designed to detect such threats.
The researchers, from firm Aikido Security, said Friday that they found 151 malicious packages that were uploaded to GitHub from March 3 to March 9. Such supply-chain attacks have been common for nearly a decade. They usually work by uploading malicious packages with code and names that closely resemble those of widely used code libraries, with the objective of tricking developers into mistakenly incorporating the former into their software. In some cases, these malicious packages are downloaded thousands of times.
Defenses see nothing. Decoders see executable code
The packages Aikido found this month have adopted a newer technique: selective use of code that isn’t visible when loaded into virtually all editors, terminals, and code review interfaces. While most of the code appears in normal, readable form, malicious functions and payloads—the usual telltale signs of malice—are rendered in unicode characters that are invisible to the human eye. The tactic, which Aikido said it first spotted last year, makes manual code reviews and other traditional defenses nearly useless. Other repositories hit in these attacks include NPM and Open VSX.
The malicious packages are even harder to detect because of the high quality of their visible portions.
“The malicious injections don’t arrive in obviously suspicious commits,” Aikido researchers wrote. “The surrounding changes are realistic: documentation tweaks, version bumps, small refactors, and bug fixes that are stylistically consistent with each target project.”
The researchers suspect that Glassworm—the name they assigned to the attack group—is using LLMs to generate these convincingly legitimate-appearing packages. “At the scale we’re now seeing, manual crafting of 151+ bespoke code changes across different codebases simply isn’t feasible,” they explained. Fellow security firm Koi, which has also been tracking the same group, said it, too, suspects the group is using AI.

If I'm understanding the attack correctly (and I'm fairly sure I am), it consists of encoding malicious code in an otherwise entirely normal, or at least abnormal-but-legitimate, UTF-8 string within the code, which decodes to code which is then executed.
It is functionally equivalent to, say, ‘encrypting’ that malicious code in a ROT13 string, and including an inline ROT13 decoder, which is run on the string before executing it. The ‘encryption’ here is barely more sophisticated than that. The only difference – and it's a crucial one – is that any reviewer would surely notice a sodding big block of ROT13 code in a patch, whereas in this case (I would lay money) most editors and renderers would display the block of ‘encrypted’ code as an empty string, which is easy to miss.
The clever thing is that the editors are not malfunctioning when doing this, and any attempt to make them display the characters would potentially count as a bug. Even if a code-reviewer thought that the
evallooked weird, they'd have to work through the decoder, and know an relatively unusual amount about Unicode, in order to work out what was going on.The codepoints in question are actually not in any of the Unicode ‘private use areas’ (despite what the article suggests; and yes, I think it's ‘private use area’ that's intended, since there's no term ‘public use area’). The codepoint ranges U+FE00 to U+FE0F and U+E0100 to 0xE01EF are ‘variation selectors’. I'm moderately familiar with the Unicode spec and... I've never heard of them before! There's a handy Wikipedia page which tells us that they exist in order to do funky things to preceding CJK characters in selected east-Asian languages. You'd have to go head-first into the Unicode spec for the details (rather you than me), but I wouldn't be at all surprised if the required rendering behaviour for these in certain circumstances is... to show nothing.
That is, this apparently isn't exploiting any UTF-8 decoding bugs, or Unicode manipulation edge-cases. It seems quite likely that the rendering behaviour of these codepoints in strings is specified, and any editor which displayed the strings as other than empty ones might well be defective.
What a clever hack! Bastards.