diff --git a/alpha/engagements/2026/Python Software Foundation/2026-07.md b/alpha/engagements/2026/Python Software Foundation/2026-07.md new file mode 100644 index 00000000..a16b0dda --- /dev/null +++ b/alpha/engagements/2026/Python Software Foundation/2026-07.md @@ -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). +