Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 233 additions & 0 deletions alpha/engagements/2026/Python Software Foundation/2026-07.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
# 2026-07

## PyPI Safety & Security Engineer (Mike Fiedler)

### Malware Response

July brought 202 malware reports across 173 unique packages.
153 were confirmed and the releases removed,
13 were false positives, and 36 remain open,
for 93.2% accuracy on closed reports.
Another 60-plus reports from prior periods are still queued.
Corroboration held steady at 53 reports (26.2%) carrying two or more independent observers,
and auto-quarantine restricted 108 of the 173 reported packages before anyone looked at them,
so most user-facing exposure was contained ahead of manual review.

Response times slipped.
Of 264 email conversations,
26% closed within 4 hours and another 29% within a day,
but the 21% that ran past 4 days pulled the office-hours average to 2 days 5 hours.
Two of five working weeks went to EuroPython and travel,
and reports arriving during a conference week wait for someone to reach a keyboard.

Mike closed out the ["Hades" wave of the Shai-Hulud campaign](https://www.endorlabs.com/learn/shai-hulud-hades-wave-hits-six-pypi-bioinformatics-packages)
that dominated June with three more advisory batches
([one](https://github.com/pypa/advisory-database/pull/333),
[two](https://github.com/pypa/advisory-database/pull/336),
[final](https://github.com/pypa/advisory-database/pull/344)).
Each entry covers phantom releases published from stolen credentials.
On import, those releases ran a bundled JavaScript payload
that harvested credentials and tried to spread itself further.
Mike also [pinned all GitHub Actions references](https://github.com/pypa/advisory-database/pull/332)
in that repository.

### Security Fixes and Hardening

Mike reviewed and shipped a fix for
[session re-authentication accepting another account's credentials](https://github.com/pypi/warehouse/pull/20126).
The re-auth form carried a hidden username field;
editing it before submission let a stale session be re-authenticated
with a different user's password.
The fix drops the field and validates against the session's own user ID,
with a [follow-up filed](https://github.com/pypi/warehouse/issues/20321)
to keep the two validation paths from drifting apart.

A late-month vulnerability report yielded three false positives and one real finding,
[percent-encoded dots accepted during URL verification](https://github.com/pypi/warehouse/pull/20333),
fixed the same day.
Mike also reviewed a proposed change to
[reject PyPI tokens found in uploaded files](https://github.com/pypi/warehouse/pull/19994),
and reviewed a public disclosure about incidents surfaced during cybersecurity evaluations,
collecting evidence on a related PyPI project.

Using [GitHub's new controls over what can trigger a workflow](https://github.blog/changelog/2026-06-18-control-who-and-what-triggers-github-actions-workflows/),
Mike blocked `pull_request_target` across the `pypi` organization.
Nothing used it, so the policy guards against someone adding one later.
Other organizations publishing to PyPI should consider the same setting.

Email handling is less silent about its own failures now.
Warehouse [re-sends the unrecognized-login notice on repeated attempts](https://github.com/pypi/warehouse/pull/20323)
instead of going quiet after a soft bounce,
[emits a reason whenever a send is skipped](https://github.com/pypi/warehouse/pull/20320),
and has [steadier MX validation coverage](https://github.com/pypi/warehouse/pull/20306).

### Trusted Publishing

[CircleCI as a Trusted Publisher](https://github.com/pypi/warehouse/pull/19349)
is in a second round of review, it's taking a while since there's a lot going on.
Mike helped debug [token expiration behavior on GitHub Actions](https://github.com/sigstore/sigstore-python/issues/1729#issuecomment-5070474146)
and published a [standalone workflow that dumps the OIDC token payload](https://github.com/miketheman/trusted-publishing-debugger/pull/1),
so maintainers can inspect the claims their CI provider emits.
A EuroPython session on Trusted Publishing prompted him
to open conversations with external publishing providers
about the security posture of the claims they issue.
Some of that may turn into changes on their side to further secure Trusted Publishing.

### Observability

Mike moved warehouse logging onto [structlog](https://www.structlog.org/),
[unifying rendering through a single ProcessorFormatter](https://github.com/pypi/warehouse/pull/20341)
and then [migrating module loggers](https://github.com/pypi/warehouse/pull/20343).
Within a day the new logs made clear that a third-party crawler
was generating a large volume of 404s,
and the vendor confirmed they will work on a fix once Mike sent the evidence.

In linehaul he [retired the legacy v1 and v2 payload formats](https://github.com/pypi/linehaul-cloud-function/pull/306)
and [stabilized the hypothesis tests in CI](https://github.com/pypi/linehaul-cloud-function/pull/307),
which unblocks the extra fields needed to measure downloaded bytes.

### Admin and Platform

* Rebuilt the [journals admin pages on Tabulator](https://github.com/pypi/warehouse/pull/20258),
closing a long-open request for a view admins can work in
* Added [project lifecycle status to admin project lists](https://github.com/pypi/warehouse/pull/20345)
and [segmented archived projects on the manage page](https://github.com/pypi/warehouse/pull/20242)
* Added a [trigram index on usernames](https://github.com/pypi/warehouse/pull/20250)
and [deferred heavyweight gcloud imports](https://github.com/pypi/warehouse/pull/20261)
* Added a [`warehouse db seed` command](https://github.com/pypi/warehouse/pull/20342)
so provenance work has realistic development data,
and took on review of [`Release.provenance_status`](https://github.com/pypi/warehouse/pull/20326)
alongside Kris, Dustin, and Nicole
* Continued retiring the `pretend` test-double library
([20238](https://github.com/pypi/warehouse/pull/20238),
[20241](https://github.com/pypi/warehouse/pull/20241),
[20262](https://github.com/pypi/warehouse/pull/20262))
* Opened [pyramid_components](https://github.com/pypi/warehouse/pull/20263) for review,
a typed props contract plus co-located template for HTML components,
tried out in admin views first
* Shipped Dependabot batches carrying security updates

### Community Engagement and Conferences

Mike spent a full week at EuroPython in Kraków.
At the [Packaging Summit](https://ep2026.europython.eu/session/packaging-summit)
he walked through [upcoming changes to the PyPI user interface](https://hackmd.io/DZj3uo6eT_qyddBP0PZlDw?view#5-Mike-Fiedler-Upcoming-changes-to-PyPI-user-Interface),
and he sat in on the Language Summit to see where those decisions land on packaging.
He delivered [Anatomy of a Phishing Campaign](https://ep2026.europython.eu/session/anatomy-of-a-phishing-campaign)
and joined a panel on [Security and Ethics in the Age of Generative AI](https://ep2026.europython.eu/session/security-and-ethics-in-the-age-of-generative-ai).
Sprints covered staged-release lifecycle status with [wheelnext](https://wheelnext.dev/),
operational questions for [pytransparency.dev](https://pytransparency.dev/),
and a draft of API v3.

Closer to home, Mike gave the NYU Secure Systems Lab a primer on PyPI
and heard out their Secure Software Operations Center idea.
He recorded a Talk Python episode on security,
and attended Alpha-Omega and OpenSSF Securing Software Repositories sessions.
He also tested a new Alpha-Omega threat modeling skill against a small Python project
and sent feedback to its author.

### Ecosystem Contributions

Outside PyPI, Mike merged five changes to `pyramid_openapi3`, including
[OpenAPI 3.2 support](https://github.com/Pylons/pyramid_openapi3/pull/324),
[serving the spec as JSON](https://github.com/Pylons/pyramid_openapi3/pull/323),
and a [fix so server prefixes respect path segment boundaries](https://github.com/Pylons/pyramid_openapi3/pull/322).
He also opened a
[proposal to consolidate that project's test authoring approach](https://github.com/Pylons/pyramid_openapi3/issues/319).

In `readme_renderer` he [enabled GFM alerts and shortcodes](https://github.com/pypa/readme_renderer/pull/374),
[stopped RST's top-level heading from being dropped](https://github.com/pypa/readme_renderer/pull/377),
and [handled expected test warnings](https://github.com/pypa/readme_renderer/pull/373).
He made the [osv.dev search input reachable from the keyboard](https://github.com/google/osv.dev/pull/5569),
and kept `stdlib-list` and `inspector` current.

## Security Developer-in-Residence (Seth Larson)

### EuroPython 2026

Seth attended EuroPython 2026 to speak in multiple sessions
and to attend summits and sprints. Seth attended and was the
blogger for the Python Language Summit and attended the
Python Packaging Summit.

Seth delivered a talk titled “[Learning from the “not‑so‑secret” Python security cabal](https://sethmlarson.dev/europython-2026-security-talk)”
which discussed how LLMs were affecting open source security teams, what
individual contributors can do to start their journey to joining
and contributing to an OSS security team, and how projects can start thinking
about this period of experimentation we're all in.

This talk is a continuation of a talk I gave a year ago: “Security Work isn’t
Special” as the keynote for OpenSSF Community Day NA where I lamented on how security
work didn't match other Open Source contribution models like documentation, community,
or code contributions.

Seth was also a member of the AI, Cybersecurity, and Ethics panel along with
Mike Fiedler and three other experts. This panel recording is
[now published to YouTube](https://www.youtube.com/watch?v=4cfgbo912rg).

### Python.org Security Fixes

Following the report on mitigating an API authentication bypass
for python.org, we received the expected uptick in scrutiny from
other security researchers. Seth responded to the reported issues
and applied the fixes:

* [Sanitize the HTML descriptions](https://github.com/python/pythondotorg/pull/3075)
imported from trusted iCalendar/ICS
files prior to displaying them on event detail pages. This prevents
a malicious takeover of a remote event calendar from being able
to inject malicious HTML into an event detail page.
* [Restrict editing of nominations outside a nomination window](https://github.com/python/pythondotorg/pull/3074).
* [Community posts that are private should not be returned in the API](https://github.com/python/pythondotorg/pull/3073).
* [Blog excerpt text still requires escaping](https://github.com/python/pythondotorg/pull/3072), even after `striptags` filter is applied.
* [Sanitize `MarkupField` content](https://github.com/python/pythondotorg/pull/3067) to a restricted list of tags and attributes using nh3.
This affected many user-editable full-text fields including event descriptions and nominations.
* Upgraded dependencies ([Django, idna](https://github.com/python/pythondotorg/pull/3071)
[Pillow](https://github.com/python/pythondotorg/pull/3068)) that were affected by vulnerabilities.

A longer-term project is [adding a strict ``Content-Security-Policy``
HTTP header](https://github.com/python/pythondotorg/pull/3042)
to ``python.org``, but this will take a bit of time
to avoid breaking the website while others are using the service.
For now a ``Report-Only`` HTTP header is in place and the plan
is to monitor the violations using Sentry before making the
switch to enforce violations if no impact is detected.

## Restricted "Open-Releases" on PyPI

The Python Package Index (PyPI) now rejects new files being uploaded to releases
that are older than 14 days. This restriction was put in place to prevent old and
long-stable releases from being poisoned in case publishing tokens or workflows of
PyPI projects were compromised. As far as we are aware this has not yet been abused,
but there is no technical reason beyond that attackers weren't aware it was possible.

This work was done after [restarting a conversation](https://discuss.python.org/t/restricting-open-ended-releases-on-pypi/43566/34) (following the LiteLLM/Telnyx
compromises) that started [back in January 2024](https://discuss.python.org/t/restricting-open-ended-releases-on-pypi/43566). With help from data gathered
by Mike Fiedler and Hugo van Kemenade and through discussing the issue
at the PyCon US 2026 Packaging Summit we were able to come to a rough consensus
and move forward with the restriction.

Seth [made the changes to PyPI]() and then [published a blog post](https://blog.pypi.org/posts/2026-07-22-releases-now-reject-new-files-after-14-days/)
to the PyPI blog detailing this change and the journey to get there. Seth also [fixed
a small bug](https://github.com/pypi/warehouse/pull/20260) in the implementation which
broke an existing benign workflow using `twine upload --skip-existing`.

### Hiring another Security Developer

The Python Software Foundation is hiring another Security Developer
to work on the Python Security Response Team and PyPI malware handling.
Seth is the hiring manager for this role and has been preparing the role
description, screening, and interview pipeline.

### Other items

* Applying to the Common Good Cyber Fund grant with Loren Crary.
* Working on the Python Security Response Team report queue.
* Nominated Tania Allard to the PSRT.
* Published the advisory for pip (CVE-2026-13346) and Python's HTML parser (CVE-2026-15308).
* Interviewed by IEEE Spectrum about slopsquatting and LLMs effects on
open source security.
* Recorded an episode of Talk Python about "Everything Security at PyCon US 2026"
with Juanita Gomez and Mike Fiedler.
* Published a blog post with a [wrap-up for United Nations Open Source Week 2026](https://sethmlarson.dev/un-open-source-week-2026).

Loading