Live data from Hacker News

Post-mortem of Shai-Hulud attack on November 24th, 2025

posthog.com

71–77 of 77 posts

Re: Post-mortem of Shai-Hulud attack on November 24th, 2025

#71
post #68
post #65

Earlier quoted context omitted.

As we're seeing, properly configuring github actions is rather hard. By default force pushes are allowed on any branch.

Yes and anyone who knows anything about software dev knows that the first thing you should do with an important repo is set up branch protections to disallow that, and require reviews etc. Basic CI/CD. This incident reflects extremely poorly on PostHog because it demonstrates a lack of thought to security beyond surface level. It tells us that any dev at PostHog has access at any time to publish packages, without rev…

Nobody understands github. I guess someone at microsoft did but they probably got fired at some point.

You can't really fault people for this.

It's literally the default settings.

Re: Post-mortem of Shai-Hulud attack on November 24th, 2025

#73
post #61
post #52

Earlier quoted context omitted.

Dear GitHub Actions: what the heck? There are so many things about GitHub Actions that make no sense. Why are actions configured per branch? Let me configure Actions somewhere on the repository that is not modifiable by some yml files that can exist in literally any branch. Let me have actual security policy for configuring Actions that is separate from permission to modify a given branch. Why do workflows have such…

While I agree with the general sentiment that lots of things about GH actions don't make sense, when you actually look at what the vulnerability was, you'll find that for lots of your questions it wasn't GitHub Actions' fault. This is the vulnerable workflow in question: https://github.com/PostHog/posthog/blob/c60544bc1c07deecf336... > Why are actions configured per branch? This workflow uses `pull_request_target` ta…

Sure, that particular workflow is quite busted. But GitHub encourages this garbage design.

For example:

> GITHUB_TOKEN: ${{ secrets.POSTHOG_BOT_GITHUB_TOKEN }}

In no particular order:

- The use of secrets like this should be either entirely invalid or strongly, strongly discouraged. If allowed at all, there should be some kind of explicit approval required for the workflow step that gets to use the secret. And a file in the branch’s tree should not count as approval.

- This particular disaster should at least have been spelled something like ${{ dynamic_secret.assign_reviewer }} where that operation creates a secret that can assign a reviewer and nothing else and that lasts for exactly as long as the workflow step runs.

- In an even better design, there would be no secret at all. One step runs the script and produces output and has no permissions:

            - name: Run reviewer assignment script
              env:
                  PR_NUMBER: ${{ github.event.pull_request.number }}
                  GITHUB_REPOSITORY: ${{ github.repository }}
                  BASE_SHA: ${{ github.event.pull_request.base.sha }}
                  HEAD_SHA: ${{ github.event.pull_request.head.sha }}
              input: worktree ro at cwd
              output: reviewer from /tmp/reviewer
              run: |
                  node .github/scripts/assign-reviewers.js
I made up the syntax - that’s a read only view of “worktree” (a directory produced by a previous step) mounted at cwd. The output is a file at /tmp/reviewers that contains data henceforth known as “reviewer”. Then the next step isn’t a “run” — it’s something else entirely:

            - name: Assign the reviewer
              env:
                  PR_NUMBER: ${{ github.event.pull_request.number }}
                  REVIEWER: ${{ outputs.reviewer }}
              action: assign-reviewer
That last part is critical. This does not execute anything in the runner VM. It consumes the output from the previous step in the VM and then it … drumroll, please, because this is way too straightforward for GitHub … assigns the reviewer. No token, no secrets, no user-modifiable code, no weird side effects, no possibility of compromise due to a rootkit installed by a previous step into the VM, no containers spawned, no nothing. It just assigns a reviewer.

In this world, action workflows have no “write” permission ever. The repository config (actual config, not stuff in .github) gives a menu of allowed “actions”, and the owner checks the box so that this workflow may do “assign-reviewer”, and that’s it. If the box is checked, reviewers may be assigned. If not, they may not. Checking the box does not permit committing things or poisoning caches or submitting review comments or anything else - those are different checkboxes.

Oh, it costs GitHub less money, too, because it does not need to call out to the runner, and that isn’t free.

Re: Post-mortem of Shai-Hulud attack on November 24th, 2025

#74
post #70

Earlier quoted context omitted.

> Problem is that you might want to have the tests run before even looking at it. Why is this a problem? The default `pull_request` trigger isn't dangerous in GitHub Actions; the issue here is specifically with `pull_request_target`. If all you want to do is have PRs run tests, you can do that with `pull_request` without any sort of credential or identity risk. > Hilariously the people at pypi advise to use trusted p…

The kind of argument of "just don't make mistakes, how hard is it" (and we're talking about something very obscure and badly documented here) didn't work for C and in my opinion doesn't work for this either.

I can’t find a single place in that comment where I said anything like “just don’t make mistakes.” Where in the world did you get that from?

Re: Post-mortem of Shai-Hulud attack on November 24th, 2025

#75
post #24

Earlier quoted context omitted.

Problem is that you might want to have the tests run before even looking at it. I think the mistake was to put secrets in there and allow publishing directly from github's CI. Hilariously the people at pypi advise to use trusted publishers (publishing on pypi from github rather than local upload) as a way to avoid this issue. https://blog.pypi.org/posts/2025-11-26-pypi-and-shai-hulud/

> Problem is that you might want to have the tests run before even looking at it. Why is this a problem? The default `pull_request` trigger isn't dangerous in GitHub Actions; the issue here is specifically with `pull_request_target`. If all you want to do is have PRs run tests, you can do that with `pull_request` without any sort of credential or identity risk. > Hilariously the people at pypi advise to use trusted p…

> the issue here is specifically with `pull_request_target`

I just went to github to search for references to that trigger-type, and I admit I was surprised at the sheer number of times it is visible in a code-search.

It seems like a common-pattern, sadly.

Re: Post-mortem of Shai-Hulud attack on November 24th, 2025

#76

Earlier quoted context omitted.

> Problem is that you might want to have the tests run before even looking at it. Why is this a problem? The default `pull_request` trigger isn't dangerous in GitHub Actions; the issue here is specifically with `pull_request_target`. If all you want to do is have PRs run tests, you can do that with `pull_request` without any sort of credential or identity risk. > Hilariously the people at pypi advise to use trusted p…

> the issue here is specifically with `pull_request_target` I just went to github to search for references to that trigger-type, and I admit I was surprised at the sheer number of times it is visible in a code-search. It seems like a common-pattern, sadly.

Yes, it’s shockingly common. I’m of the opinion that GitHub should remove it entirely, since only a tiny majority of uses of it are demonstrably safe.

Re: Post-mortem of Shai-Hulud attack on November 24th, 2025

#77

Does anyone have experience putting their production branches in a separate repo from their development branches? GitHub makes it very easy to make a pull request from one repo into another. This would seem to have a lot of benefits: you can have different branch protection rules in the different repos, different secrets. Would it be a pain in the ass? For an open source project you could have an open contribution mo…

[deleted]
Post reply on HN