OpenAI's response to the Axios developer tool compromise (openai.com)

80 points by shpat 11 hours ago

fortuitous-frog 9 hours ago

Interesting that (1) this blog post published on April 10th, 10 days after the Axios compromise, and (2) this was emailed to ChatGPT / Codex users yesterday, April 21st, 11 days after the blog post...

After an incident as widely publicized as Axios, I'd expect dependency auditing, credential rotation, and public incident communication to all be carried out with much more urgency. And if they were going to send this out to all of their users (as they should), I would expect _that_ to happen shortly after publishing the post (why wait 11 days???).

himata4113 9 hours ago

"April 10, 2026"

I don't blame you, took me awhile to find the date.

danscan 9 hours ago

Axios, like Express, is something I'm shocked to see used in any modern codebase. I loved both in the 2010s. In JS/TS-land there are much simpler and better options these days. Depending on Axios suggests the devs don't know how to use fetch. I can't think of another reason it would be a necessary dependency

zarzavat 7 hours ago

> Depending on Axios suggests the devs don't know how to use fetch.

You could equally say that using fetch means that the developers don't know how to use axios.

They do the same thing, except axios does it a little better, when it doesn't pwn you.

Axios predates the availability of fetch in node by 2 years, and fetch has never caught up with axios so there was no reason to switch to fetch, unless you need to run on both client and server then of course you use fetch.

kamranjon 6 hours ago

In what ways has fetch never caught up to axios? I have not encountered a situation where I could not use fetch in the last 5 years so I'm just curious what killer features axios has that are still missing in fetch (I certainly remember using axios many moons ago).

junon 5 hours ago

mattmanser 6 hours ago

worble 2 hours ago

> when it doesn't pwn you.

That's a pretty big asterisk though. Taking on a supply chain risk in exchange for reducing developer friction is not worth it in a lot of situations. Every dependency you take increases your risk of getting pwned (especially when it pulls in it's own dependencies), and you seriously need to consider whether it's worth that when you install it.

Don't get me wrong, sometimes it is; I'm certainly not going to create my own web framework from scratch, but a web request helper? Maybe not so much.

TranquilMarmot 5 hours ago

I usually reach for ky these days since it's an extremely lightweight wrapper over `fetch` - basically just adds a few niceties

https://github.com/sindresorhus/ky

From the readme:

- Simpler API

- Method shortcuts (ky.post())

- Treats non-2xx status codes as errors (after redirects)

- Retries failed requests

- JSON option

- Timeout support

- Upload and download progress

- Base URL option

- Instances with custom defaults

- Hooks

- Response validation with Standard Schema (Zod, Valibot, etc.)

- TypeScript niceties (e.g., .json() supports generics and defaults to unknown, not any)

Of course, this is only for projects where I have to make a lot of HTTP requests to a lot of different places where these niceties make sense. In most cases, we're usually using a library generated from an OpenAPI specification and fall back to `fetch` only as an escape hatch.

samtrack2019 7 hours ago

I compare this to the request and httplib in python, request library is vastly superior in usability but both do the same..

tommy_axle 8 hours ago

I wouldn't go that far. Right tool for the job as always. Axios offers a lot over fetch for all but the simplest use cases plus you get to take advantage of the ecosystem. Need offline, axios-cache-interceptor already exists. Sure you can do all of those things with fetch but you need more to go with it taking you right back to just using axios. Also is no one annoyed that you can't replay fetch like the xhr? Same with express: solves a problem reliably.

danpalmer 9 hours ago

If you want a fully built out network layer, with auth, logging, monitoring, policies, etc, then `fetch` doesn't really help. Axios and other libraries provide much more for building that sort of framework.

internetter 8 hours ago

Any sufficiently competent typescript developer can build out an adhoc wrapper (that just inherits the type definition and passes along whatever it is passed after altering it however needed) in under a hour. It doesn't scale in the sense that you don't expose a configuration, but config as code is king.

