matt.log()

I’m a Senior Software Engineer, open-source contributor, and product builder with 15 years of experience. I share my experiences and observations in software engineering, web technologies, and the reality of shipping great software.

Matt Stypa profile picture

How the Axios maintainer was hacked

When the Axios story broke, a lot of us did the same thing. We checked lockfiles, read the advisory, maybe cursed once. That is how you protect your own builds. The sequence that mattered started earlier. Someone got onto Jason Saayman’s machine first, and malicious Axios releases on npm followed from his account. I am not here to rehash every technical detail. I want to talk about how ordinary that setup looked. I think I could be tricked by something like it too.

What happened first

Attackers pretended to be a company founder and had put enough work into the look of the person and the company that the first message did not obviously look fake. Threat actors brought Jason into a Slack that looked like a real company workspace. Channels looked active. Fake teammates dropped LinkedIn style posts that could have pointed at a legit account somewhere else. There were profiles that looked like a team, and Jason said there were even profiles that looked like other open source people. The workspace was set up to look like a real company.

Then came a Teams call with several people on it. Something on Jason’s machine was “out of date.” He installed an updated that was sold as a fix for Teams. That was the malware. Hackers took their time. The operation was coordinated and looked professional. It was not a sloppy link in a rush email.

Google’s threat intel folks tie this kind of campaign to UNC1069 and similar reporting on fake execs and AI assisted faces. Crypto teams have been seeing the same method for a while. Axios was the same approach with a different outcome. Attackers wanted a computer that could reach npm accounts, not one wallet.

Why this worries me

The stories from people who study these attacks all sound the same after a while. The relationship stretches over weeks. Meetings move around so you never feel hustled. The call can look fine in the browser. Then audio breaks, or something feels off, and the person you trust tells you how to fix it. Maybe a tiny script. Maybe paste this in Terminal. Maybe double click something that runs AppleScript. After that your machine checks in on a timer and someone on the other end can push more junk. I have sat on calls where I would have wanted to be polite and move things along. That patience is what attackers count on.

If you are thinking “I am nobody,” I get it. I still think package maintainers are squarely on attacker lists now. One publish session can reach a staggering number of machines. You do not have to be famous. You just have to own a name a lot of people trust.

Jason and others are blunt about MFA. Once someone runs code on your laptop, a Yubikey does not undo the fact that an attacker is already on your system. Folks who do incident response talk about threat actors who learn your hours, reuse your logged in sessions, and keep going long enough to establish persistence on the machine. What I remember most from those threads is short. Do not let strangers talk you into running things on the machine where your keys live.

What you can do to protect yourself

None of this is a corporate checklist. It is what actually matches how these attacks work in practice.

The attack Jason described was aimed at someone generous enough to take a meeting and competent enough to fix a “small” IT problem. The defense that fits can feel rude in the moment. Hang up. Verify. Say no to the paste.

Let me know what you think on Blusky

The Dark Software Factory is a lie

AI

BCG Platinion’s essay on the “Dark Software Factory” borrows an image from manufacturing. Picture a plant that runs with the lights off because nobody has to be on the floor. In their version, AI agents build, test, and ship around the clock. People supply intent and check the results. Whoever sets up the factory well and says clearly what they want is supposed to win. The article reads well, it cites sources, and it sounds like this shift is already normal.

It is also a sales pitch dressed up as a forecast. You are usually not buying the software that comes out the other end. You are buying the transformation package, the harness, the governance story, the training plan, and the hope that your company will be the next case study. I am not saying every number in there is wrong. I am saying we should split what the tools really do from what the deck needs you to feel.

None of this means I think models are a waste. We have all seen code show up faster than we could type it, and plenty of us have shipped real work that way. The fight is over what problem we think we solved. After a while you notice that the expensive part of software was almost never typing. It was figuring out what “right” even means, which tradeoffs matter, which edge cases count, and what failure you can accept. That work takes rounds. It does not vanish because the model got faster.

