[HN Gopher] First Self-Propagating Worm Using Invisible Code Hit...
       ___________________________________________________________________
        
       First Self-Propagating Worm Using Invisible Code Hits OpenVSX and
       VS Code
        
       Author : dnslavin
       Score  : 51 points
       Date   : 2025-10-20 19:05 UTC (3 hours ago)
        
 (HTM) web link (www.koi.ai)
 (TXT) w3m dump (www.koi.ai)
        
       | kulahan wrote:
       | For anyone else curious WTH "invisible code" is...
       | 
       | > invisible Unicode characters that make malicious code literally
       | disappear from code editors.
        
         | rictic wrote:
         | So, they have a custom decode function that extracts info from
         | unprinted characters which they then pass to `eval`. This
         | article is trying to make this seem way fancier than it is.
         | Maybe GitHub or `git diff` don't give a sense of how many bits
         | of info are in the unicode string, but the far scarier bit of
         | code is the `eval(atob(decodedString))` at the bottom. If your
         | security practices don't flag that, either at code review,
         | lint, or runtime then you're in trouble.
         | 
         | Not to say that you can't make innocuous looking code into a
         | moral equivalent of eval, but giving this a fancy name like
         | Glassworm doesn't seem warranted on that basis.
        
           | Terr_ wrote:
           | Yeah, doing eval(extract_and_decode(file)) is marginally
           | sneakier than eval(fetch_from_internet()) , but it's not so
           | far as being some sort of, er... "mirror life" biology.
        
         | moffkalast wrote:
         | Makes you wonder why unicode has invisible characters in the
         | first place and why a compiler would interpret them at all.
        
           | AnimalMuppet wrote:
           | The compiler doesn't. They get passed to decode, and then to
           | eval.
        
           | h4ck_th3_pl4n3t wrote:
           | It's not the compiler.
           | 
           | It's JavaScript and its fucked up UTF-16 strings.
           | 
           | UTF-16 should have been UTF-8 for a variety of reasons, and I
           | thought we have learned from the Effective power
           | luluSWbululSWburran LL LLh LL LL Rong  incident.
        
             | amingilani wrote:
             | The what incident? Can you elaborate?
             | 
             | Edit: Here's the incident-https://www.theregister.com/2015/
             | 05/27/text_message_unicode_...
        
       | fxtentacle wrote:
       | I call bullshit on this: "The attacker is using a public
       | blockchain - immutable, decentralized, impossible to take down -
       | as their C2 server."
       | 
       | "There's no hosting provider to contact, no registrar to
       | pressure, no infrastructure to shut down. The Solana blockchain
       | just... exists. "
       | 
       | Yes, but you still need to connect to it. Blocking access to
       | *.solana.com is enough to stop the trojan from accessing its 2nd
       | stage.
       | 
       | "Connections to Solana RPC nodes look completely normal. Security
       | tools won't flag it. "
       | 
       | Then your security tools are badly configured. Lots of crypto
       | traffic should be treated as a red flag in almost any corporate
       | environment.
       | 
       | "there's literally no way to take it down"
       | 
       | There is, you just have to accept that Solana goes down with it.
       | Why is A-OK in a work environment.
        
         | maccam912 wrote:
         | There's also the backup C2 path though, via google calendar.
         | Wayyy less of a red flag.
        
           | fxtentacle wrote:
           | I'm surprised that Google hasn't deactivated the link in the
           | 24+ hours since that article went online.
        
             | dns_snek wrote:
             | That should tell you (everyone) how much these companies
             | actually care about our security the next time they claim
             | to be stripping away our freedoms "for our security".
        
               | throwaway48476 wrote:
               | Google is a malware services company. They make money
               | when someone creates malware OBS and pays Google for it
               | to be the top result.
        
         | knallfrosch wrote:
         | That blocks Solana only on your corporate network.
        
         | djmips wrote:
         | Obviously... SMH - what a tough read this blog post was.
        
         | iSnow wrote:
         | >Yes, but you still need to connect to it. Blocking access to
         | *.solana.com is enough to stop the trojan from accessing its
         | 2nd stage.
         | 
         | How is that if you can just run a bunch of Solana RPC servers?
         | For what would you need to access solana.com or a subdomain?
        
         | rezonant wrote:
         | > There is, you just have to accept that Solana goes down with
         | it.
         | 
         | And nothing of value was lost.
        
       | nawgz wrote:
       | Cool write-up. Seems pretty unintuitive to me that Unicode would
       | allow someone to serialize normal code as invisible characters
       | and that something like an IDE or a git diff has never been
       | hardened against that at all.
       | 
       | In my mind it's one thing to let a string control whitespace a
       | bit versus having the ability to write any string in a non-
       | renderable format. Can anyone point me to some more information
       | about why this capability even exists?
        
         | clscott wrote:
         | The issue does not lie with Unicode.
         | 
         | It's just a custom string encoder/decoder whose encoded
         | character set is restricted to non-printables.
         | 
         | Many editors and IDEs have features (or plugins) to detect
         | these characters.
         | 
         | VSCode:
         | https://marketplace.visualstudio.com/items?itemName=YusufDan...
         | 
         | VIM: https://superuser.com/questions/249289/display-invisible-
         | cha...
        
         | dragonwriter wrote:
         | > Seems pretty unintuitive to me that Unicode would allow
         | someone to serialize normal code as invisible characters
         | 
         | If you have a text encoding with two invisible characters, you
         | can trivially encode anything that you could represent in a
         | digital computer in it, in binary, by treating one as a zero
         | and the other as a one. More invisible characters and some
         | opinionated assumptions about what you are allows denser
         | representation than one bit per character.
         | 
         | Of course, the trick in any case is you have to also slip in
         | the call to decode and execute the invisible code, and unless
         | you have a very unusual language, that's going to be very
         | visible.
        
         | wunderwuzzi23 wrote:
         | It gets even worse with LLMs and agents.
         | 
         | Many LLMs can interpret invisible Unicode Tag characters as
         | instructions and follow them (eg invisible comment or text in a
         | GitHub issue).
         | 
         | I wrote about this a few times, here a recent example with
         | Google Jules: https://embracethered.com/blog/posts/2025/google-
         | jules-invis...
        
       | gary_0 wrote:
       | If all you're interested in is which extensions have been
       | infected:
       | 
       | Compromised OpenVSX Extensions:
       | codejoy.codejoy-vscode-extension@1.8.3         codejoy.codejoy-
       | vscode-extension@1.8.4         l-igh-t.vscode-theme-seti-
       | folder@1.2.3         kleinesfilmroellchen.serenity-dsl-
       | syntaxhighlight@0.3.2         JScearcy.rust-doc-viewer@4.2.1
       | SIRILMP.dark-theme-sm@3.11.4         CodeInKlingon.git-worktree-
       | menu@1.0.9         CodeInKlingon.git-worktree-menu@1.0.91
       | ginfuru.better-nunjucks@0.3.2         ellacrity.recoil@0.7.4
       | grrrck.positron-plus-1-e@0.0.71         jeronimoekerdt.color-
       | picker-universal@2.8.91         srcery-colors.srcery-colors@0.3.9
       | sissel.shopify-liquid@4.0.1         TretinV3.forts-api-
       | extention@0.3.1
       | 
       | Compromised Microsoft VSCode Extensions:                   cline-
       | ai-main.cline-ai-agent@3.1.3
        
         | benxh wrote:
         | cline is used by a lot of devs
        
       | DiabloD3 wrote:
       | And this is why you don't use VSCode.
        
         | dist-epoch wrote:
         | Do you also not use SSH? Because that was also infected last
         | year (XZ)
        
         | agile-gift0262 wrote:
         | and this is why you must minimise and be extra careful with the
         | extensions you install in your editor of choice.
        
         | h4ck_th3_pl4n3t wrote:
         | Imagine a worm written in VimL or emacs lisp.
         | 
         | Haha, that would be kinda fun as an experiment :D
        
       | afishhh wrote:
       | Using non-printable characters to encode malicious code is
       | creative, but I wouldn't say it "breaks our security model".
       | 
       | I would be pretty suspicious if I saw a large string of non-
       | printable text wrapped in a decode() function during code
       | review... Hard to find a legitimate use for encoding things like
       | this.
       | 
       | Also another commenter[1] said there's an eval of the decoded
       | string further down the file, and that's definitely not
       | invisible.
       | 
       | Has no one thought to review the AI slop before publishing?
       | 
       | [1] https://news.ycombinator.com/item?id=45649224
        
         | codebje wrote:
         | There's no self-propagation happening, that's just the terrible
         | article's breathless hyping of how devastating the attack is.
         | It's plain old deliberately injected and launched malware.
         | OpenVSX is a huge vector for malicious actors taking real
         | Marketplace extensions, injecting a payload, and uploading
         | them. The article lists exactly one affected Marketplace
         | extension, but that extension does not exist.
         | 
         | > Has no one thought to review the AI slop before publishing?
         | 
         | If only Koi reviewed their AI slop before publishing :(
        
       | TheServitor wrote:
       | "Here's the thing - this technique completely breaks traditional
       | code review. You can't spot what you can't see. GitHub's diff
       | view? Shows nothing suspicious. Your IDE's syntax highlighting?
       | All clear. Manual code inspection? Everything looks normal.
       | 
       | The invisible code technique isn't just clever - it's a
       | fundamental break in our security model. We've built entire
       | systems around the assumption that humans can review code.
       | GlassWorm just proved that assumption wrong."
       | 
       | This is pure Claude talk.
        
         | dingnuts wrote:
         | it sure is and it's complete bullshit too!
         | 
         | that screenshot looks suspicious as hell, and my editor (Emacs)
         | has a whitespace mode that shows unprintable characters sooooo
         | 
         | if GitHub's diff view displays unprintable characters like this
         | that seems like a problem with GitHub lol
         | 
         | "it isn't just X it's Y" fuck me, man. get this slop off the
         | front page. if there's something useful in it, someone can
         | write a blog post about it. by hand.
        
         | 1bpp wrote:
         | Claude, remember to always replace em-dashes with a single dash
        
         | burkaman wrote:
         | Yeah the whole article is awful to read. Everything the LLM
         | added is completely useless fluff, sometimes misleading, and
         | always painful to get through.
        
           | r_lee wrote:
           | Alright, no fluff. Only real talk. It's not just a great
           | argument--it's the truth. You're absolutely right.
        
       | wrs wrote:
       | That's clever, but if your code review missed the perfectly
       | visible line                   eval(atob(decodedString))
       | 
       | then they didn't really need invisible characters to get past
       | you, did they?
        
         | rezonant wrote:
         | Ahh but what if you are code reviewing a malware package
         | already? Then this would be entirely normal!
        
       | vemv wrote:
       | What are the specific "Unicode variation selectors" in question?
       | 
       | I'd like to implement some simple linting against them.
        
       | lennartkoopmann wrote:
       | I was always afraid of browser extensions and now I'm also afraid
       | of IDE extensions. Recently came across SecureAnnex[0] and it
       | looks promising to get some control over it.
       | 
       | [0] https://secureannex.com/
        
       | sublinear wrote:
       | > Let me say that again: the malware is invisible. Not
       | obfuscated. Not hidden in a minified file. Actually invisible to
       | the human eye.
       | 
       | I stopped reading at this point. This is not only false, but yet
       | another strong reason to lint out the silly nonsense people
       | argued for on here years ago. No emoji, no ligatures, etc.
        
       | blauditore wrote:
       | Why not just indicate non-printable characters in code review
       | tools? I've always wondered that, regardless of security
       | implications. They are super rare in real code (except line
       | breaks and tabs maybe), so no disruption in most cases.
       | 
       | Also, as notes in other comments, you can't do shady stuff purely
       | with invisible code.
       | 
       | The article seems bit sensationalist to me.
        
       | a-dub wrote:
       | vim-plug with pinned hashes and manual reviews ftw!
        
       | OptionOfT wrote:
       | I have started denying any kind of non-ASCII characters in the
       | source code.
       | 
       | I understand this is extremely limiting, but it does do the
       | trick. For now.
        
         | AnimalMuppet wrote:
         | I mean, someone could still run a string of _printable_
         | characters into  "decode" and then "eval"...
        
           | OptionOfT wrote:
           | At least that is visible in a PR.
        
         | rkagerer wrote:
         | This is an old-man rant, but the first time I saw Unicode I
         | felt like I was looking at a train wreck coming from a long way
         | off. It has too many edge cases, footguns and unintuitive
         | artifacts like this. I wish we constrained its use to only
         | where required. Text was so much easier to reason about and
         | safer to manipulate in the ASCII days.
        
           | OptionOfT wrote:
           | I don't think it's an old-man rant. I think experience comes
           | with age, but I don't associate with old-man (yet).
           | 
           | It's about safety.
        
       ___________________________________________________________________
       (page generated 2025-10-20 23:02 UTC)