(Source: have built out much more scuffed variants of this than the one I just described like https://github.com/boehs/ajar)

I guess a LLM can do as well. Although that's not something I'm quite ready to admit.

8n4vidtmkvmk 8 hours ago

interstice 4 hours ago

whattheheckheck 8 hours ago

jwilliams 9 hours ago

I do "just use fetch" nowadays -- but I have to say, axios definitely has better ergonomics than fetch, especially for calling APIs.

sampullman 8 hours ago

I drag a tiny fetch wrapper around with error/json handling, timeouts and basic interceptor support. It doesn't cover everything axios does but it's nice enough and I haven't had to touch it in a couple years.

For reference: https://github.com/sampullman/fetch-api/blob/main/lib/fetchA...

nurettin 9 hours ago

When the vulnerability was announced, it took me two minutes to one-shot convert an entire legacy project from axios to fetch (it already wrapped api calls neatly), react cra to vite, update all dependencies, convert to deep imports to reduce bundle size and get zero npm warnings while fetching coffee. There is just no excuse to use it.

ipaddr 7 hours ago

azangru 4 hours ago

> Axios, like Express, is something I'm shocked to see used in any modern codebase

I am totally with you on axios; but why is express shocking, and what do you expect to see in its place? Fastify? Hono? Node:http?

Chyzwar 2 hours ago

Because your fetch most likely mishandle errors, lack retries, fail on redirects and is unnecessary verbose for both people and agents.

ariwilson 8 hours ago

What's wrong with Express?

rozenmd 7 hours ago

Several newer alternatives that outperform it on Node, like Hono

internetter 8 hours ago

Just slow and convoluted internals due to the accumulation of cruft over time

koolba 8 hours ago

What’s wrong with express?

dheerajvs 4 hours ago

Annoyingly, fetch does not support progress events and HTML / XML Document parsing, which are both supported by XMLHttpRequest, which Axios is based on.

chvid 8 hours ago

ChatGPT in general recommends axios over fetch. (At least it did about 2 months ago)

internetter 8 hours ago

This is why people still need to know how to write code and why it is asinine to have an LLM write code without a human reading it. Good developers should know what good code looks like and push back when what they're fed is wrong.

seanp2k2 7 hours ago

jQuery is still useful too. May you never work in heathcare / government / defense where you need to support legacy browsers far past their expiration date.

docheinestages 3 hours ago

> Out of an abundance of caution we are taking steps to protect the process that certifies our macOS applications are legitimate OpenAI apps.

What did I just read?

eranation 2 hours ago

They used a GitHub action with a floating tag (I guess @latest or non SHA pinned e.g. @v4) that I’m assuming in turn had its latest version bringing latest axios.

That GitHub action used to sign their Mac apps.

So they assume the certificate used to sign is compromised.

The risk is not to existing app, but theoretically someone could give you a copy of a malicious OpenAI binary, sign it with the compromised certificate, and impersonate OpenAI. Unlikely, but not impossible.

SSLy 3 hours ago

I'd assume they're retiring their old codesign certificates and rolling new ones, hopefully on a HSM or sth

mlitwiniuk 4 hours ago

I’m a web dev, I never made publicly accessible desktop app, so please forgive my ignorance, but:

> At that time, a GitHub Actions workflow we use in the macOS app-signing process downloaded and executed a malicious version of Axios (version 1.14.1)

So if I understand this correctly their GH Actions is free to upgrade the package just like that? Is this normal practice or it’s just shifting blame?

eranation 2 hours ago

I believe you understand correctly. And yes, it’s both a bad practice and shifting blame. But it’s not an uncommon practice sadly.

They mention it toward the end:

> The root cause of this incident was a misconfiguration in the GitHub Actions workflow, which we have addressed. Specifically, the action in question used a floating tag, as opposed to a specific commit hash, and did not have a configured minimumReleaseAge for new packages.

Some preventive actions everyone should take:

1. pin GitHub actions to SHAs (GitHub sadly doesn’t enforce immutable tags, it’s opt in only, but commits are practically non-repeatable, minus sha collision), also even if an action it’s not compromised directly, the latest version might be using a compromised dependency, so by taking the latest of one you get the latest (compromised) of the other. Pinning just prevents auto updates like this.

2. do npm ci instead of npm install (the first will be using a lock file the other may take the latest depending on how your package.json defines dependencies)

3. have a min release age (e.g. min-release-age=7 in .npmrc) most recent SSC attacks were removed from npm within hours. Adding a delay is similar to a live broadcast “bleep” delay.

chrisweekly 42 minutes ago

Solid advice -- though I recommend pnpm over npm (for better speed, determinism, node_modules bloat reduction, dep graph mgmt, install script safety,...)

AlienRobot 38 minutes ago

At this point I feel Github is getting Wordpress'd.

It has become so critical and ubiquitous that it has become a huge target for attackers.

eranation 5 hours ago

As others said, no one should be using axios in 2026, fetch has been available in node v18 (experimental) in 2022 [0], stable since v21 in 2023 [1], although Claude Code sometimes will suggest it, probably worth adding a rule.

Side note. I'm sure many of you know this, but for those who don't, setting min-release-age=7 in .npmrc (needs npm 11.10+), would have made the malicious axios (@1.14.1 and @0.30.4) invisible to npm install (removed within ~3h). Same for ua-parser-js (caught within hours) and node-ipc (caught in days). It wouldn't have prevented event-stream (over 2 months), but you can't win them all.

Some examples (hat tip to [2]):

  ~/.config/uv/uv.toml
  exclude-newer = "7 days"

  ~/.npmrc
  min-release-age=7 # days

  ~/Library/Preferences/pnpm/rc
  minimum-release-age=10080 # minutes

  ~/.bunfig.toml
  [install]
  minimumReleaseAge = 604800 # seconds
p.s. sorry for the plug, but we released a free tool ([3]) to gather all these settings + a cli to auto configure them. You can set these settings without it, but if you are confused (like me) with what is in minutes, what's in seconds, what is in days and where each of them is located, this might save you a few keystrokes / prompts (it also ensures you have the right min version for the package manager, otherwise you'll have the settings but they would be ignored...)