In practice the loop looks the same for me. I ask for code. The first cut is believable and wrong in the usual first cut ways. I tighten the ask, narrow the design, call out invariants, and go again. The gap between what I asked for and what I would ship gets wider as the task gets bigger. I do not treat that as a temporary rough patch until the next release. I treat it as the job, the same back and forth you have always had with a junior engineer, just sped up.

The pushback you hear is that the spec was the problem. If only intent had been clearer, if the org had invested in “intent thinking,” the factory would have nailed it on the first try. That is a neat way to blame the customer. A spec that is complete enough to deliver exactly what I want, with the tradeoffs and edge cases I would have caught in review, is not lighter work than building the thing. It is the build, just written in English. And English is a bad tool for that job. It is great for getting aligned. It is bad at being exact. We built types, contracts, tests, and invariants for a reason. Prose does not turn precise because we are in a hurry.

So the real question is not whether agents can write code. They can. The question is whether we admit what still limits us. For me the limit never moved from my hands to my prompts. It is still the messy part where you figure out what you are building, weigh bad options, and pick what to live with. Models help me read APIs I do not have memorized, try approaches I would have coded more slowly, and push through the middle of a feature once I know what done looks like. That is real help with learning and execution. It is not a way to skip the part where you decide what is worth building.

When someone sells a “dark” factory where the lights are off and people mostly think in intent, ask what you are actually trading for. You will get process, urgency, and a story that more output equals better judgment. I use these tools a lot, and I still want the lights on. The work that keeps software from falling apart is still the slow stuff, the review, and the plain work of knowing what you are making. An empty factory floor looks great in a photo. It is not how I would describe a team that ships good work.

Let me know what you think on Blusky

About me

I’ve spent about fifteen years building software for the web. My most recent role was at Block; before that, Neighborhoods.com and earlier stops I’ll mention below. Most of that recent work sat in TypeScript, React, Vue, and Node, but the through line is longer: I came up through PHP and Laravel, and that background still colors what I optimize for. Uptime matters. Clarity for the person using the product matters. So does being honest about whether the system is actually tested and observable, or merely impressive in a slide deck.

Photo from Laracon, the Laravel community conference

When I can, I contribute to open source, keep a few tools of my own, and send patches upstream (Tailwind CSS among them). I’m interested in building in public and in narrowing the gap between an idea and something shipped. This site is where I write about that tension: the discipline of craft, the velocity of the industry, and what it takes to build well with other people.

Most recently at Block, my work tended to braid a few threads. I explored how AI can augment engineering in durable ways: quicker iteration, less mechanical refactors, tests and documentation that stay tethered to the code. I helped shape internal tooling so teams weren’t reinventing the same patterns (skills, conventions, MCP servers, and the glue between them). I was also involved in large customer facing web and commerce launches, where the goal is a calm rollout rather than a heroic rescue. I gravitate toward solid automated tests, monitoring you can act on, and metrics that answer a question instead of filling a dashboard.

At Neighborhoods.com I led engineering through a stretch where the company grew fast and the team roughly tripled. That meant architecture calls, evolving the stack, CI/CD and containers, and codifying how we wanted to work, not only what we shipped. I’m proud of the products we delivered and of helping people grow into stronger engineers along the way.

Earlier roles rounded out the picture. At DOSE I worked on very high traffic properties, performance and caching, and a gradual move from monolith toward microservices on Docker, with server rendered React in the mix for SEO and speed. At NMI I worked in payments under tight compliance constraints, shipped iOS work in Swift and Objective-C, and touched some of the earlier Payment Facilitation integrations in the market. At Aisle Rocket I focused on PHP and MySQL, built shop.oraquick.com from the ground up, and collaborated on cookmore.com, which picked up a CIMA Star Award for B2C.

Outside of employment, I think of myself as a maker. Sometimes that means code, sometimes wood, metal, ink, or whatever the idea asks for. I like the process of turning nothing into something you can point at. I have a line tattooed on my arm: Idle hands build nothing. It’s a reminder I’m happy to wear.

Tattoo on my arm with the words Idle hands build nothing

If you’re still reading, we may share some priorities: ship with intent, take risk seriously without moving at a crawl, and treat the human side of the work as part of the job, not an afterthought. That’s the territory I plan to write from here. I’m glad you’re here.