CINXE.COM

The Python Package Index Blog

<!doctype html> <html lang="en" class="no-js"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="description" content="The official blog of the Python Package Index"> <link rel="canonical" href="https://blog.pypi.org/"> <link rel="next" href="tags/"> <link rel="alternate" type="application/rss+xml" title="RSS feed" href="feed_rss_created.xml"> <link rel="alternate" type="application/rss+xml" title="RSS feed of updated content" href="feed_rss_updated.xml"> <link rel="icon" href="assets/favicon.ico"> <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.11"> <title>The Python Package Index Blog</title> <link rel="stylesheet" href="assets/stylesheets/main.4af4bdda.min.css"> <link rel="stylesheet" href="assets/stylesheets/palette.06af60db.min.css"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback"> <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style> <link rel="stylesheet" href="stylesheets/extra.css"> <script>__md_scope=new URL(".",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script> <script id="__analytics">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e("js",new Date),e("config","G-4L9L0H79CY"),document.addEventListener("DOMContentLoaded",(function(){document.forms.search&&document.forms.search.query.addEventListener("blur",(function(){this.value&&e("event","search",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll("[type=submit]"))a.addEventListener("click",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute("data-md-value");e("event","feedback",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(".md-feedback__note [data-md-value='"+d+"']");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e("config","G-4L9L0H79CY",{page_path:t.pathname})}))}));var t=document.createElement("script");t.async=!0,t.src="https://www.googletagmanager.com/gtag/js?id=G-4L9L0H79CY",document.getElementById("__analytics").insertAdjacentElement("afterEnd",t)}</script> <script>"undefined"!=typeof __md_analytics&&__md_analytics()</script> <meta property="og:type" content="website" > <meta property="og:title" content="The Python Package Index Blog" > <meta property="og:description" content="The official blog of the Python Package Index" > <meta property="og:image" content="https://blog.pypi.org/assets/images/social/index.png" > <meta property="og:image:type" content="image/png" > <meta property="og:image:width" content="1200" > <meta property="og:image:height" content="630" > <meta property="og:url" content="https://blog.pypi.org/" > <meta name="twitter:card" content="summary_large_image" > <meta name="twitter:title" content="The Python Package Index Blog" > <meta name="twitter:description" content="The official blog of the Python Package Index" > <meta name="twitter:image" content="https://blog.pypi.org/assets/images/social/index.png" > <link rel="alternate" type="application/feed+json" title="JSON feed" href="feed_json_created.json" /> <link rel="alternate" type="application/feed+json" title="JSON feed of updated content" href="feed_json_updated.json" /> <script async type="text/javascript" src="/_/static/javascript/readthedocs-addons.js"></script><meta name="readthedocs-project-slug" content="blogpypiorg" /><meta name="readthedocs-version-slug" content="latest" /><meta name="readthedocs-resolver-filename" content="/" /><meta name="readthedocs-http-status" content="200" /></head> <body dir="ltr" data-md-color-scheme="pypi" data-md-color-primary="indigo" data-md-color-accent="indigo"> <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <label class="md-overlay" for="__drawer"></label> <div data-md-component="skip"> <a href="#the-pypi-blog" class="md-skip"> Skip to content </a> </div> <div data-md-component="announce"> </div> <header class="md-header md-header--shadow" data-md-component="header"> <nav class="md-header__inner md-grid" aria-label="Header"> <a href="https://pypi.org" title="The Python Package Index Blog" class="md-header__button md-logo" aria-label="The Python Package Index Blog" data-md-component="logo"> <img src="assets/logo.png" alt="logo"> </a> <label class="md-header__button md-icon" for="__drawer"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class="md-header__title" data-md-component="header-title"> <div class="md-header__ellipsis"> <div class="md-header__topic"> <span class="md-ellipsis"> The Python Package Index Blog </span> </div> <div class="md-header__topic" data-md-component="header-topic"> <span class="md-ellipsis"> The PyPI Blog </span> </div> </div> </div> <form class="md-header__option" data-md-component="palette"> <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="pypi" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to Dark mode" type="radio" name="__palette" id="__palette_0"> <label class="md-header__button md-icon" title="Switch to Dark mode" for="__palette_1" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg> </label> <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to Light mode" type="radio" name="__palette" id="__palette_1"> <label class="md-header__button md-icon" title="Switch to Light mode" for="__palette_0" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> </label> <div class="md-search" data-md-component="search" role="dialog"> <label class="md-search__overlay" for="__search"></label> <div class="md-search__inner" role="search"> <form class="md-search__form" name="search"> <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required> <label class="md-search__icon md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </label> <nav class="md-search__options" aria-label="Search"> <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg> </button> </nav> </form> <div class="md-search__output"> <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix> <div class="md-search-result" data-md-component="search-result"> <div class="md-search-result__meta"> Initializing search </div> <ol class="md-search-result__list" role="presentation"></ol> </div> </div> </div> </div> </div> <div class="md-header__source"> <a href="https://github.com/pypi/warehouse" title="Go to repository" class="md-source" data-md-component="source"> <div class="md-source__icon md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg> </div> <div class="md-source__repository"> GitHub </div> </a> </div> </nav> </header> <div class="md-container" data-md-component="container"> <main class="md-main" data-md-component="main"> <div class="md-main__inner md-grid"> <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" > <div class="md-sidebar__scrollwrap"> <div class="md-sidebar__inner"> <nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0"> <label class="md-nav__title" for="__drawer"> <a href="https://pypi.org" title="The Python Package Index Blog" class="md-nav__button md-logo" aria-label="The Python Package Index Blog" data-md-component="logo"> <img src="assets/logo.png" alt="logo"> </a> The Python Package Index Blog </label> <div class="md-nav__source"> <a href="https://github.com/pypi/warehouse" title="Go to repository" class="md-source" data-md-component="source"> <div class="md-source__icon md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg> </div> <div class="md-source__repository"> GitHub </div> </a> </div> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item md-nav__item--active"> <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc"> <span class="md-ellipsis"> The PyPI Blog </span> <span class="md-nav__icon md-icon"></span> </label> <a href="." class="md-nav__link md-nav__link--active"> <span class="md-ellipsis"> The PyPI Blog </span> </a> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class="md-nav__title" for="__toc"> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> <li class="md-nav__item"> <a href="#introducing-our-new-terms-of-service" class="md-nav__link"> <span class="md-ellipsis"> Introducing our new Terms of Service </span> </a> </li> <li class="md-nav__item"> <a href="#pypi-now-supports-project-archival" class="md-nav__link"> <span class="md-ellipsis"> PyPI Now Supports Project Archival </span> </a> </li> <li class="md-nav__item"> <a href="#project-quarantine" class="md-nav__link"> <span class="md-ellipsis"> Project Quarantine </span> </a> </li> <li class="md-nav__item"> <a href="#supply-chain-attack-analysis-ultralytics" class="md-nav__link"> <span class="md-ellipsis"> Supply-chain attack analysis: Ultralytics </span> </a> </li> <li class="md-nav__item"> <a href="#malware-package-analysis-aiocpa" class="md-nav__link"> <span class="md-ellipsis"> Malware Package Analysis: aiocpa </span> </a> </li> <li class="md-nav__item"> <a href="#pypi-now-supports-digital-attestations" class="md-nav__link"> <span class="md-ellipsis"> PyPI now supports digital attestations </span> </a> </li> <li class="md-nav__item"> <a href="#safety-security-engineer-first-year-in-review" class="md-nav__link"> <span class="md-ellipsis"> Safety &amp; Security Engineer: First Year in Review </span> </a> </li> <li class="md-nav__item"> <a href="#incident-report-leaked-github-personal-access-token" class="md-nav__link"> <span class="md-ellipsis"> Incident Report: Leaked GitHub Personal Access Token </span> </a> </li> <li class="md-nav__item"> <a href="#prohibiting-outlook-email-domains" class="md-nav__link"> <span class="md-ellipsis"> Prohibiting Outlook email domains </span> </a> </li> <li class="md-nav__item"> <a href="#expanding-trusted-publisher-support" class="md-nav__link"> <span class="md-ellipsis"> Expanding Trusted Publisher Support </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="tags/" class="md-nav__link"> <span class="md-ellipsis"> Tags </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_3" > <label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0"> <span class="md-ellipsis"> Archive </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_3"> <span class="md-nav__icon md-icon"></span> Archive </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="archive/2025/" class="md-nav__link"> <span class="md-ellipsis"> 2025 </span> </a> </li> <li class="md-nav__item"> <a href="archive/2024/" class="md-nav__link"> <span class="md-ellipsis"> 2024 </span> </a> </li> <li class="md-nav__item"> <a href="archive/2023/" class="md-nav__link"> <span class="md-ellipsis"> 2023 </span> </a> </li> </ul> </nav> </li> </ul> </nav> </div> </div> </div> <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" > <div class="md-sidebar__scrollwrap"> <div class="md-sidebar__inner"> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class="md-nav__title" for="__toc"> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> <li class="md-nav__item"> <a href="#introducing-our-new-terms-of-service" class="md-nav__link"> <span class="md-ellipsis"> Introducing our new Terms of Service </span> </a> </li> <li class="md-nav__item"> <a href="#pypi-now-supports-project-archival" class="md-nav__link"> <span class="md-ellipsis"> PyPI Now Supports Project Archival </span> </a> </li> <li class="md-nav__item"> <a href="#project-quarantine" class="md-nav__link"> <span class="md-ellipsis"> Project Quarantine </span> </a> </li> <li class="md-nav__item"> <a href="#supply-chain-attack-analysis-ultralytics" class="md-nav__link"> <span class="md-ellipsis"> Supply-chain attack analysis: Ultralytics </span> </a> </li> <li class="md-nav__item"> <a href="#malware-package-analysis-aiocpa" class="md-nav__link"> <span class="md-ellipsis"> Malware Package Analysis: aiocpa </span> </a> </li> <li class="md-nav__item"> <a href="#pypi-now-supports-digital-attestations" class="md-nav__link"> <span class="md-ellipsis"> PyPI now supports digital attestations </span> </a> </li> <li class="md-nav__item"> <a href="#safety-security-engineer-first-year-in-review" class="md-nav__link"> <span class="md-ellipsis"> Safety &amp; Security Engineer: First Year in Review </span> </a> </li> <li class="md-nav__item"> <a href="#incident-report-leaked-github-personal-access-token" class="md-nav__link"> <span class="md-ellipsis"> Incident Report: Leaked GitHub Personal Access Token </span> </a> </li> <li class="md-nav__item"> <a href="#prohibiting-outlook-email-domains" class="md-nav__link"> <span class="md-ellipsis"> Prohibiting Outlook email domains </span> </a> </li> <li class="md-nav__item"> <a href="#expanding-trusted-publisher-support" class="md-nav__link"> <span class="md-ellipsis"> Expanding Trusted Publisher Support </span> </a> </li> </ul> </nav> </div> </div> </div> <div class="md-content" data-md-component="content"> <div class="md-content__inner"> <header class="md-typeset"> <h1 id="the-pypi-blog">The PyPI Blog</h1> </header> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/ewdurbin.png" alt="Ee Durbin"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2025-02-25 00:00:00+00:00">February 25, 2025</time></li> <li class="md-meta__item"> 1 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="introducing-our-new-terms-of-service"><a class="toclink" href="posts/2025-02-25-terms-of-service/">Introducing our new Terms of Service</a></h2> <p>We're introducing a new <a href="https://policies.python.org/pypi.org/Terms-of-Service/">Terms of Service</a> to formalize our relationship to users and enable us to move forward with providing new features and services, specifically <a href="https://docs.pypi.org/organization-accounts/">Organization Accounts</a>.</p> <nav class="md-post__action"> <a href="posts/2025-02-25-terms-of-service/"> Continue reading </a> </nav> </div> </article> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/facutuesca.png" alt="Facundo Tuesca"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2025-01-30 00:00:00+00:00">January 30, 2025</time></li> <li class="md-meta__item"> 2 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="pypi-now-supports-project-archival"><a class="toclink" href="posts/2025-01-30-archival/">PyPI Now Supports Project Archival</a></h2> <p>Support for marking projects as archived has landed on PyPI. Maintainers can now archive a project to let users know that the project is not expected to receive any more updates.</p> <p>This allows users to make better decisions about which packages they depend on, especially regarding supply-chain security, since archived projects clearly signal that no future security fixes or maintenance should be expected.</p> <nav class="md-post__action"> <a href="posts/2025-01-30-archival/"> Continue reading </a> </nav> </div> </article> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/miketheman.png" alt="Mike Fiedler"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2024-12-30 00:00:00+00:00">December 30, 2024</time></li> <li class="md-meta__item"> 7 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="project-quarantine"><a class="toclink" href="posts/2024-12-30-quarantine/">Project Quarantine</a></h2> <p>Earlier this year, I wrote briefly about new functionality added to PyPI, the <a href="posts/2024-08-16-safety-and-security-engineer-year-in-review/#project-lifecycle-status-quarantine">ability to quarantine projects</a>. This feature allows PyPI administrators to mark a project as potentially harmful, and prevent it from being easily installed by users to prevent further harm.</p> <p>In this post I'll discuss the implementation, and further improvements to come.</p> <nav class="md-post__action"> <a href="posts/2024-12-30-quarantine/"> Continue reading </a> </nav> </div> </article> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/sethmlarson.png" alt="Seth Larson"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2024-12-11 00:00:00+00:00">December 11, 2024</time></li> <li class="md-meta__item"> 5 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="supply-chain-attack-analysis-ultralytics"><a class="toclink" href="posts/2024-12-11-ultralytics-attack-analysis/">Supply-chain attack analysis: Ultralytics</a></h2> <p>Last week, the Python project “<a href="https://pypi.org/project/ultralytics/">ultralytics</a>” suffered a supply-chain attack through a compromise of the projects’ GitHub Actions workflows and subsequently its PyPI API token. No security flaw in PyPI was used to execute this attack. Versions 8.3.41, 8.3.42, 8.3.45, and 8.3.46 were affected and have been removed from PyPI.</p> <nav class="md-post__action"> <a href="posts/2024-12-11-ultralytics-attack-analysis/"> Continue reading </a> </nav> </div> </article> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/miketheman.png" alt="Mike Fiedler"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2024-11-25 00:00:00+00:00">November 25, 2024</time></li> <li class="md-meta__item"> 6 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="malware-package-analysis-aiocpa"><a class="toclink" href="posts/2024-11-25-aiocpa-attack-analysis/">Malware Package Analysis: aiocpa</a></h2> <p>On 2024-11-21, PyPI was notified about a malware attack with few details. Upon further investigation, we found that the maintainer was injecting obfuscated code that will exfiltrate credentials to a specific Telegram bot. The credentials include tokens, API servers, and other Crypto Pay-related data, and it is unknown to PyPI Security whether these have been used in any manner.</p> <p>The project has been removed from PyPI.</p> <p>If you have installed any versions of <code>aiocpa</code>, audit your usage of the library and consider alternatives. This may also appear as <code>cryptopay</code> on disk, as that's the internal name of this particular module -- which is not the same as the PyPI package <a href="https://pypi.org/project/cryptopay/">cryptopay</a> -- a completely different package.</p> <nav class="md-post__action"> <a href="posts/2024-11-25-aiocpa-attack-analysis/"> Continue reading </a> </nav> </div> </article> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/di.png" alt="Dustin Ingram"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2024-11-14 00:00:00+00:00">November 14, 2024</time></li> <li class="md-meta__item"> 3 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="pypi-now-supports-digital-attestations"><a class="toclink" href="posts/2024-11-14-pypi-now-supports-digital-attestations/">PyPI now supports digital attestations</a></h2> <p>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.</p> <p>Many projects have already begun publishing attestations, with more than 20,000 attestations already published.</p> <p>This finalizes PyPI's support for <a href="https://peps.python.org/pep-0740/">PEP 740</a>, and follows directly from previous work to add support for <a href="https://docs.pypi.org/trusted-publishers/">Trusted Publishing</a>, as well as the <a href="https://blog.pypi.org/posts/2023-05-23-removing-pgp/">deprecation and removal of PGP signatures</a>.</p> <nav class="md-post__action"> <a href="posts/2024-11-14-pypi-now-supports-digital-attestations/"> Continue reading </a> </nav> </div> </article> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/miketheman.png" alt="Mike Fiedler"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2024-08-16 00:00:00+00:00">August 16, 2024</time></li> <li class="md-meta__item"> 7 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="safety-security-engineer-first-year-in-review"><a class="toclink" href="posts/2024-08-16-safety-and-security-engineer-year-in-review/">Safety &amp; Security Engineer: First Year in Review</a></h2> <p>Hello reader! It's me, Mike, and it's been just over a year since I posted <a href="posts/2023-08-04-pypi-hires-safety-engineer/">about joining the PSF</a> as the Safety &amp; Security Engineer for the Python Package Index (PyPI).</p> <p>I wanted to take a moment to reflect on the past year, and share some of the things I've been working on.</p> <nav class="md-post__action"> <a href="posts/2024-08-16-safety-and-security-engineer-year-in-review/"> Continue reading </a> </nav> </div> </article> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/ewdurbin.png" alt="Ee Durbin"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2024-07-08 00:00:00+00:00">July 8, 2024</time></li> <li class="md-meta__item"> 5 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="incident-report-leaked-github-personal-access-token"><a class="toclink" href="posts/2024-07-08-incident-report-leaked-admin-personal-access-token/">Incident Report: Leaked GitHub Personal Access Token</a></h2> <p>On June 28, 2024 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#101;&#99;&#117;&#114;&#105;&#116;&#121;&#64;&#112;&#121;&#112;&#105;&#46;&#111;&#114;&#103;">&#115;&#101;&#99;&#117;&#114;&#105;&#116;&#121;&#64;&#112;&#121;&#112;&#105;&#46;&#111;&#114;&#103;</a> and I (Ee Durbin) were notified of a leaked GitHub Personal Access Token for my GitHub user account, <code>ewdurbin</code>. This token was immediately revoked, and a review of my GitHub account and activity was performed. No indicators of malicious activity were found.</p> <nav class="md-post__action"> <a href="posts/2024-07-08-incident-report-leaked-admin-personal-access-token/"> Continue reading </a> </nav> </div> </article> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/ewdurbin.png" alt="Ee Durbin"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2024-06-16 00:00:00+00:00">June 16, 2024</time></li> <li class="md-meta__item"> 2 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="prohibiting-outlook-email-domains"><a class="toclink" href="posts/2024-06-16-prohibiting-msn-emails/">Prohibiting Outlook email domains</a></h2> <p>In response to ongoing mass bot account registrations, Outlook domains <code>outlook.com</code> and <code>hotmail.com</code> have been prohibited from new associations with PyPI accounts. This includes new registrations as well as adding as additional addresses.</p> <nav class="md-post__action"> <a href="posts/2024-06-16-prohibiting-msn-emails/"> Continue reading </a> </nav> </div> </article> <article class="md-post md-post--excerpt"> <header class="md-post__header"> <nav class="md-post__authors md-typeset"> <span class="md-author"> <img src="https://github.com/di.png" alt="Dustin Ingram"> </span> </nav> <div class="md-post__meta md-meta"> <ul class="md-meta__list"> <li class="md-meta__item"> <time datetime="2024-04-17 00:00:00+00:00">April 17, 2024</time></li> <li class="md-meta__item"> 2 min read </li> </ul> </div> </header> <div class="md-post__content md-typeset"> <h2 id="expanding-trusted-publisher-support"><a class="toclink" href="posts/2024-04-17-expanding-trusted-publisher-support/">Expanding Trusted Publisher Support</a></h2> <p>Starting today, PyPI package maintainers can publish via Trusted Publishing from three additional providers:</p> <ul> <li>GitLab CI/CD</li> <li>Google Cloud</li> <li>ActiveState</li> </ul> <p>These providers join existing support for publishing from GitHub Actions without long-lived passwords or API tokens, which <a href="posts/2023-04-20-introducing-trusted-publishers/">we announced last year</a>, and bring support for Trusted Publishing to even more hosted providers.</p> <nav class="md-post__action"> <a href="posts/2024-04-17-expanding-trusted-publisher-support/"> Continue reading </a> </nav> </div> </article> <nav class="md-pagination"> <span class="md-pagination__current">1</span> <a class="md-pagination__link" href="pages/2/">2</a> <a class="md-pagination__link" href="pages/3/">3</a> <a class="md-pagination__link" href="pages/4/">4</a> </nav> </div> </div> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type="button" class="md-top md-icon" data-md-component="top" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class="md-footer"> <nav class="md-footer__inner md-grid" aria-label="Footer" > <a href="tags/" class="md-footer__link md-footer__link--next" aria-label="Next: Tags"> <div class="md-footer__title"> <span class="md-footer__direction"> Next </span> <div class="md-ellipsis"> Tags </div> </div> <div class="md-footer__button md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg> </div> </a> </nav> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class="md-copyright"> Made with <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener"> Material for MkDocs </a> </div> <div class="md-social"> <a href="https://github.com/pypi" target="_blank" rel="noopener" title="github.com" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </a> <a href="https://fosstodon.org/@pypi" target="_blank" rel="noopener me" title="fosstodon.org" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M433 179.11c0-97.2-63.71-125.7-63.71-125.7-62.52-28.7-228.56-28.4-290.48 0 0 0-63.72 28.5-63.72 125.7 0 115.7-6.6 259.4 105.63 289.1 40.51 10.7 75.32 13 103.33 11.4 50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 10.1c-40.41-1.4-83-4.4-89.63-54a102.5 102.5 0 0 1-.9-13.9c85.63 20.9 158.65 9.1 178.75 6.7 56.12-6.7 105-41.3 111.23-72.9 9.8-49.8 9-121.5 9-121.5m-75.12 125.2h-46.63v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 18.41-175 25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5 11.6-19.5c24.11-37.1 78.12-34.8 103.83-6.1 23.71 27.3 18.4 53 18.4 175z"/></svg> </a> <a href="https://bsky.app/profile/pypi.org" target="_blank" rel="noopener" title="bsky.app" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M111.8 62.2C170.2 105.9 233 194.7 256 242.4c23-47.6 85.8-136.4 144.2-180.2 42.1-31.6 110.3-56 110.3 21.8 0 15.5-8.9 130.5-14.1 149.2-18.2 64.8-84.4 81.4-143.3 71.3C456 322 482.2 380 425.6 438c-107.4 110.2-154.3-27.6-166.3-62.9-1.7-4.9-2.6-7.8-3.3-7.8s-1.6 3-3.3 7.8c-12 35.3-59 173.1-166.3 62.9-56.5-58-30.4-116 72.5-133.5C100 314.6 33.8 298 15.7 233.1 10.4 214.4 1.5 99.4 1.5 83.9c0-77.8 68.2-53.4 110.3-21.8z"/></svg> </a> <a href="https://twitter.com/pypi" target="_blank" rel="noopener" title="twitter.com" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253"/></svg> </a> <a href="https://blog.pypi.org/feed_rss_created.xml" target="_blank" rel="noopener" title="blog.pypi.org" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.18 15.64a2.18 2.18 0 0 1 2.18 2.18C8.36 19 7.38 20 6.18 20 5 20 4 19 4 17.82a2.18 2.18 0 0 1 2.18-2.18M4 4.44A15.56 15.56 0 0 1 19.56 20h-2.83A12.73 12.73 0 0 0 4 7.27zm0 5.66a9.9 9.9 0 0 1 9.9 9.9h-2.83A7.07 7.07 0 0 0 4 12.93z"/></svg> </a> </div> </div> </div> </footer> </div> <div class="md-dialog" data-md-component="dialog"> <div class="md-dialog__inner md-typeset"></div> </div> <script id="__config" type="application/json">{"base": ".", "features": ["navigation.expand", "navigation.top", "navigation.footer"], "search": "assets/javascripts/workers/search.f8cc74c7.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script> <script src="assets/javascripts/bundle.c8b220af.min.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10