[HN Gopher] Tj-actions/changed-files GitHub Action Compromised -...
___________________________________________________________________
Tj-actions/changed-files GitHub Action Compromised - used by over
23K repos
Author : varunsharma07
Score : 197 points
Date : 2025-03-14 22:29 UTC (1 days ago)
(HTM) web link (www.stepsecurity.io)
(TXT) w3m dump (www.stepsecurity.io)
| varunsharma07 wrote:
| What Happened? * The compromised Action executes a Python script
| that dumps CI/CD secrets from the Runner Worker process. *
| Multiple v35 tags were modified four hours ago, indicating a
| recent supply chain attack. * The malicious behavior can be
| observed in StepSecurity Harden-Runner insights, showing the
| Action downloading and executing an unauthorized script.
| varunsharma07 wrote:
| https://github.com/tj-actions/changed-files/issues/2463
| jasonthorsness wrote:
| Wow that's scary, they updated tons of tags to an offending
| random commit. With the way repositories are included in
| automation and the fact that this adjusted the tags of older
| versions (so not requiring an upgrade) this sort of attack can
| have a huge impact very quickly :(.
|
| Maybe GitHub should have some kind of security setting a repo
| owner can make that locks-down things like old tags so after a
| certain time they can't be changed.
| SAI_Peregrinus wrote:
| Tags are a git concept, not a GitHub concept. Tags provide
| human-readable names to commits. They're intended to be
| changeable, to allow things like a "latest" tag pointing to the
| latest release. Tags aren't versions, commit hashes are.
| kurmiashish wrote:
| Disclaimer: I am a co-founder of StepSecurity.
|
| StepSecurity Harden-Runner detected this security incident by
| continuously monitoring outbound network calls from GitHub
| Actions workflows and generating a baseline of expected
| behaviors. When the compromised tj-actions/changed-files Action
| was executed, Harden-Runner flagged it due to an unexpected
| endpoint appearing in the network traffic--an anomaly that
| deviated from the established baseline. You can checkout the
| project here: https://github.com/step-security/harden-runner
| shawabawa3 wrote:
| A simpler method to detect this would be to store GitHub action
| tag hashes and freeze an action if any tag is changed
| cyrnel wrote:
| The advertising in this article is making it actively difficult
| to figure out how to remediate this issue. The "recovery steps"
| section just says "start our 14 day free trial".
|
| The security industry tolerates self-promotion only to the
| extent that the threat research benefits everyone.
| kurmiashish wrote:
| Thank you, cyrnel, for the feedback! We are trying our best
| to help serve the community. Now, we have separate recovery
| steps for general users and our enterprise customers.
| cyrnel wrote:
| Thanks for the edit! In "incident response mode" every
| moment counts!
| mubou wrote:
| In recent years, it's started to feel like you can't trust third-
| party dependencies and extensions at all anymore. I no longer
| install npm packages that have more than a few transitive
| dependencies, and I've started to refrain from installing vscode
| or chrome extensions altogether.
|
| Time and time again, they either get hijacked and malicious code
| added, or the dev themselves suddenly decides to betray
| everyone's trust and inject malicious code (see: Moq), or they
| sell out to some company that changes the license to one where
| you have to pay hundreds of dollars to keep using it (e.g. the
| recent FluentAssertions debacle), or one of those happens to any
| of the packages' hundreds of dependencies.
|
| Just take a look at eslint's dependency tree:
| https://npmgraph.js.org/?q=eslint
|
| Can you really say you trust all of these?
| scrapcode wrote:
| Are there examples of these types of actions in other circles
| outside of the .NET ecosystem? I knew about the
| FluentAssertions ordeal, but the Moq thing was news to me. I
| guess I've just missed it all.
| do_not_redeem wrote:
| node-ipc is a recent example from the Node ecosystem. The
| author released an update with some code that made a request
| to a geolocation webservice to decide whether to wipe the
| local filesystem.
| mubou wrote:
| Yeesh. Found an article for anyone interested:
| https://snyk.io/blog/peacenotwar-malicious-npm-node-ipc-
| pack...
|
| I like this comment from u/mailto_devnull (https://www.redd
| it.com/r/node/comments/tg451e/do_not_use_nod...):
| Where do I stand on the war? I stand with Ukraine.
| Where do I stand on software supply chain issues? I stand
| with not fucking around with the software supply chain.
| sanex wrote:
| Missed them too. Always was annoyed by FluentAssertions
| anyway, some contractor added it to a project that we took
| over couldn't see the value add.
| mh- wrote:
| _> eslint 's dependency tree_
|
| And if you turn on devDependencies (top right), it goes from 85
| to 1263.
| Terr_ wrote:
| I'd also emphasize out that there's nothing safe about it
| being "only dev", given how many attacks use employee
| computers (non-prod) as a springboard elsewhere.
| XorNot wrote:
| The original .NET (and I think Java?) had an idea in them of
| basically library level capability permissions.
|
| That sort of idea seems increasingly like what we need because
| reputation based systems can be gamed too easily: i.e. there's
| no reason an action like this _ever_ needed network access.
| mdaniel wrote:
| It was only recently removed in Java and there was a related
| concept (adopted from OSGi) designed to only export certain
| symbols -- not for security but for managing the surface area
| that a library vendor had to support
|
| But I mentioned both of those things because [IMHO] they both
| fell prey to the same "humanity bug": specifying permissions
| for anything (source code, cloud security, databases,
| Kubernetes, ...) is _a lot_ of trial and error, whereas
| {Effect: Allow, Action: [ "*:*"]} always works and so they
| just drop a "TODO: tighten permissions" and go on to the next
| Jira
|
| I had high hopes for the AWS feature "Make me an IAM Policy
| based on actual CloudTrail events" but it talks a bigger game
| than it walks
| kilroy123 wrote:
| I agree completely.
|
| If I see a useful extension, I want to use is on GitHub. I fork
| it. Sometimes I make a bookmarklet with the code instead.
|
| I keep most extensions off until I need to use them. Then, I
| enable them, use them, and turn them off again. I try to even
| keep Mac apps to a minimum.
| ocdtrekkie wrote:
| When using NuGet packages I usually won't even consider ones
| with non-Microsoft dependencies, and I like to avoid third-
| party dependencies altogether. I used to feel like this made me
| a weird conspiracy theorist but it's holding up well!
|
| It also has led to some bad but fun choices, like implementing
| POP3 and IMAP directly in my code, neither of which worked well
| but taught me a lot?
| usef- wrote:
| Yes. Same with browser plugins. I've heard multiple free-plugin
| authors say they're receiving regular offers to purchase their
| projects. I'm sure some must take up the offer.
| ronjouch wrote:
| For an example of a scary list of such offers, see
| https://github.com/extesy/hoverzoom/discussions/670
| remram wrote:
| This is cool but useless because they redacted all the
| company names. The opposite of a name and shame, because no
| name and no shame.
| xboxnolifes wrote:
| It's not useless. It shows the scale at which extension
| authors get offers for buyouts. The intended buyer
| doesn't exactly matter.
| ronjouch wrote:
| Precisely. Thank you.
| _boffin_ wrote:
| do you know of any other ones like this that post their
| offers?
| ronjouch wrote:
| No I don't. But Wladimir Palant is where I get most of my
| information on the topic (and is probably where I got
| this link). His blog might have a post (or a comment)
| that links to similar lists:
| https://palant.info/categories/security/
| mubou wrote:
| This is why I fork the extensions I use, with the exception
| of uBlock. Basically just copy the extension folder, if I
| can't find it on GitHub. That way I can audit the code and
| not have to worry about an auto-update sneaking in
| something nefarious. I've had two extensions in the past
| suddenly start asking for permissions they definitely did
| not need, and I suspect this is why.
|
| Btw, here's a site where you can inspect an extension's
| source code _before_ you install it:
| https://robwu.nl/crxviewer/
| ronjouch wrote:
| Yeah, and thx for the link to the neat crx explorer.
|
| Close to what you do, I started writing my own addon to
| replace a couple addons whose featureset I use only
| partially.
|
| For example, when I use Chromium I want 1. to customize
| the New Tab page, and 2. to add a keyboard shortcut to
| pin/unpinTab. These two features are absolutely part of
| extensions, but in addition to the security risk I find
| them heavy (I don't need the kitchen sink, just need 2
| micro-features!). And so, I have my little personal addon
| with zero resource usage with just these two features.
| It's tiny (20 lines of code!), git-versioned, and never
| changes / gets pwned. When I need an extra micro-feature,
| it's easy enough to add it by searching addons docs, of
| asking an LLM.
| Gigachad wrote:
| I have long since stopped using any extension that doesn't
| belong to an actual company (password managers for example).
| Even if they aren't malware when you installed them, they
| will be after they get sold.
| fluidcruft wrote:
| Actual companies also get sold and churned into shit. See
| LastPass for example.
| stockhorn wrote:
| A bit off topic, but how is the bitwarden browser extension
| protected against supply-chain attacks (npm dependencies)?
| from-nibly wrote:
| I got an outreach for an extension I made as a joke. It had
| like maybe 5000 downloads ever.
| throwaway48476 wrote:
| The solution for trusting dependencies is signed public builds
| and ML 'weirdness' detectors that require manual review.
| bolognafairy wrote:
| If this were "the solution", then the many, many smart
| individuals and teams tasked with solving these problems
| throughout the software industry would've been out of work
| for some time now.
|
| It's obviously more complicated than that.
|
| Signed public builds don't inherently mean jack. It highly
| depends on the underlying trust model.
|
| --
|
| Malicious actor: "we want to buy your browser extension, and
| your signing credentials".
|
| Plugin author: "Well, OK".
|
| --
|
| Malicious actor: _hijacks npm package and signs new release
| with new credentials_
|
| The vast majority of dependent project authors: _at best, see
| a "new releaser" warning from their tooling, which is far
| from unusual for many dependencies. ignores After all, what
| are they going to do?._
|
| --
|
| Hacker News, as usual, loves to pretend it has all the
| answers to life's problems, and the issue is that nobody has
| listened to them.
| dijksterhuis wrote:
| > Hacker News, as usual, loves to pretend it has all the
| answers to life's problems, and the issue is that nobody
| has listened to them.
|
| eh, it's not just HN.
|
| like, there's no single technical/material solution to
| something as complex and widespread as humanity's apparent
| base need to "get more stuff". which is the root cause for
| acting maliciously -- it's just "getting more stuff" in a
| way that's harmful to others.
|
| but that won't stop people from claiming that they can come
| up with a technical solution. whether that's politicians,
| tech bros, HN commentators or that guy down the pub on a
| thursday evening.
|
| --
|
| that being said, signing software is better than doing
| nothing... so, a better way of phrasing it from the GP
| would probably have been it is _a partial mitigation_ for
| the problem _in some cases_.
| ashishb wrote:
| > Can you really say you trust all of these?
|
| We need better capabilities. E.g. when I run `fd`, `rg` or
| similar such tool, why should it have Internet access?
|
| IMHO, just eliminating Internet access for all tools (e.g. in a
| power mode), might fix this.
|
| The second problem is that we have merged CI and CD. The
| production/release tokens should ideally not be on the same
| system as the ones doing regular CI. More users need access to
| CI (especially in the public case) than CD. For example, a
| similar one from a few months back
| https://blog.yossarian.net/2024/12/06/zizmor-ultralytics-inj...
| CamJN wrote:
| You also need to block write access, so they can't encrypt
| all your files with an embedded public key. And read access
| so they can't use a timing side channel to read a sensitive
| file and pass that info to another process with internet
| privileges to report the secret info back to the bad guy. You
| get the picture, I'm sure.
| ashishb wrote:
| > You also need to block write access, so they can't
| encrypt all your files with an embedded public key. And
| read access so they can't use a timing side channel to read
| a sensitive file and pass that info to another process with
| internet privileges to report the secret info back to the
| bad guy. You get the picture, I'm sure.
|
| Indeed.
|
| One can think of a few broad capabilities that will
| drastically reduce the attack surface.
|
| 1. Read-only access vs read-write 2. Access to only current
| directory and its sub-directories 3. Configurable Internet
| access
|
| Docker mostly gets it right. I wish there was an easy way
| to run commands under Docker.
|
| E.g.
|
| If I am running `fd`
|
| 1. Mount current read-only directory to Docker without
| Internet access (and without access to local network or
| other processes) 2. Run `fd` 3. Print the results 4.
| Destroy the container
| mivirl wrote:
| > 1. Mount current read-only directory to Docker without
| Internet access (and without access to local network or
| other processes) 2. Run `fd` 3. Print the results 4.
| Destroy the container
|
| Systemd has a lot of neat sandboxing features [1] which
| aren't well known but can be very useful for this. You
| can get pretty far using systemd-run [2] in a script like
| this: #!/bin/sh uid="$(id
| -u)" gid="$(id -g)" cwd="$(pwd -P)"
| sudo systemd-run --system --pty --same-dir --wait
| --collect --service-type=exec \ --uid="$uid" \
| --gid="$gid" \ -p "TemporaryFileSystem=/:ro
| /tmp" \ -p "BindReadOnlyPaths=-/bin -/sbin
| -/usr/bin -/usr/sbin -/lib -/lib64 -/usr/lib -/usr/lib64
| -/usr/libexec" \ -p "BindPaths=$cwd" \
| -p "PrivateNetwork=true" \ -p
| "PrivateDevices=true" \ -p "PrivateIPC=true" \
| -p "RestrictNamespaces=true" \ -p
| "RestrictSUIDSGID=true" \ -p
| "CapabilityBoundingSet=" \ "$@"
|
| Which creates a blank filesystem with no network or
| device access and only bind mount the specified files.
|
| Unfortunately TemporaryFileSystem require running as a
| system instance of the service manager rather than per-
| user instance, so that will generally mean running as
| root (hence sudo). One approach is to create a suid
| binary that does the same without needing sudo.
|
| [1] https://www.freedesktop.org/software/systemd/man/late
| st/syst...
|
| [2] https://www.freedesktop.org/software/systemd/man/late
| st/syst...
|
| You could also use bubblewrap [3] pretty similarly, and
| may not need to use sudo if unprivileged user namespaces
| are allowed by your kernel. #!/bin/sh
| cwd="$(pwd -P)" bwrap --new-session --die-
| with-parent \ --tmpfs /tmp \ --ro-
| bind-try /bin /bin \ --ro-bind-try /sbin /sbin
| \ --ro-bind-try /usr/bin /usr/bin \
| --ro-bind-try /usr/sbin /usr/sbin \ --ro-bind-
| try /lib /lib \ --ro-bind-try /lib64 /lib64 \
| --ro-bind-try /usr/lib /usr/lib \ --ro-bind-try
| /usr/lib64 /usr/lib64 \ --ro-bind-try
| /usr/libexec /usr/libexec \ --bind "$cwd"
| "$cwd" \ --dev-bind /dev/null /dev/null \
| --dev-bind /dev/zero /dev/zero \ --dev-bind
| /dev/random /dev/random \ --unshare-net \
| --unshare-ipc \ --cap-drop ALL \
| --chdir "$cwd" \ "$@"
|
| [3] https://github.com/containers/bubblewrap
| homebrewer wrote:
| If you require network (for pnpm to install packages,
| etc), you also often have to add readonly access to
| /etc/ssl, or https wouldn't work.
|
| It might also be helpful to just use --unshare-all, and
| then whitelist things you actually need (--share-net,
| etc).
| 418tpot wrote:
| This is exactly what the tool bubblewrap[1] is built for.
| It is pretty easy to wrap binaries with it and it gives
| you control over exactly what permissions you want in the
| namespace.
|
| [1]: https://github.com/containers/bubblewrap
| pdimitar wrote:
| I get the picture, yes, namely that probably 99% of project
| dependencies don't need I/O capabilities at all.
|
| And even if they do, they should be controlled in a
| granular manner i.e. "package org.ourapp.net.aws can only
| do network and it can only ping *.aws.com".
|
| Having finer-grained security model that is enforced at a
| kernel level (and is non-circumventable barring rootkits)
| is like 20 years overdue at this point.
|
| _Every single big org_ is dragging their feet.
| redserk wrote:
| I've been doing all of my dev work in a virtual machine as a
| way to clamp things down. I've even started using a browser
| in a VM as a primary browser.
|
| Computers are fast enough where the overhead doesn't feel
| like it's there for what I do.
|
| For development, I think Vagrant should make a comeback as
| one of the first things to setup in a repo/group of repos.
| bombcar wrote:
| https://www.qubes-os.org/ is the extension of this.
| redserk wrote:
| I'm not sure I can recommend Qubes entirely due to the
| usability aspect.
|
| I've used Qubes several times for a week at a time over
| the last few years. It's gotten better, but they really
| need someone to look at the user experience of it all for
| it to be a compelling option.
|
| I'm regularly questioning myself if what I'm doing is
| making it less secure because I don't understand exactly
| everything Qubes is doing. I know how all the pieces work
| individually (Xen, etc).
|
| Outside of configuration, I believe I'd have to ditch any
| hope of running 3D-anything with any expectation of
| performance. That's simply a non-starter as someone who
| has written off "nation-state actor targeting me,
| specifically" as something I can defend against.
|
| And lastly, I'm deeply skeptical of anything that loudly
| wears the Snowden-badge-of-approval as that seems to
| follow grifts.
|
| My main workstation is a Mac and I'm doing this on
| Parallels. Would Qubes probably be more secure? Maybe.
| But it comes at a massive usability hit.
| LPisGood wrote:
| I get a lot or usability from having one single operating
| system.
|
| Sure it's less secure than full isolation, but full
| isolation is a real pain.
| hypeatei wrote:
| OpenBSDs pledge[0] system call is aimed at helping with this.
| Although, it's more of a defense-in-depth measure on the
| maintainers part and not the user.
|
| > The pledge() system call forces the current process into a
| restricted-service operating mode. A few subsets are
| available, roughly described as computation, memory
| management, read-write operations on file descriptors,
| opening of files, networking (and notably separate, DNS
| resolution). In general, these modes were selected by
| studying the operation of many programs using libc and other
| such interfaces, and setting promises or execpromises.
|
| [0]: https://man.openbsd.org/pledge.2
| yencabulator wrote:
| Pledge is for self-isolating, it helps with mistakes but
| not against intentional supply chain attacks.
| hypeatei wrote:
| How so? Obviously this is ineffective at the package
| level but if the thing spawning these processes, like the
| GitHub runners or Node itself added support to enter a
| "restricted" mode and pledged then that would help, no?
| _flux wrote:
| According to
| https://www.openbsd.org/papers/eurobsdcon2017-pledge.pdf
| pledge turns off upon execve. Surely it would be quite
| limiting for runners to use it.
|
| As far as I see its purpose is mostly a mitigation/self-
| defence for vulnerabilities in C-based apps, so basically
| limiting what happens _once_ the attacker has exploited a
| vulnerability. Maybe it has other uses.
|
| It could be used defending against bugs in the Node
| runtime itself, as you say, but as I understand
| vulnerabilities in the Node runtime itself are quite
| rare, so more fine-grained limitations could be
| implemented within itself.
| ratmice wrote:
| I'm not much of an openbsd user, but I have been meaning
| to understand if this is the hole execpromises is
| intended to fill.
|
| At the very least, I think execpromises was added a year
| after the documentation that you linked, so it's worth
| looking into.
| h4ck_th3_pl4n3t wrote:
| But that's what firejail and docker/podman are for. I never
| run any build pipeline on my host system, and neither should
| you. Build containers are pretty good for these kind of
| mitigations of security risks.
| mnahkies wrote:
| I've found firejail to be a useful tool for this
| (https://github.com/netblue30/firejail), and additionally use
| opensnitch (https://github.com/evilsocket/opensnitch) to
| monitor for unexpected network requests.
|
| For CI/CD using something like ArgoCD let's you avoid giving
| CI direct access to prod - it still needs write access to a
| git repo, and ideally some read access to Argo to check if
| deployment succeeded but it limits the surface area.
| homebrewer wrote:
| bubblewrap is a safer alternative to firejail because it
| does not use setuid to do its job, and it is used by
| flatpak (so hopefully has more eyes on it, but I have no
| idea).
|
| https://wiki.archlinux.org/title/Bubblewrap
|
| You do have to assemble isolation scripts by hand though,
| it's pretty low level. Here is a decent comment which
| closely aligns to what I'm using to isolate
| npm/pnpm/yarn/etc, I see no need to repeat it:
|
| https://news.ycombinator.com/item?id=43369927
| varunsharma07 wrote:
| Great points! Harden-Runner (https://github.com/step-
| security/harden-runner) is similar to Firejail and
| OpenSnitch but purpose-built for CI/CD context. Harden-
| Runner detected this compromise due to an anomalous
| outbound network request to gist.githubusercontent.com.
|
| Interestingly, Firejail itself uses Harden-Runner in its
| GitHub Actions workflows! https://github.com/search?q=repo%
| 3Anetblue30%2Ffirejail%20ha...
| mschuster91 wrote:
| > We need better capabilities.
|
| I'd love to say "just use Kubernetes and run Nexus as a
| service inside" but unfortunately Network Policies are
| _seriously_ limited [1]...
|
| [1] https://kubernetes.io/docs/concepts/services-
| networking/netw...
| nextaccountic wrote:
| > We need better capabilities. E.g. when I run `fd`, `rg` or
| similar such tool, why should it have Internet access?
|
| Yeah!! We really need to auto sandbox _everything_ by
| default, like mobile OSes. Or the web.
|
| People browse the web (well, except Richard Stallman) all the
| time, and run tons of wildly untrusted code, many of them
| malicious. And apart from zero days here and there, people
| don't pay much attention to it, and will happily enter any
| random website in the same machine they also store sensitive
| data.
|
| At the same time, when I open a random project from Github on
| VSCode, it asks whether the project is "trusted". If not, it
| doesn't run the majority of features like LSP server. And why
| not? Because the OS doesn't sandbox stuff by default. It's
| maddening.
| ptx wrote:
| FreeBSD has Capsicum [0] for this. Once a process enters
| capability mode, it can't do anything except by using already
| opened file descriptors. It can't spawn subprocesses, connect
| to the network, load kernel modules or anything else.
|
| To help with things that can't be done in the sandbox, e.g.
| DNS lookups and opening new files, it provides the libcasper
| library which implements them using helper processes.
|
| Not all utilities are sandboxed, but some are and hopefully
| more will be.
|
| Linux recently added Landlock [1] which seems sort of
| similar, although it has rulesets and doesn't seem to block
| everything by default, as far as I can tell from quickly
| skimming the docs.
|
| [0] https://wiki.freebsd.org/Capsicum
|
| [1] https://docs.kernel.org/userspace-api/landlock.html
| theamk wrote:
| I don't think it would help in this case, when the entire
| process can be replaced with malicious version. It just
| won't make the Capscium call.
|
| What you really want is something external and easily
| inspectable, such as systemd per-service security rules, or
| flatpak sandboxing. Not sure if FreeBSD has somethingike
| this.
| kubectl_h wrote:
| npm supply chain attacks are the lone thing that keeps me up at
| night, so to speak. I shudder thinking about the attack
| surface.
|
| I go out of my way to advocate for removing dependencies and
| pushing against small dependency introductions in a large ruby
| codebase. Some dependencies that suck and impose all sorts of
| costs, from funky ass idiosyncratic behavior or absurd file
| sizes (looking at you any google produced ruby library,
| especially the protocol buffer dependent libraries) are
| unavoidable, but I try to keep fellow engineers honest about
| introducing libraries that do things like determine the
| underlying os or whatever and push towards them just figuring
| that out themselves or, at the least, taking "inspiration" from
| the code in those libraries and reproducing behavior.
|
| A nice side effect of AI agents and copilots is they can
| sometimes write "organic" code that does the same thing as
| third party libraries. Whether that's ethical, I don't know,
| but it works for me.
| harrisi wrote:
| This isn't new - Thompson warned us 40 years ago (and I believe
| others before him) in his Reflections on Trusting Trust paper.
|
| It's something I've been thinking about lately because I was
| diving into a lot of discussion from the early 90s regarding
| safe execution of (what was, at the time, called) "mobile code"
| - code that a possibly untrustworthy client would send to have
| executed on a remote server.
|
| There's actually a lot of discussion still available from w3
| thankfully, even though most of the papers are filled with
| references to dead links from various companies and
| universities.
|
| It's weirdly something that a lot of smart people seemed to
| have thought about at the start of the World Wide Web which
| just fell off. Deno's permissions are the most interesting
| modern implementation of some of the ideas, but I think it
| still falls flat a bit. There's always the problem of "click
| yes to accept the terms" fatigue as well, especially when
| working in web development. It's quite reasonable for many
| packages one interacts with in web development to need network
| access, for example, so it's easy to imagine someone just
| saying "yup, makes sense" when a web-related package requests
| network access.
|
| Also none of this even touches on the reality of so much code
| which exists to brutally impact a business need (or perceived
| need). Try telling your boss you need a week or two to audit
| every one of the thousands of packages for the report generator
| app.
| imoreno wrote:
| Trusting Trust is not about this at all. It's about the
| compiler being compromised, and making it impossible to catch
| malicious code by inspecting the source code.
|
| The problem here is that people don't even bother to check
| the source code and run it blindly.
| nextts wrote:
| If you want a Cathedral they still exist. Use .NET and only MS
| Nuget packages.
| stickfigure wrote:
| I'm just going to say this out loud: It's mostly a Javascript
| thing.
|
| Not that every other platform in the world isn't theoretically
| vulnerable to the same sort of attack, but there's some deep-
| rooted culture in the javascript community that makes it
| especially vulnerable.
|
| The charitable interpretation is "javascript evolves so fast!".
| The uncharitable interpretation is "they are still figuring it
| out!"
|
| Either way, I deliberately keep my javascript on the client
| side.
| puffybuf wrote:
| Stealing crypto is so lucrative. So there is a huge 'market'
| for this stuff now that wasn't there before. Security is more
| important now than ever. I started sandboxing Emacs and python
| because I can't trust all the packages.
| semi-extrinsic wrote:
| What do you use for sandboxing?
| ycombiredd wrote:
| Yes, this...
|
| I hope the irony is not completely lost on the fine folks at
| semgrep that the admittedly "overkill" suggested semgrep
| solution is exactly the type of pattern that leads to this sort
| of vulnerability: that of executing arbitrary code that is
| modifiable completely outside of one's own control.
| re-thc wrote:
| > In recent years, it's started to feel like you can't trust
| third-party dependencies and extensions at all anymore.
|
| Was it really a recent thing?
|
| > Just take a look at eslint's dependency tree
|
| Npm / node has always been extra problematic though. Where's
| the governance / validation on these packages? It's free for
| all.
| h4ck_th3_pl4n3t wrote:
| The alternative would be to find a sustainable funding model
| for open source, which is the source of betrayals due to almost
| all of the maintainers having to sell their projects to make a
| living in the first place.
|
| The problem you're describing is an economical and a social
| one.
|
| Currently, companies exploit maintainers of open source
| projects. There are rarely projects that make it due to their
| popularity, like webpack, when it comes to funding...but the
| actual state is that everyone that webpack is based on as a
| dependency didn't get a single buck for it, which is unfair,
| don't you think?
|
| On top of sustainable funding, we need to change our workflows
| to reproducible build ecosystems that can also revert
| independent of git repositories. GitHub has become the almost
| single source of code for the planet, which is insane to even
| bet on from a risk assessment standpoint. But it's almost
| impossible to maintain your own registry or mirror of code in
| most ecosystems due to the sheer amount of transitive
| dependencies.
|
| Take go mod vendor, for example. It's great to stick your
| dependencies but it comes with a lot of overhead work in case
| something like OPs scenario happens to its supply chain. And we
| need to account for that in our workflows.
| from-nibly wrote:
| It's not going to happen. If buying a forever license of
| unlimited usage for an open source library cost $1 I'd skip
| it. Not be cause I don't want to give money to people who
| deserve it, but because of the absolute monstrous
| bureaucratic nightmare that comes from trying to purchase
| anything at a company larger than 10 people.
|
| Don't even talk about when the company gets a lawyer who
| knows what a software license is.
| prepend wrote:
| Open source has a very sustainable funding model as evidenced
| by 50 years of continuous, quality software being developed
| and maintained by a diverse set of maintainers.
|
| I say sustainable because it has been sustained, is
| increasing in quantity and quality, and reasonably seems to
| be continuing.
|
| > companies exploit maintainers of open source projects Me
| giving something away and others taking what I give is not
| exploitation. Please don't speak for others and claim people
| are exploited. One of the main tenets of gnu is to prevent
| exploitation.
| from-nibly wrote:
| This is the death of fun. Like when you had to use SSL for
| buying things online.
|
| Adding SSL was not bad, don't get me wrong. It's good that it's
| the default now. However. At one point it was sorta risky, and
| then it became required.
|
| Like when your city becomes crime ridden enough that you have
| to lock your car when you go into the grocery store. Yeah you
| probably should have been locking it the whole time. what would
| it have really cost? But now you have to, because if you don't
| your car gets jacked. And that's not a great feeling.
| aorloff wrote:
| Just you wait. Here in America when your city becomes crime
| ridden enough you start leaving it unlocked again.
| mubou wrote:
| Used to live near San Francisco, and had a lot of coworkers
| say they intentionally leave their windows down when
| parking in SF so that burglars don't break the glass to
| steal something!
| nozzlegear wrote:
| On the other extreme, I can (and do) leave my keys inside
| my running car while I shop for groceries!
| asveikau wrote:
| Crime is lower than the 80s and 90s. It has been declining
| since 2023.
| asveikau wrote:
| In the era of the key fob it's pretty automatic to lock the
| car every time. Some cars even literally do it for you. I
| hardly think of this, let alone get not great feelings about
| it.
| prepend wrote:
| I liked living in a city where I could leave my doors
| unlocked and windows down. It was less to worry about.
| sroussey wrote:
| Yeah, I'm working on a library where the core is dependency
| free. It takes longer but I know the provenance of everything--
| me!
| jrockway wrote:
| You can trust (in time), but you can't blindly upgrade. Vendor
| or choose to "lock" with a cryptographic hash over the files
| your build depends on. You then need to rebuild that trust when
| you upgrade (wait until everyone else does; read the diffs
| yourself).
|
| There is something to be said for the Go proverb "a little
| copying is better than a little dependency", as well. If you
| want a simple function from a complicated library, you can
| probably copy it into your own codebase.
| phantomathkg wrote:
| How far will you go? If you are user of Linux, are you going to
| inspect all sources before using a distribution?
| padjo wrote:
| Years ago I saw that most browser extensions ask for the
| permission "can access all data on all websites" and thought
| yeah let's not do that...
| bobnamob wrote:
| Yeah, I've moved off vscode entirely, back to fully featured
| out of the box ides for me. Jetbrains make some excellent tools
| and I don't need to install 25 (dubious) plugins for them to be
| excellent
| ta1243 wrote:
| This amuses me:
|
| > But Lewis Ardern on our team wrote a Semgrep rule to find
| usages of tj-actions, which you can run locally (without
| sending code to the cloud) via: semgrep --config
| r/10Uz5qo/semgrep.tj-actions-compromised.
|
| So "remote code you download from a repo automatically and run
| locally has been compromised, here run this remote code you
| download from a repo automatically and run locally to find it"
| aryx wrote:
| A semgrep rule is not code; it does not run anything.
| ozim wrote:
| You should never have trusted blindly in third-party
| dependencies in the first place.
|
| Abnormal behavior was to trust by default.
| lenkite wrote:
| This is why I have begin to prefer languages with
| comprehensive, batteries-included standard libraries so that
| you need very few dependencies. Dep Management has become a
| full time headache nowadays with significant effort going into
| CVE analysis.
| mlfreeman wrote:
| I think this is the root of the problem.
|
| I think library/runtime makers aren't saying "let's make an
| official/blessed take on this thing that a large number of
| users are doing" as much as they should.
|
| Popular libraries for a given runtime/language should be
| funded/bought/cloned by the runtime makers (e.g. MS for .NET,
| IBM/Oracle for Java) more than they are now.
|
| I know someone will inevitably mention concerns about
| monopolies/anti-trust/"stifling innovation" but I don't
| really care. Sometimes you have to standardize some things to
| unlock new opportunities.
| imoreno wrote:
| Instead of bloating the base language for this, a trusted
| entity could simply fork those libraries, vet them, and
| repackage into some "blessed lib" that people like you can
| use in peace. In fact, the level of trust needed to develop
| safe libraries is less than developing language features.
| magicalhippo wrote:
| That's basically what Boost[1] brought to C++.
|
| [1]: https://www.boost.org/
| icetank wrote:
| 49 modules with only one maintainer and over 600 modules with
| only one maintainer if devDependencies are included. This is
| only a matter of time until the next module becomes
| compromised.
| touristtam wrote:
| I have used https://github.com/lirantal/npq for a good while
| now, but I am yearning for that'd look deeper into the health
| of the package at hand.
| YZF wrote:
| You should have never trusted them. That ecosystem is fine for
| hobbyists but for professional usage you can't just grab
| something random from the Internet and assume it's fine.
| Security or quality wise.
| dan_manges wrote:
| GitHub Actions should use a lockfile for dependencies. Without
| it, compromised Actions propagate instantly. While it'd still be
| an issue even with locking, it would slow down the rollout and
| reduce the impact.
|
| Semver notation rather than branches or tags is a great solution
| to this problem. Specify the version that want, let the package
| manager resolve it, and then periodically update all of your
| packages. It would also improve build stability.
| jasonthorsness wrote:
| Since they edited old tags here ... maybe GitHub should have
| some kind of security setting a repo owner can make that locks-
| down things like old tags so after a certain time they can't be
| changed.
| CaliforniaKarl wrote:
| In your GitHub Actions YAML, instead of referencing a
| specific tag, you can reference a specific commit. So,
| instead of ... uses: actions/checkout@v4
|
| ... you can use ... uses:
| actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
| OptionOfT wrote:
| That still doesn't help when the action is a docker action
| only marked with a tag.
|
| So you need to check the action.yml itself to see if it has
| a sha256 pinned (in the case it uses Docker).
| mceachen wrote:
| GitHub actions supports version numbers, version ranges, and
| even commit hashes.
| frenchtoast8 wrote:
| The version numbers aren't immutable, so an attacker can just
| update the versions to point to the compromised code, which
| is what happened here. Commit hashes are a great idea, but
| you still need to be careful: lots of people use bots like
| Renovate to update your pinned hashes whenever a new version
| is published, which runs into the same problem.
| marsovo wrote:
| I don't think that's exactly what happened here: the
| compromise created new tags but generally the tag
| consumption relies on semantic versioning
|
| In other words: you specify version 44, the attacker
| creates 44.1, you're still hosed.
| BlackFingolfin wrote:
| No you literally can (and the attackers did) change
| version 44 (the tag for it) to point to a different
| compromised commmit
| werrett wrote:
| Only commit hashes are safe. In this case the bad actor
| changed all of the version tags to point to their malicious
| commit. See https://github.com/tj-actions/changed-files/tags
|
| All the tags point to commit `^0e58ed8`
| https://github.com/tj-actions/changed-
| files/commit/0e58ed867...
| eddythompson80 wrote:
| You can always just fork it and reference your own fork.
| postalrat wrote:
| Or just write your own.
| cmckn wrote:
| I always use commit hashes for action versions. Dependabot
| handles it, it's a no brainer.
| Terr_ wrote:
| > commit hashes
|
| There is some latent concern that most git installations use
| SHA-1 hashes, as opposed to SHA-256. [0]
|
| Also the trick of creating a branch that happens to be named
| the same as a revision, which then takes precedence for
| certain commands.
|
| [0] https://git-scm.com/docs/hash-function-transition
| password4321 wrote:
| _creating a branch that happens to be named the same as a
| revision, which then takes precedence for certain commands_
|
| TIL; yikes! (and thanks)
| Terr_ wrote:
| A signed commit [0] might be good for internal devops
| stuff (e.g. "yes, we really do want this version in
| production") but unfortunately that's not gonna work for
| pulling in third-party tooling, since most won't use it.
|
| [0]https://git-scm.com/book/ms/v2/Git-Tools-Signing-Your-
| Work
| mixologic wrote:
| All the version tags got relabled to point to a compromised
| hash. Semver does nothing to help with this.
|
| your build should always use hashes and not version tags of
| GHA's
| nextts wrote:
| Also don't het GH actions to do anything other than build and
| upload artifacts somewhere. Ideally a write only role. Network
| level security too no open internet.
|
| Use a seperate system for deployments. That system must be
| hygienic.
|
| This isn't foolproof but would make secrets dumping not too
| useful. Obviously an attack could still inject crap into your
| artefact. But you have more time and they need to target you. A
| general purpose exploit probably won't hurt as much.
| jasonthorsness wrote:
| I think this article from earlier today was the discoverer who
| opened the issue
|
| https://news.ycombinator.com/item?id=43367987
| simonw wrote:
| I've always felt uncomfortable adding other people's actions to
| my GitHub workflows, and this is exactly the kind of thing I was
| worried about.
|
| I tend to stick to the official GitHub ones (actions/setup-python
| etc) plus the https://github.com/pypa/gh-action-pypi-publish one
| because I trust the maintainers to have good security habits.
| 3eb7988a1663 wrote:
| That's exactly where I stand, and I feel partially vindicated
| by this outcome. There are so many useful Github actions made
| by randos, but I am not adding more unvetted dependencies to my
| project. I will unhappily copy and paste some useful code into
| my project rather than relying upon yet another mutable
| dependency.
| mirashii wrote:
| Not the first time this particular action has had a
| vulnerability, either.
|
| https://nvd.nist.gov/vuln/detail/CVE-2023-51664
| zahlman wrote:
| I could have sworn that I've seen other GitHub Actions
| vulnerabilities that worked the same way, too. And/or HN
| submissions talking about this specific kind of vulnerability,
| the standard mitigation strategies, etc.
|
| Feels like the same kind of problem as SQL injection, where
| everybody kinda knows about it and some people are actively
| aware and there are standard ways to avoid it but it still
| happens all the time anyway.
|
| Might also be a good time to mention I'm really not a fan of
| YAML.
| tsujamin wrote:
| How does SBOM and such account for this? If you're a package
| maintainer, do you need to include CI pipeline plugins, their
| dependencies, going down as far as the pipeline host, in your
| security-relevant dependencies? Hard problems :/
| captn3m0 wrote:
| Most recommendations treat SBOM as the "ingredients" and are he
| build dependencies such as GitHub Actions as the recipe.
|
| However, I think the GitHub SBOM features include GitHub
| Actions as dependencies, but that is merely a side-effect of
| their Dependabot heritage.
| neuroelectron wrote:
| CI was sold as a solution for engineers having too much
| sovereignty. So that's what they got.
| random17 wrote:
| I wish Github required some sort of immutability for actions by
| default as most package managers do, either by requiring reusable
| actions to be specified via commit hash or by preventing the code
| for a published tag to be changed.
|
| At the moment the convention is to only specify the tag, which is
| not only a security issue as we see here, but may also cause
| workflows to break if an action author updates the action.
| wutwutwat wrote:
| You can target `some/action@commithash` already, that's up to
| you. You're also free to fork or clone each action you use, vet
| the code, and consume your fork in your workflows. You can also
| disable the use of third party actions at an org level, or
| approve them on a case-by-case basis.
|
| This all depends on your threat model and risk tolerance, it's
| not so much a GitHub problem. There will always be bad code
| that exists, especially on the largest open source code hosting
| platform. You defend against it because that's more realistic
| than trying to eradicate it.
| arianvanp wrote:
| One problem with this is that actions can be Composite and
| call arbitrary other actions. So only if you use actions that
| themselves lock everything by commit for the actions they
| depend on you're safe.
| chuckadams wrote:
| Someone elsewhere suggested a lockfile, which seems a pretty
| obvious solution in hindsight. I'm fine with commit hashes,
| but the UX is terrible and consists of pasting the action
| into into StepSecurity's thingie, when this is something that
| GH should have built in.
| mubou wrote:
| Someone else in the thread mentioned that this is coming!
| https://github.com/features/preview/immutable-actions
| xyst wrote:
| A company I worked at went all in on GH too. The internal gh team
| probably going to do a fire drill this whole weekend and app
| teams forced to rotate all secrets and credentials.
|
| Fortunately don't have to deal with that shit anymore
| frenchtoast8 wrote:
| My day job is also in the middle of moving everything to Github
| Actions, so this is fun. But in my case, we aren't affected by
| this vulnerability because it could only be exploited by
| workflows with public logs, and currently my company only uses
| Github Actions for private repositories.
| werrett wrote:
| I mean maybe! But only if you've removed all of the usage of
| this compromised `tj-actions/changedfiles` action, across all
| your repos and their branches.
|
| Otherwise, if you continue to use it and it will run anytime
| there has been a push. Potentially on any branch, not just
| `main`! Depending on your GH config.
|
| Unless you've blocked `tj-actions/changed-files` you're
| banking on the bad actor not coming back tonight and making
| malicious commit that exfils those secrets to pastebin.com.
| arionmiles wrote:
| It's possible to whitelist actions on an org level.
|
| You can whitelist
|
| - all actions from a specific org (e.g. actions/*)
|
| - a specific action (e.g. actions/setup-go)
|
| - a specific version of a specific action (e.g. actions/setup-
| go@commit-sha)
|
| Any workflow attempting to use actions outside of the whitelist
| will simply fail to start up.
| dboreham wrote:
| Good policy to fork all actions not owned by a reputable
| organization (e.g. github themselves).
| frenchtoast8 wrote:
| You can combine this with a policy that blocks third party
| actions from being used across your organization.
| https://docs.github.com/en/organizations/managing-organizati...
| xyst wrote:
| Pretty good timing on the attacker.
|
| https://github.com/tj-actions/changed-files/tags?after=v35.9...
|
| Most folks around the world signed off. B-squad probably left
| cleaning up remaining tasks or just fucking around with co-
| workers and pondering the weekend. Most GH actions run on a
| schedule (ie, backups of db, connecting to blob storage
| services).
|
| Attacker(s) likely to extract plenty of secrets and exfil data
| before the alarms get triggered (if any) at companies.
|
| The next data dumps are going to be wild.
| harrisi wrote:
| It's always been shocking to me that the way people run CI/CD is
| just listing a random repository on GitHub. I know they're
| auditable and you pin versions, but it's crazy to me that the
| recommended way to ssh to a server is to just give a random
| package from a random GitHub user your ssh keys, for example.
|
| This is especially problematic with the rise of LLMs, I think.
| It's the kind of common task which is annoying enough, unique
| enough, and important enough that I'm sure there are a ton of
| GitHub actions that are generated from "I need to build and
| deploy this project from GitHub actions to production". I know,
| and do, know to manually run important things in actions related
| to ssh, keys, etc., but not everyone does.
| sestep wrote:
| The crazier part is, people typically don't even pin versions!
| It's possible to list a commit hash, but usually people just
| use a tag or branch name, and those can easily be changed (and
| often are, e.g. `v3` being updated from `v3.5.1` to `v3.5.2`).
| harrisi wrote:
| You and someone else pointed this out. I only use GitHub-org
| actions, and I just thought that surely there would be a "one
| version to rule them all" type rule.. how else can you audit
| things?
|
| I've never seen anything recommending specifying a specific
| commit hash or anything for GitHub actions. It's always just
| v1, v2, etc.
| mcpherrinm wrote:
| OpenSSF scorecard flags dependencies (including GitHub
| actions) which aren't pinned by hash
|
| https://scorecard.dev/
|
| https://github.com/ossf/scorecard/blob/main/docs/checks.md#
| p...
| evntdrvn wrote:
| it is documented as recommended here fwiw:
| https://docs.github.com/en/actions/security-for-github-
| actio...
| sundarurfriend wrote:
| And the syntax to do that is to use
| `foo/bar@commitshagoeshere` as in -
| uses: RafaelGSS/bad-
| action@e20fd1d81b3f403df56f5f06e2aa9653a6a60763 # v1.0.1
|
| (example from https://blog.rafaelgss.dev/why-you-should-
| pin-actions-by-com...)
| nextts wrote:
| Fuck. Insecure defaults again. I argue that a version
| specifier should be only a hash. Nothing else is acceptable.
| Forget semantic versions. (Have some other method for
| determining upgrade compatibility you do out of band. You
| need to security audit every upgrade anyway). Process: old
| hash, new hash, diff code, security audit, compatibility
| audit (semver can be metadata), run tests, upgrade to new
| hash.
| remram wrote:
| People don't pin versions. Referencing a tag is not pinning a
| version, those can be updated, and they are even with the
| official actions from GitHub.
| harrisi wrote:
| Aren't GitHub action "packages" designate by a single major
| version? Something like checkout@v4, for example. I thought
| that that designated a single release as v4 which will not be
| updated?
|
| I'm quite possibly wrong, since I try to avoid them as much
| as I can, but I mean.. wow I hope I'm not.
| remram wrote:
| No the "v4" tag gets updated from v4.1 to v4.2 etc as those
| minor versions are released. They are branches,
| functionally.
| harrisi wrote:
| Wow, thank you (and the other person that pointed this
| out to me). That's madness.
| semiquaver wrote:
| You _can_ pin actions to a git sha to prevent this but
| people generally do not. Action authors would prefer
| their updates be picked up automatically.
| werrett wrote:
| Exactly. And that's what happened here -- the bad actor
| changed all of those version tags to point to their
| malicious commit.
|
| See https://github.com/tj-actions/changed-files/tags
|
| All the tags point to commit `^0e58ed8`
| https://github.com/tj-actions/changed-
| files/commit/0e58ed867...
| diggan wrote:
| Correct me if I'm wrong, but you would be able to prevent
| this specific issues with the "Rules" in order to block
| updates of tags; https://github.blog/news-
| insights/product-news/github-reposi...
| sestep wrote:
| Yeah but no GitHub Action is going to do this because
| updating tags is the de facto mechanism for releasing
| patches for those repositories.
| jakub_g wrote:
| I think a big part of the problem is the way one typically
| "installs" a GH action: by copy-pasting something from README
| of the action.
|
| Let's have a look at a random official GH provided action:
|
| https://github.com/actions/checkout
|
| It lists the following snippet:
|
| `uses: actions/checkout@v4`
|
| Almost everyone will just copy paste this snippet and call it
| a day. Most people don't think twice that v4 is a movable
| target that can be compromised.
|
| In case of npm/yarn deps, one would often do the same, and
| copy paste `yarn install foobar`, but then when installing,
| npm/yarn would create a lockfile and pin the version. Whereas
| there's no "installer" CLI for GH actions that would pin the
| version for you, you just copy-paste and git push.
|
| To make things better, ideally, the owners of actions would
| update the workflows which release a new version of the GH
| action, to make it update README snippet with the sha256 of
| the most recent release, so that it looks like
|
| `uses: actions/checkout@abcdef9876543210` # v4.5.6
|
| Since GitHub doesn't promote good defaults, it's not
| surprising that third-party maintainers do the same.
| kalaksi wrote:
| So much this. I recently looked into using GitHub Actions but
| ended up using GitLab instead since it had official tools and
| good docs for my needs. My needs are simple. Even just little
| scripting would be better than having to use and audit some 3rd
| party repo with a lot more code and deps.
|
| And if you're new, and the repo aptly named, you may not
| realize that the action is just some random repo
| tommasoamici wrote:
| Having to use actions for ssh/rsync always rubbed me the wrong
| way. I've recently taken the time to remove those in favor of
| using the commands directly (which is fairly straightforward,
| but a bit awkward).
|
| I think it's a failure of GitHub Actions that these third party
| actions are so widespread. If you search "GitHub actions how to
| ssh" the first result should be a page in the official
| documentation, instead you'll find tens of examples using third
| party actions.
| naikrovek wrote:
| I've been saying for a while that there aren't supply chain
| problems when the supply chain is the problem.
|
| I'm getting to the point where I feel that library use at all
| should be frowned upon, unless it is your own library, with
| obvious exceptions for the most widely used things like
| encryption and authentication. None of these things are
| particularly difficult, people just don't want to do them "oh
| noes my velocity"
| eviks wrote:
| And writing your library should be frowned upon because you can
| easily add a major security vulnerability with your own two
| hands
| naikrovek wrote:
| If my library is left-padding a string with spaces, I don't
| know how that could possibly introduce a major security
| vulnerability at all.
|
| People write the trusted, secure code, and people retire from
| that work, and new people need to come in and do the work.
| Inexperienced people are going to be writing code no matter
| what.
|
| So, you are either saying that no one should write new
| libraries because a major security vulnerability could be
| introduced by their hands, or you are saying that all
| libraries should be written by hands which will not introduce
| a major security vulnerability, and neither of those is at
| all feasible.
| eviks wrote:
| Well, broaden your horizon a bit from an irrelevant example
| of a "library" of a few lines to a real one a of few
| thousand lines, then you might know. Also those same people
| also write insecure code before they retire. Experienced
| people write security bugs all the time.
|
| What I'm saying is if you imagine a world where there is so
| much time to be wasted rewriting the same library a
| thousand times, you could try to imagine spending a small
| share of that time hardening the supply chain
| londons_explore wrote:
| > await exec.getExecOutput('bash', ['-c', `echo "aWYgW1sgIiRPU1RZ
| UEUiID09ICJsaW51eC1nbnUiIF1dOyB0aGVuCiAgQjY0X0JMT
|
| This malicious code isn't hard to recognise... Surely someone can
| run an LLM over all code in GitHub and just ask it 'does this
| code looks like it's blatantly trying to hide some malicious
| functionality'?
|
| Then review the output and you'll probably discover far more
| cases of this sort of thing.
| gkbrk wrote:
| What if before the command, there is also a code comment that
| says "this is not malicious, it has been manually verified by
| the engineers" and the LLM just believes it?
| edoceo wrote:
| Noob question: is it possible to version lock these things? Could
| one "vendor" these tools into a fork and use that in the
| pipeline? Maybe it's one of those possible but crazy endeavour?
| werrett wrote:
| You can pin GitHub Actions to specific versions or specific
| commits. But note you can change version tags arbitrarily. In
| this specific case, the bad actor changes all of the version
| tags to point to their malicious commit: https://github.com/tj-
| actions/changed-files/tags
|
| So to avoid that you'd have to pin your GitHub Action to
| specific commits as outlined in this SO post:
| https://stackoverflow.com/a/78905195
| zahlman wrote:
| > In this specific case, the bad actor changes all of the
| version tags to point to their malicious commit:
| https://github.com/tj-actions/changed-files/tags
|
| This required compromising the entire repository, yes? It
| can't be explained as the maintainer being tricked into
| merging something malicious?
| ImPostingOnHN wrote:
| The repo looks like it uses itself in its workflows, so
| it's possible that the commit being merged resulted in the
| necessary credentials being leaked to the attacker.
| rognjen wrote:
| There doesn't seem to be a PR for the commit though.
| werrett wrote:
| Yes. It was probably a maintainer's creds being
| compromised.
|
| The [malicious commit is masquerading as a commit from
| Renovate](https://github.com/tj-actions/changed-files/commi
| t/0e58ed867...)((https://github.com/apps/renovate) but it's
| not a `verified` commit (and so it's trivial for a bad
| actor to masquerade as them).
|
| https://stackoverflow.com/questions/67609381/why-do-all-
| my-g...
| nomilk wrote:
| I'd used GitHub Actions for at least 6-12 months before even
| realising <thing>/<thing> was not something that got parsed by
| the action (like a namespace and method/function), but was simply
| a reference to a github user name and repo. That whole object
| should really have been called a 'repo', because that's what it
| is, and that would alert users to use extreme caution whenever
| using one that wasn't created by themselves.
| Griffinsauce wrote:
| Another fun fact related to this is that when someone changes
| their github username, their actions break. Just a hilariously
| bad design IMO. There should be a repository in between with
| immutable versions.
| nextts wrote:
| Well timed for the weekend. Some teams may notice Monday morning.
| londons_explore wrote:
| So this dumps env to stdout using some obfustucated code? And
| then relies on the fact logs are viewable publicly so the
| attacker can go scrape your secrets.
|
| If so, why did they use obfustucated code? Seems innocuous enough
| to load env into environment vars, and then later to dump all env
| vars as part of some debug routine. Eg. 'MYSQL env var not set,
| mysql integration will be unavailable. Current environment vars:
| ${dumpenv}'
| werrett wrote:
| No idea. But they didn't do a great job -- they broke the
| action, which caused build failures that people were going to
| notice.
|
| The malicious commit only landed at 09:57 PDT today (March 14)
| in one specific action (out of a number that is quite popular).
| Maybe they were planning on coming back and doing proper exfil?
| mceachen wrote:
| Presumably the cracker:
|
| 1. spoofed an account whose PRs were auto-merged
| (renovate[bot]) 2. found that `index.js` was marked as binary,
| and knew that GitHub is "helpful" (for the exploit), and hides
| diffs in the PR for that file by default 3. shoved the chunk of
| base64 wayyyy down the commit, so the maintainer had review
| fatigue by the time they scrolled. Having "memdump.py" in the
| commit in plaintext would certainly highlight the exploit more
| than the b64 string.
| captn3m0 wrote:
| Sounds about right to me. We can use a few knowns about
| GitHub IAM to deduce a few things:
|
| 1. There are no deleted PRs or Issues on the repo (2461..2463
| are all valid refs)
|
| 2. A legitimate `Renovate[Bot]` dep bump would have filed a
| PR. Last such PR was 5 days ago, and is presumably not the
| source for this. (I haven't gone through every dep change,
| but doesn't look like it).
|
| 3. That leaves us with the 0e58ed867 commit, which has to be
| a spoofed commit, since it doesn't belong to a branch and we
| don't have a corresponding PR(1). A complete takeover of the
| repo can result in a hanging commit (by deleting the renovate
| bump branch), but there must be a hanging PR-ref around.
| Since there isn't one:
|
| 4. All of the above points to a compromised account that has
| write access to the repo.
|
| There is also the https://github.com/tj-actions-bot account,
| but unclear if it has write access.
|
| Edit: gurchik's guess at https://github.com/tj-
| actions/changed-files/issues/2463#issu... seems more likely:
|
| > 1. Fork the repository > > 2. Push compromised code to the
| fork > > 3. Update the tags in the parent repository to point
| to the SHA of the fork
| rognjen wrote:
| > Update the tags in the parent repository to point to the
| SHA of the fork
|
| I don't think that's possible.
|
| Forks are a GitHub UI construct.
|
| There would be two .git dirs so for all intents and
| purposes they're two repos that don't know about each
| other.
|
| Locally you can't refer to a commit that's in a different
| dir...
| captn3m0 wrote:
| You just set two remotes locally, create a tag and push
| just the tag to upstream. You can definitely do it
| locally, and I think GitHub doesn't prevent such pushes
| either.
| cedws wrote:
| I called it:
|
| https://cedwards.xyz/github-actions-are-an-impending-securit...
| btown wrote:
| Does anyone know if https://github.com/tj-actions/verify-changed-
| files/ was compromised as well?
| themgt wrote:
| This is hilarious, the maven-lockfile project "Lockfiles for
| Maven. Pin your dependencies. Build with integrity" appears to
| have auto-merged a PR for the compromised action commit. So the
| real renovate bot immediately took the exfiltration commit from
| the fake renovate bot and started auto-merging it into other
| projects:
|
| https://github.com/chains-project/maven-lockfile/pull/1111
| sureIy wrote:
| The fun part is that they used commits specifically for
| security, but then add an auto-updater. Might as well use tags.
| mdaniel wrote:
| heh, timing is everything https://github.com/chains-
| project/maven-lockfile/issues/1085...
|
| > After some cleanup the changed-files (https://github.com/tj-
| actions/changed-files) action seems to be more work to remove.
| It would be awesome if it could be added to the allowlist
|
| > Done. Allowed all versions of this action. Should I pin it to
| one version in the allowlist (won't be convenient if renovate
| updates this dependency)?
| joshka wrote:
| Just leaving this here...
|
| https://docs.github.com/en/actions/security-for-github-actio...
| sangeeth96 wrote:
| Don't want to be alarmist but even if not using this action
| directly, I wonder what implications might be if this has leaked
| tokens from prominent public-facing project repos which might be
| used by several folks? I spotted an issue[1] to fix this in Expo
| EAS CLI and I'm guessing there are many more. The payload I saw
| from the report only seems to dump things to stdout but I guess
| analysis is still in progress and IDK if it's the same payload
| for all the tags.
|
| [1]: https://github.com/expo/eas-cli/pull/2948/files
| mdaniel wrote:
| The semgrep URL about this seems to have won the submission
| lottery: https://news.ycombinator.com/item?id=43368870
| mellosouls wrote:
| A list of projects claimed to be using it from the GitHub page:
|
| https://github.com/tj-actions/changed-files?tab=readme-ov-fi...
| jeeyoungk wrote:
| Looks like a lot of them are pinning to tags (which are not
| guaranteed to change) or SHA (https://github.com/vitejs/vite/bl
| ob/8da04227d6f818a8ad9efc00...) which is more hermetic.
| gizzlon wrote:
| tags do not help, they're just a labelor a pointer
| oefrha wrote:
| > https://github.com/tj-actions/changed-files/pull/2460
|
| This kind of auto dependency bump bots are more trouble than
| their worth. If your app works today, bumping random deps won't
| make it work better in any meaningful sense in 95% of cases. With
| such a small upside, the downside of introducing larger attack
| surfaces, subtle breakages (despite semver), major breakages, and
| in the worst cases, compromises (whether it's a compromised dep,
| or fake bot commits that people are trained to ignore) just
| completely outweighs the upside. You're on the fast lane to
| compromises by using this kind of crap.
|
| People should really learn from Go's minimum version selection
| strategy.
| lostmsu wrote:
| Your app will have unpatched vulnerabilities.
| oefrha wrote:
| As long as you subscribe to security advisories, it's a lot
| more likely that new vulnerabilities are introduced than old
| undiscovered vulnerabilities are accidentally patched. In
| fact barring rewrites (which usually won't be picked up by
| semver-respecting auto bumps anyway) I can hardly think of an
| example of the latter.
| rajbot wrote:
| This GitHub Action is still compromised, leaving thousands of
| repositories vulnerable.
|
| Is there anyone here from GitHub that can help get this fixed?
| captn3m0 wrote:
| Helpful update: The gist author has deleted the gist, so
| https://gist.githubusercontent.com/nikitastupin/30e525b776c4...
| now results in a 404, and stops the action from any further
| secrets being leaked. This means you're impacted only if you used
| the action, and had a build triggered in the last 6 hours or so.
| lmc wrote:
| Beautiful... 3rd party dependency exploit thwarted by its own
| 3rd party dependency.
| Sytten wrote:
| I am surprised nobody here mentionned immutable github actions
| that are coming [1]. Been waiting for them since the issue was
| open in 2022. This would have significantly reduce impact and
| hopefully github will get it over the finish line.
|
| I always fork my actions or at least use a commit hash.
|
| [1] https://github.com/features/preview/immutable-actions
| ricardobeat wrote:
| I thought actions were already immutable and published to a
| registry, not fetched directly from their repo. TIL.
|
| Go also uses tags for module versioning, and while go.mod or
| package-lock.json stop this attack from reaching existing
| consumers, allowing remapping of all versions to the
| compromised one still expands the impact surface a lot. GitHub
| should offer a "immutable tags" setting for repos like these.
| samschooler wrote:
| https://gist.github.com/gmatuz/7186f583df5f28196cc1f402af3bf...
|
| This gist is pretty much the exact code, from the base64 encoded
| stuff. Looks like who ever put this in at least neafed the shell
| script.
| gbraad wrote:
| Am I seeing this correctly, that a (fake/impersonation?) Renovate
| bot actually proposed the fix... and then other repositories
| trickled that fix in, also suggested by Renovate or Dependabot,
| as the dependency updated?
|
| I usually fork (or create my own) actions, as I do not trust the
| whole chain on GitHub. The marketplace does no enforcement. It is
| really based on trust you have in the 3rd-party... and I do not
| have this; as many actions have side-effects, or only operate on
| a specific runner OS, etc.
| brown9-2 wrote:
| Renovate sending PRs to projects to upgrade their action
| version is unrelated to the original comment having a spoofed
| author of Renovate
| Everdred2dx wrote:
| How does this siphon the secrets away? It looks like it just
| dumps them out to stdout and stops there.
| varunsharma07 wrote:
| Yes, just prints to the build log, so the risk is higher for
| public repos. Lot of public repos have creds printed in their
| build logs due to this compromised action.
| stephenr wrote:
| I'm sorry I must be missing something.
|
| The examples from the repo itself aren't helping to explain.
|
| Why would anyone use this whole convoluted nodejs thing when `git
| diff-tree` exists?
|
| I'm struggling to see a scenario where this isn't just part of
| some deliberately over complicated rube Goldberg setup.
| globular-toast wrote:
| Shocked Pikachu anyone?
| eacapeisfutuile wrote:
| What is the current state? Tags reverted or still poisoned?
| phantomathkg wrote:
| User and repo all 404 now.
|
| https://github.com/tj-actions
|
| https://github.com/tj-actions/changed-files
| eacapeisfutuile wrote:
| Damn, so fully pulled, by authors, GitHub or adversary?
| eacapeisfutuile wrote:
| Hey, please tell me how my comment was bad in some way
| instead of just downvoting. It was a genuine question if
| anyone might have insight.
| vimgrinder wrote:
| with all the AI stuff going around, can't github just scan repos
| for such malicious code?
| prmph wrote:
| To me the only solution is that we need a security in depth
| approach:
|
| - Create a trusted packages program, and mark trusted packages
| with a prominent badge. Package authors can apply to join the
| program, which will involve a review of their package and any
| subsequent updates. Ensure trusted packages can only depend on
| other trusted packages.
|
| - Implement a capabilities model for package managers. I hear
| Deno is better in that respect.
|
| - Have the package manager back-end use AI to continually review
| the packages. If anything suspicious is found, flag it and
| investigate manually.
|
| - Require all packages to be name-spaced
| carols10cents wrote:
| who is going to pay for the review of packages and updates? how
| do we know we can trust the reviewers?
|
| github actions are name-spaced and that didn't help anything
| here...
| ebfe1 wrote:
| Doing a bit of investigation with github_events in clickhouse, it
| is quite clear that the accounts used to perform the attack was
| "2ft2dKo28UazTZ", "mmvojwip" also seems suspicious:
|
| https://play.clickhouse.com/play?user=play#c2VsZWN0ICogZnJvb...
|
| Actions taken by the threat actor at the time can be seen here:
|
| https://play.clickhouse.com/play?user=play#c2VsZWN0ICogZnJvb...
| ebfe1 wrote:
| Note that these account seems to be deleted now -
| 2ft2dKo28UazTZ clearly did more than just changed-files and
| also seem to target coinbase/agentkit as well (Actually .. they
| might be targeted by the threat actor)
| ebfe1 wrote:
| It seems i forgot to cater for the quota applied to free "play"
| user in ClickHouse in my previous query... In fact, the threat
| actor did a lot more... this should give a better list of
| actions that was performed - Clearly showed he was testing his
| payload:
|
| https://play.clickhouse.com/play?user=play#c2VsZWN0ICogZnJvb...
| skwashd wrote:
| The GitHub repo and org disappeared while I was poking around.
| Both https://github.com/tj-actions and https://github.com/tj-
| actions/changed-files return 404.
| jtwaleson wrote:
| Is there a safe fork somewhere?
| kareemery wrote:
| Looking for one as well. My gh actions broke and looking for
| a drop in replacement.
|
| Got this working with claude, would love if someone with more
| knowledge had thoughts:
|
| ```bash # Extract branch name from GITHUB_REF or
| GITHUB_HEAD_REF echo "current_branch=${GITHUB_HEAD_REF:-${GIT
| HUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT # Determine if this
| is the default branch if [[ "${GITHUB_REF#refs/heads/}" ==
| "${GITHUB_REF_NAME}" && "${GITHUB_REF_NAME}" ==
| "${GITHUB_BASE_REF:-${GITHUB_REF_NAME}}" ]]; then echo
| "is_default=true" >> $GITHUB_OUTPUT else echo
| "is_default=false" >> $GITHUB_OUTPUT fi # Set default branch
| name echo
| "default_branch=${GITHUB_BASE_REF:-${GITHUB_REF_NAME}}" >>
| $GITHUB_OUTPUT ```
| isamu_2000 wrote:
| https://github.com/dorny/paths-filter ? looking into it.
|
| Definitely going through and pinning all my 3rd party actions
| to specific commits e.g. party/package@<commitsha>.
| jtwaleson wrote:
| A colleague sent this: https://github.com/trmlabs/changed-
| files
| hn8726 wrote:
| I wish Github didn't just purge entire repositories/accounts in
| the event like this, although I know why they do this. But
| there's now no way to analyze the repository/exploit anymore
| sathyabhat wrote:
| See also - https://news.ycombinator.com/item?id=43368870
| eacapeisfutuile wrote:
| Was the entire repo just deleted from GitHub?
| mmsc wrote:
| Paid Github organizations have a policy to block third-party
| actions. Would be nice if there was a way to allow third-party
| actions as long as they are referenced by hash, not version.
| m4rtink wrote:
| Another reason why you should be getting software via distro,
| with searate maintainers taking care of it there rather than
| directly from the developers that can inject malware via the very
| next version you mindlessly pull in without checking.
|
| Also due to here being usually more than one distro, more people
| will look at the code & can spot the usptream getting rogue or
| getting compromised.
| SAI_Peregrinus wrote:
| Adding MITM to your chain of trust doesn't make it more
| trustworthy, it adds an extra possible attacker.
| m4rtink wrote:
| Often there is vetting before one becomes a distro maintainer
| & even if one of them gets compromised, the blast radius is
| at least limitted to that one distro, rather than "everyone"
| like in case of NPM & co. Non rolling distros aslo have
| various policies for package updates, making it much harder
| to get a compromised package to all supported distro versions
| before it is eventually discovered.
| imoreno wrote:
| Actually it does. The repo maintainer is on the user's side,
| so they are doing MITM on the attack vector. This makes it
| harder to get your malicious code in, because MITM might
| intercept it.
|
| Yes now you have to trust the maintainer but that's sometimes
| easier.
| rarkins wrote:
| Hi, Renovate author/maintainer here.
|
| The affected repo has now been taken down, so I am writing this
| partly from memory, but I believe the scenario is:
|
| 1. An attacker had write access to the tj-actions/changed-files
| repo
|
| 2. The attacker chose to spoof a Renovate commit, in fact they
| spoofed the most recent commit in the same repo, which came from
| Renovate
|
| 3. Important: this spoofing of commits wasn't done to "trick" a
| maintainer into accepting any PR, instead it was just to
| obfuscate it a little. It was an orphan commit and not on top of
| main or any other branch
|
| 4. As you'd expect, the commit showed up as Unverified, although
| if we're being realistic, most people don't look at that or
| enforce signed commits only (the real bot signs its commits)
|
| 5. Kind of unrelated, but the "real" Renovate Bot - just like
| Dependabot presumably - then started proposing PRs to update the
| action, like it does any other outdated dependency
|
| 6. Some people had automerging of such updates enabled, but this
| is not Renovate's default behavior. Even without automerging, an
| action like this might be able to achieve its aim only with a PR,
| if it's run as part of PR builds
|
| 7. This incident has reminded that many people mistakenly assume
| that git tags are immutable, especially if they are in semver
| format. Although it's rare for such tags to be changed, they are
| not immutable by design
| mlor wrote:
| Thanks for taking the time to comment. Not that it wasn't there
| before this, but this incident highlights a lot to take into
| consideration with respect to securing one's supply chain going
| forward.
| diggan wrote:
| > 6. Some people had automerging of such updates enabled, but
| this is not Renovate's default behavior. Even without
| automerging, an action like this might be able to achieve its
| aim only with a PR, if it's run as part of PR builds
|
| I'm not sure how this could exploited by just making a PR,
| unless you for some reason have secrets enabled for builds by
| unknown contributors, which obviously would be a mistake.
| Usually, only builds using secrets only run on certain branches
| which has a known contributor approving the code before it gets
| there.
|
| > people mistakenly assume that git tags are immutable
|
| If you're distributing a library on GitHub used by many other
| people/projects, then you really need to setup `protected
| branches` and `protected tags`, where you can prevent changes
| somewhat.
| semiquaver wrote:
| > I'm not sure how this could exploited by just making a PR,
| unless you for some reason have secrets enabled for builds by
| unknown contributors
|
| In this context the renovate bot would be making the PR to a
| repo it had been installed on, making it a trusted
| contributor able to trigger CI builds on its PRs.
| jonenst wrote:
| Neither Branch Protection nor the newer Rulesets allow to
| protect secrets from someone with push acces to the repo.
| From what I understand, only environment secrets provide this
| feature (and have the drawback that you can't share them
| among multiple repos in the same org without copying them
| everywhere, although you can script the copying with the
| github api)
| srvaroa wrote:
| >7. This incident has reminded that many people mistakenly
| assume that git tags are immutable, especially if they are in
| semver format. Although it's rare for such tags to be changed,
| they are not immutable by design
|
| IME, this will be more "learned" than "reminded". Many many
| people set up pipelines to build artefacts based on tags (e.g.
| a common practise being "on tag with some pattern, then build
| artefact:$tag") and are just surprised if you call out the
| flaws.
|
| It's one of many practises adopted because everyone does it but
| without basic awareness of the tradeoffs. Semver is another
| similar case of inherited practise, where surprisingly many
| people seem to believe that labelling software with a
| particular string magically translates into hard guarantees
| about its behaviour.
| nine_k wrote:
| Tags can be signed, and the signature can be verified. It's
| about as easy as signing / verifying commits. One can even
| make signing tags as the default option when creating tags.
|
| This won't help in this case though, because a legitimate bot
| was tricked into working with a rogue commit; a tricked bot
| could as well sign a tag with a legitimate key.
|
| "Immutable tags" of course exist, they are commit hashes, but
| they are uninformative :(
| greatgib wrote:
| Honestly now most people doing "modern software engineering" are
| retards with no concept of real software engineering concepts.
|
| Shitload of cardboard cto are pushing for "modern practice" to
| use whatever new version of whatever random dependency downloaded
| straight from internet.
|
| Some persons asked why I don't like Ruff or UV for Python for
| example? You start a new job, first thing you have to do after
| installing a serious and safe Linux distribution like debian:
|
| Curl whateverwebsite.com/ruff/download/latest | bash --blindly-
| execute --like-an-idiot
|
| -> retrieving-random-dependancy1.tgz
|
| -> executing-random-code...
|
| And I don't speak about the current trend with "pre-commit" where
| a lot of persons are ok to have automatic downloads and execution
| on dev machines and ci, at each commit, of hundred of really
| totally random plugins from random places.
|
| But this is a cto enforced decision to have this pre-commit for
| software quality...
| trallnag wrote:
| There are usually several different ways to install tools like
| uv. For example, uv is available as a Homebrew formula.
|
| And regarding pre-commit: It usually relies on external code,
| but it is not a requirement. Pre-commit can also be used to
| just run arbitrary commands and scripts defined within the pre-
| commit config using the values "system" or "script" for the
| "language" key.
| imglorp wrote:
| Anybody have a snapshot of the good one, or maybe a drop in
| replacement? The repo is gone now.
| thinkplay11 wrote:
| Yup this would be super useful. Scouring about now trying to
| find
| v1sionSec wrote:
| As the repo is was taken down is someone able to tell me when was
| the malicious commit pushed. Trying to get a timeline to see if
| any workflows using this action were trigger in that timeframe.
| Thank you
| imnotjames wrote:
| Your secrets will be published to the CI log if you were
| affected.
|
| I believe it's everything since around 10pm ET last night. I
| would consider any runs in the past 24 hours to be suspect.
| v1sionSec wrote:
| Thank you, unfortunately we have a multiple of repositories
| with multiple runs that use this action so checking the logs
| one by one will be hard. Any idea how to get all logs? Thank
| you
| mixologic wrote:
| also the secrets will be published as double base 64
| encoded, so it will just look like a string of random chars
| at the end of the changed-files action in the log.
| mongrelion wrote:
| I think your best bet is to traverse all the pipeline logs
| that make use of the action using Github's REST API.
|
| It should be easy to do with thr Github CLI tool and some
| bash scripting.
|
| Not sure how easy it'll be to parse the logs to look for a
| base64 string but it shouldn't be that complicated either.
| imnotjames wrote:
| If you are using the action and were as of 10p ET last
| night I would assume everything is compromised, remove the
| action, and rotate secrets.
| alper wrote:
| Somewhere after 18:00 CET Friday.
| MotiBanana wrote:
| Does anyone know if the secrets compromised were sent out, or
| just printed to stdout? We don't have any public repos using this
| action.
| varunsharma07 wrote:
| They were only printed to stdout and not sent out
| alper wrote:
| GitHub's incident response to this took 17 hours give or take.
|
| Actions is a paid service but Microsoft probably replaced all the
| security teams with AI.
| onnimonni wrote:
| It seems pretty awful that the de-facto way to use GitHub Actions
| is using git tags which are not immutable. For example to
| checkout code [1]:
|
| - uses: actions/checkout@v4
|
| Github does advise people to harden their actions by referring to
| git commit hashes [2] but Github currently only supports SHA-1 as
| hashing algorithm. Creating collisions with this hashing algo
| will be more and more affordable and I'm afraid that we will see
| attacks using the hash collisions during my lifetime.
|
| I wish that they will add support for SHA-256 soon and wrote
| product feedback regarding it here:
| https://github.com/orgs/community/discussions/154056
|
| If this resonates with you please go and give it a thumbs up :)
|
| [1]: https://github.com/actions/checkout?tab=readme-ov-file#usage
|
| [2]: https://docs.github.com/en/actions/security-for-github-
| actio...
| onnimonni wrote:
| I wasn't aware of the already existing SHA-1 collision support
| created by Github. It's very interesting read and AFAIK it
| seems that using SHA-1 collisions is not possible:
|
| https://github.blog/news-insights/company-news/sha-1-collisi...
|
| Is anyone aware of a git hook I could use to analyse my
| .github/workflows/*.yml files and replace git tags like "v4"
| with the current git commit hashes?
|
| I think this would make it much safer to use 3rd party GitHub
| Actions.
| Y_Y wrote:
| That's the sort of hook you should be able to write yourself
| pretty quickly. So I threw your comment into o3-mini-high and
| it gave me a decent-looking solution. Decent but wrong, since
| it thought "current git commit" referred to the project repo,
| rather than the referenced dependency.
|
| Anyway here's the gist of a solution without any of the
| necessary checking that the files actually exist etc.
| #!/bin/sh for file in .github/workflows/*.yml; do
| grep -E
| "uses:[[:space:]]+[A-Za-z0-9._-]+/[A-Za-z0-9._-]+@v[0-9]+"
| "$file" | while read -r line; do repo=$(echo
| "$line" | sed -E 's/.*uses:[[:space:]]+([A-Za-z0-9._-]+\/[A-Z
| a-z0-9._-]+)@v[0-9]+.*/\1/') tag=$(echo "$line" |
| sed -E 's/.*@((v[0-9]+)).*/\1/') commit_hash=$(git
| ls-remote "https://github.com/$repo.git" "refs/tags/$tag" |
| awk '{print $1}') [ -n "$commit_hash" ] && sed
| -i.bak -E "s|(uses:[[:space:]]+$repo@)$tag|\1$commit_hash|g"
| "$file" && git add "$file" && rm -f "$file.bak" done
| done exit 0
| onnimonni wrote:
| Thanks! Today I learned:
|
| $ git ls-remote "https://github.com/$repo.git"
| "refs/tags/$tag"
|
| Even though the grep and sed are not very readable this was
| very useful way to avoid yet another tool!
| ffsm8 wrote:
| > ... SHA-1 ... Collusions ... will be more and more
| affordable.
|
| I can put your fears on that account to rest. At current
| trajectory, that's not gonna happen.
|
| While a collision has been successfully produced, that's a
| _very_ far milestone away from creating a specific collision
| with a payload you actually want to deliver with reasonable
| size so any sanity check such as a multi GB file size wouldnt
| "accidentally" detect it through timeouts in CI or similar.
|
| This is so far beyond our current technological capabilities
| and Moore's law hasn't been active for over a decade now. Sure,
| we've had astounding success in the GPU space, but that's still
| not even remotely close to the previous trajectory while on
| Moore's Law.
| deathanatos wrote:
| I've said this before, but in my mind the central problem in
| supply chain issues is this. Choose one:
|
| 1. You fix what version you're using to a fixed, immutable
| package. You receive no updates, no bug fixes, no security
| patches.
|
| 2. You follow a pointer to something like a API-compatible
| version, "latest" (#yolo) or ^5.0.0. You get bug fixes, security
| patches, but someone can push malicious updates.
|
| Security types, IME, invariably want _both_ : fix that package to
| a hash, so that we can't have a take over attack. But also we
| need to stay on top of updates, because we don't want to find out
| we have a decades old struct4j CVE buried in our codebase just
| waiting to be exploited.
|
| So to accomplish "both", then we get into schemes like "fix the
| hashes ... but we'll have a bot1 update our dependency tree
| automatically". So like, #2, with more steps. Is anyone actually
| _vetting_ that that update hash isn 't going to compromise stuff?
| Hell no, no company is hiring that level of engineers; I'm lucky
| to have decent staffing for our primary concerns, reading the
| code in the dependency tree is out of the question.
|
| And I'm sure in the coming days, security minded people will
| stampede in the general direction of #1. Stuff'll get fixed to
| hash, and stuff'll stop getting security patches.
|
| IDK what the _answer_ is, these seem pretty like fundamentally
| opposed forces of nature. The staffing problems aren 't a
| technical problem, that's a capitalism problem, mostly in that
| there is very little to no penalty for a breach, so why would
| anyone hire the eng required to ensure the software works. There
| was hardly regulation in 2024, and any fines I did see regulatory
| bodies award are pittances, without fail. And, what regulation
| there was is now being actively dismantled.
|
| There is some discussion of signed packages in this thread, and
| that's a helpful idea, I think, though I don't think it
| completely eliminates the problem: if the signing key is
| compromised, we're back to square one. The lay eng struggles with
| PKI.
|
| 1While there is a bot of such nature (the renovate bot) somewhat
| tied up in this _particular_ instance, I wouldn 't over-focus on
| that bot, specifically; renovate, in particular, is not that
| relevant to the point I'm trying to make.
| rahulr0609 wrote:
| For folks looking for a drop-in replacement for v45 (latest major
| version), we have a patched mirror here:
| https://github.com/trmlabs/changed-files
|
| 1] We took the public mirror from: https://code.forgejo.org/tj-
| actions/changed-files/src/tag/v4...
|
| 2] Undid the malicious code change: https://code.forgejo.org/tj-
| actions/changed-files/commit/0e5... - You can see the change
| here: https://github.com/trmlabs/changed-
| files/commit/8567847ee196...
|
| 3] Published under a v1 tag (since we can't vet historical
| releases and changes and didn't want folks to get confused)
|
| If you want to contribute or report an issue, file a GH Issue or
| ping us at security@trmlabs.com
| kurmiashish wrote:
| Due to the ongoing security incident involving the tj-
| actions/changed-files Action, we at StepSecurity have provided a
| secure, drop-in replacement: step-security/changed-files.
|
| We strongly advise replacing all instances of tj-actions/changed-
| files in your workflows with our secure alternative:
| https://github.com/step-security/changed-files
| frenchtoast8 wrote:
| The repository is back online, with this explanation from the
| developer:
|
| > This attack appears to have been conducted from a PAT token
| linked to @tj-actions-bot account to which "GitHub is not able to
| determine how this PAT was compromised."
|
| > Account Security Enhancements
|
| > * The password for the tj-actions-bot account has been updated.
|
| > * Authentication has been upgraded to use a passkey for
| enhanced security.
|
| > * The tj-actions-bot account role has been updated to ensure it
| has only the minimum necessary permissions.
|
| > * GitHub proactively revoked the compromised Personal Access
| Token (PAT) and flagged the organization to prevent further
| exploitation.
|
| https://github.com/tj-actions/changed-files/issues/2464#issu...
___________________________________________________________________
(page generated 2025-03-15 23:01 UTC)