[0] https://nodejs.org/en/blog/announcements/v18-release-announc...

[1] https://nodejs.org/en/blog/release/v21.0.0

[2] https://news.ycombinator.com/item?id=47513932

[3] https://depsguard.com

tlb 21 minutes ago

Of course, when everyone sets min-release-age=7, supply chain attacks won't get noticed until 7 days later. So you should set min-release-age=14 and be safe forever.

ga_to 5 hours ago

Nice ad you got there. How do I define request interceptors with fetch? Axios does it.

eranation 4 hours ago

You can add your own wrapper but if you're building a whole auth/retry/logging layer, axios is probably better for that. For most other use cases a small wrapper will do the job.

Didn't mean it as an ad btw, the supply chain risk is real though. Axios could be the best HTTP library ever written and it still would've dropped a RAT on your laptop on March 31 without min-release-age set.

tomalbrc 3 hours ago

Whatever. If you are still using OpenAI products, shame on you.

mrcwinn 9 hours ago

Above and beyond post. This is good.

sdevonoes 5 hours ago

Using TS/JS in the backend is irresponsible in 2026. We have better languages and ecosystems

knocte 4 hours ago

The real issue is the cancer practice in our software development industry of updating dependencies for the sake of updating.

Deps should be updated when you need some features or bugfixes from the new versions; not just when DependaBot prompts you to do it.

I see value in DependaBot and things like that only to check that your module still passes your CI with upgraded dependencies (and if not, then it's worth looking at the failure, to be prepared for the updgrade in the future).

PufPufPuf 4 hours ago

Other ecosystems have better protections against compromised packages? I don't see it.