Live data from Hacker News

Glassworm is back: A new wave of invisible Unicode attacks hits repositories

aikido.dev

151–160 of 201 posts

Re: Glassworm is back: A new wave of invisible Unicode attacks hits repositories

#151

Earlier quoted context omitted.

Please explain why an invisible zero width "character" is necessary.

To prevent ligatures from forming when you need that.

That's the job of a typesetting language.

Re: Glassworm is back: A new wave of invisible Unicode attacks hits repositories

#152
post #85

Earlier quoted context omitted.

> Yes. Unicode should not be about semantic meaning, it should be about the visual. Like text in a book. Do you think 1, l and I should be encoded as the same character, or does this logic only extend to characters pesky foreigners use.

They are visually distinct to the reader.

[dead]

Re: Glassworm is back: A new wave of invisible Unicode attacks hits repositories

#153

I keep seeing this and wondering if the ESLint default rules against weird characters would catch this? But I can’t figure out how to check.

Appears not to. https://claude.ai/share/ac070cf5-0034-4f3c-9a8c-1c43a58eea36

Claude’s analysis seems solid here based on reading the snippets it tested.

A purpose-built linter could be cross-language, it’s pretty reasonable to blanket ban these characters entirely, or at least allowlist them.

Re: Glassworm is back: A new wave of invisible Unicode attacks hits repositories

#154
post #7

The `eval` alone should be enough of a red flag

Sadly JS has ways around it that is far from obvious since you can chain effects over multiple files that leads to running code.

Like the following example (you can paste it into node to verify), could be spread out over multiple source files to make it even harder to follow:

  // prelude 1, obfuscate the constructor property name to avoid raising simple analyser alarms
  const prefix = "construction".substring(0,7);
  const suffix = "tractor".substring(3);
  const obfuscatedConstructorName = prefix + suffix; // innocent looking, but we have the indexing name.

  // prelude 2, get the Function class by indexing a function object with our constructor property name (that does not show up in source-code)
  const existingFunction = ()=>"nothing here";
  const InnocentLookingClass = existingFunction[obfuscatedConstructorName];

  // payload decoding elsewhere (this is where we decode our nasty source)
  const nastyPayloadDisguisedAsData = "console.log('sourced string that could be malicious')";

  // Unrelated location where payload gets executed
  const hardToMissFun = new InnocentLookingClass(nastyPayloadDisguisedAsData);
  hardToMissFun(); // when this function is run somewhere.. the nasty things happen.
Unless you have a data-tracing verifier or a sandbox that is continiously run it's going to be very hard to even come close to determining that arbitrary code is being evaluated in this example. Not a single trace of eval or even that the property name constructor is used.

Re: Glassworm is back: A new wave of invisible Unicode attacks hits repositories

#155
post #85

Earlier quoted context omitted.

> Yes. Unicode should not be about semantic meaning, it should be about the visual. Like text in a book. Do you think 1, l and I should be encoded as the same character, or does this logic only extend to characters pesky foreigners use.

They are visually distinct to the reader.

That is entirely dependent on the font.

Re: Glassworm is back: A new wave of invisible Unicode attacks hits repositories

#156

Earlier quoted context omitted.

It already works. Tell me what the problem is and what your proposed solution would be.

Infer the meaning from the context. a) it's a bullet point b) a+b means a is a variable c) apple means a means the sound "aaaah" d) ape means a means the sound "aye" e) 0xa means a means "10" f) "a" on my test paper means I did well on it g) grade "a" means I bought the good bolts h) "achtung" means it's a German "a" I didn't need 8 different Unicode characters. And so on.

Your trolling is really rock bottom. All this already works fine. Millions of times, each day. Just once a week it fails because someone messed up. Not an issue.

Re: Glassworm is back: A new wave of invisible Unicode attacks hits repositories

#157
I don't quite understand how this is working tbh. I looked at one of the affected repos, ironically named "reworm".

The malicious code was introduced in this commit - https://github.com/pedronauck/reworm/commit/d50cd8c8966893c6...

It says coauthored by dependabot and refers to a PR opened in 2020 (https://github.com/pedronauck/reworm/pull/28).

That PR itself was merged in 2020 here - https://github.com/pedronauck/reworm/commit/df8c1803c519f599...

But the commit with the worm (d50cd8c), re-introduces the same change from df8c180 to the file `yarn.lock`.

And when you look at the history of yarn.lock inside of github, all references to the original version bump (df8c180) are gone...? In fact if you look at the overall commit history, the clean df8c180 commit does not exist.

I'm struggling to understand what kind of shenanigans happened here exactly.

Re: Glassworm is back: A new wave of invisible Unicode attacks hits repositories

#159
This gets a lot worse when a coding agent is in the loop. A human at least has a review step—an autonomous agent that reads a Glassworm-infected file just acts on it. The fix probably needs to happen at the tool result layer, before the payload ever enters the agent's context, not just on what the agent writes out.

Re: Glassworm is back: A new wave of invisible Unicode attacks hits repositories

#160

[dead]

Grepping your own source for variation selectors is the easy part. The problem is nobody's doing that on what they install. A compromised upstream package lands those characters in your node_modules and your CI never looks twice. `npm audit signatures` catches some supply chain stuff but not this. Honestly surprised no package manager has a "scan installed files for suspicious Unicode" step yet.
Post reply on HN