back to article How to find NPM dependencies vulnerable to account hijacking

Following the recent disclosure of a technique for hijacking certain NPM packages, security engineer Danish Tariq has proposed a defensive strategy for those looking to assess whether their web apps include dependencies tied to subvertable email domains. NPM, acquired by Microsoft's GitHub in March 2020, operates the NPM …

  1. Mike 137 Silver badge

    Blinding stupidity abounds

    "identifying NPM packages managed by email accounts tied to expired domains. By registering the expired domain, the attacker then gains control of any email addresses associated with that domain."

    I've always thought it utterly idiotic to use a publicly known credential such as an email address as an access identifier for a resource, particularly where said email address is also used to engage with password management for that resource. However it seems almost universal these days. Not surprising then that security breaches of resources such as these NPM respositories occur.

  2. Pascal Monett Silver badge

    "an opportunity to preempt this threat"

    Here's another one : don't download anything to your production server before validating it on your test server.

    Because you have a test server, right ?

    RIGHT ?

    1. Anonymous Coward
      Anonymous Coward

      Re: "an opportunity to preempt this threat"

      Test servers are a sign of weakness, a bit like using a version control system or doing backups.

      That's why all my development is on the production servers, as root of course. And I only use unmaintained dependencies (the more of them the better), to show them that I'm not afraid.

      I'm available for hire, by the way.

      1. bombastic bob Silver badge
        Happy

        Re: "an opportunity to preempt this threat"

        heh - the snark is STRONG with THIS one!

    2. Anonymous Coward
      Anonymous Coward

      Re: "an opportunity to preempt this threat"

      Sooo 2000s (and yes I did have test servers back in the day)

      Nowadays you have snapshots for your VMs and backups that can be restored quickly and replicas of your VMs. You rarely have to go back to tape these days.

      Yesterday I restored my home PBX because (salient facts):

      * I'm an IT bod - obvs we have a home PBX

      * Wife does dog boarding at home

      * We have electric underfloor heating, a fairly open floor plan and 75% of ground floor is laminate. U/F is connected to its own consumer unit (UK) with ten zones

      * IT gear is mostly in the attic - VMware esxi (Dell T420) and router and switch and other stuff

      * IT gear in the attic is powered off one of the U/F circuits with a UPS

      * ... leaky dog ... ... very leaky dog ...

      I have yet to 100% confirm that a dog killed one room's underfloor heating but it is rather likely. I've got five out of ten zones switched off via the consumer unit and one of the switched off zones is where they pissed. Whilst working out what the hell was happening I flicked power off and on a few times.

      The Dell VM host decided that its battery backed cache on the RAID had lost data. I'm not sure exactly why because I monitor all my gear and my customers with Icinga1 and 2 (migration ongoing) and none of the logs indicated a problem. Power went out, UPS depleted and box crashed. Outage was about 12 hours but the battery on RAID should have managed several days at least.

      I had three MariaDBs on that box and two went wibble. I recovered my PBX from backup (Veeam), my Nextcloud was fine and Zoneminder needed a parameter to ignore knackered data in INNODB and I also had to delete the redo logs (which I thought should have saved me - nope) and I was able to dump the zm databases to files. I recreated my ZM db and dumped the data back in.

      Backups are quite handy,

  3. Anonymous Coward
    Anonymous Coward

    I'll never understand how NPM is still a thing

    Here's an idea, you can have 17 layers of depedencies in your code, we'll make sure the links in place at the repo all you worry about is the top level directly under your code. Meanwhile Scumbag Sam decides to "corrupt" something at the bottom of the stack for their own twisted ends or just for shit'n'giggles and next thing your latest project is a serious security threat.

    1. Brewster's Angle Grinder Silver badge

      2347

      I'm most definitely not a fan of it. But it only magnifies a problem that has always existed. Any code you didn't write yourself could be corrupted by a "scumbag". Fortunately programmers are more collaborative than financiers so the instances of corruption are mercifully rare and rarely malicious.

      1. Filippo Silver badge

        Re: 2347

        That is true. However, the word "only" there is carrying quite a lot of weight.

        In my main desktop application, which is written in .NET, I effectively depend on two library providers (three if you count Microsoft), both of them well-known businesses that are not easily impersonated. I also used to sell an older C++/MFC version, which depended on three providers, again all well-known. And due to the way both those environments are structured, it's unlikely that any of those libraries has further external dependencies that I'm not aware of.

        The last time I had to work on a JS project, it had over 800 dependencies, and that was for a project far simpler than either the .NET or C++ applications I mentioned earlier. Many of those dependencies were published by little more than "some guy somewhere". At some point, if you have the same problem, "only" it's over two orders of magnitude bigger... well, it's not the same problem any more.

        1. Anonymous Coward
          Anonymous Coward

          Re: 2347

          I think you might be getting a false sense of security.

          For code of equal complexity we can expect very roughly equal effort. It is possible that your libraries have little code reuse but even then they will be relying on a bunch of lower level libraries and so on and so forth.

          I bet that if you do an ldd on your program you will find a lot more than the three vendors that you mention.

          Not to minimise the problem, which is very real, but I think tools like Node.js are actually helping to a point by making the reuse more visible.

          1. Filippo Silver badge

            Re: 2347

            > For code of equal complexity we can expect very roughly equal effort.

            Yes, but in the JS world that effort is spread across hundreds of distinct sources, many of which are difficult to verify. I probably use hundreds of libraries in my projects, but nearly all of them come bundled with the OS or with the main SDK. Extremely difficult to impersonate.

            The same goes for third-party libraries - they in turn can rely on the same vast body of hard-to-impersonate system libraries, so they have few, if any, fourth-party dependencies.

            1. Brewster's Angle Grinder Silver badge

              Re: 2347

              "...hard-to-impersonate system libraries..."

              I'm not sure what it's like with modern Windows. But I'm old enough to have replaced system DLLs with my own wrappers so I could alter the functionality on the way through... But we're really talking about supply chain attacks where the scumbag has access to the source and can tweak it (and recompile if needed) to meet their nefarious ends.

              The point you are making is that it's easier to delegate trust to a few organisations (the OS manufacturer and purveyors of certain libraries) than having to trust ?hundreds of collectives and/or individual devs. (N.B. The number of dependencies can be misleading as marquee projects are often componentised into dozens of modules and plugins from the official team.)

              I do think that's a reasonable point; hierarchies make management tractable. I suppose the counterargument is nothing has changed: your relationship is with those top level dependencies you install. You are trusting those teams to have done their due diligence. You can at least now see what dependencies they have whereas you were completely unaware of what was #include or statically linked into the DLL. If that teams screws up you can drop them just as you could have dropped a company producing a DLL.

              I actually think the bigger problem is you end up with four different libraries doing the same thing in slightly different ways. But that's what happens when its free. People don't have time. So, even if they could write something themselves, they grab tools other have written, and the sprawl goes. Nobody consolidates and rationalises. And trying to under the knots become harder and harder.

    2. bombastic bob Silver badge
      Pirate

      Re: I'll never understand how NPM is still a thing

      Scumbag Sam

      heh - that reminds me of a video game that has N.P.C.s known as "Thieving Scumbags". But they are useful in the game, if you use items to multiply your monetary gain at the end of a battle, it will also multiply any "recovered" loot stolen by scumbags that you kill (without letting them escape from battle). If properly hacked, you can get millions of currency units pretty fast by manipulating the scumbag characters like that, letting them steal, . and then 'recover' it by killing them before they escape.

      (IRL I wish I could do the same thing - see icon)

  4. John Geek
    Facepalm

    I've come to the conclusion that the average NodeJS developer knows as much about software engineering as a kid playing with Lego knows about architecture and structural engineering.

    1. Anonymous Coward
      Anonymous Coward

      re: nodejs developers

      i think you give them too much credit. I think they're worse than that.

  5. captain veg Silver badge

    > Danish Tariq has proposed a defensive strategy for those looking to assess whether their web apps include dependencies tied to subvertable email domains.

    I believe that my own defensive strategy is better: don't trust code just because it has been published on some random public repository. Write it yourself, or at the very least review what you're importing.

    > security researchers scanned NPM and found 2,818 maintainer email addresses associated with expired domains, through which they had the opportunity to hijack 8,494 packages via account takeovers.

    There you go.

    > "Few understand that code copied from the internet from strangers needs to be reviewed under the same scrutiny, if not higher, than code written by employees,"

    Aha. So I'm not the only one.

    Why do this to yourself? If you can, write the code yourself. If you can't, well, how can you have any kind of opinion about the quality of what you're importing from unverified sources?

    -A.

    1. Randomuser

      What if?

      What if you have reviewed what you imported but the maintainer behind that package is using some dumb email address like blabla@expireddomain.com , and after a few months some malicious actor claims the expireddomain.com and pushes a new update on that package (maybe an urgent security update) in that case there is a possibility that you update that package (as you would assume that you had reviewed the package initially) and go on with updating but now the updated one would have that malicious stuff.

      In short, the first maintainer or developer was not malicious but was dumb or ignorant to use an email address that would not be maintained after a few years leaving it expired and claimable which eventually means the access of maintainer level to some NPM package unclaimed available for some malicious owner.

      Your strategy is good but the defense strategy in this article is for these types of cases.

      1. captain veg Silver badge

        Re: What if?

        It's a fair question, but the "urgent security update" would have to make sense in the context of what I already know about the code, because I reviewed it. And I would review the update, natch.

        The best protection against getting pwned is Not Being A Muppet. Let's at least try.

        -A.

  6. Falmari Silver badge
    Facepalm

    Unvalidated Updates added to packages!

    Why are updates added to packages like NPM released without review and testing?

    A change is made and it is included without any validation in the next update of packagers like NPM which is then got by developers.

    They way I see it is the packagers are at fault for not validating what the release. The developers are at fault for not validating what the pull down into their projects.

    1. bombastic bob Silver badge
      Unhappy

      Re: Unvalidated Updates added to packages!

      the whole system is a house of cards In My Bombastic Opinion.

      And WHO gets the midnight phone call to correct the problem caused by an update to a trivial and insignificant shared thing that's merely in the dependency list and NOT even relevant to your code? Why YOU do, of course!

      It's as bad as DLL HELL, and maybe even WORSE. [also why I statically link or build from source on a target platform whenever practical]

      1. nagyeger

        Re: Unvalidated Updates added to packages!

        Exactly. But this 'rapid deployment' seems to be the whole point of the system.

        NPM? Not on *my* machine, you don't.

  7. Coen Dijkgraaf

    Enhanced login verification - wouldn't stop expired domain issue

    > NPM has subjected this group to "enhanced login verification," which involves receiving an emailed one-time code on login to confirm account control. To avoid this extra step, you have to activate 2FA.

    Having it email a one-time code to an domain that has expired and taken over by a bad actor would not help prevent the takeover in any way unless that code was sent before the domain expired.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon

Other stories you might like