{"id":"INC-pypi-s8vm6pwr46c2","kind":"incident","aliases":[],"related":[],"title":"PyPI: Malicious takeover of ctx project on PyPI.","description":"Takeover of the ctx project was reported on multiple channels overnight and was mitigated as of 6:07 AM Eastern.\n\nWe confirmed via investigation that this compromise was of a single user account due to re-registration over an expired domain. The domain that hosted the users email address was re-registered 2022-05-14T18:40:05Z and a password reset completed successfully for the user at 2022-05-14T18:52:40Z. Original releases were then deleted and malicious copies uploaded.\n\nPyPI itself was not directly compromised.\n\nRead the full incident report at [https://python-security.readthedocs.io/pypi-vuln/index-2022-05-24-ctx-domain-takeover.html](https://python-security.readthedocs.io/pypi-vuln/index-2022-05-24-ctx-domain-takeover.html).","summary":"The ctx project on PyPI was hijacked after its maintainer's email domain expired and was re-registered by someone else, who reset the account password. The attacker deleted the original releases and uploaded malicious copies that would be installed by anyone pulling ctx from PyPI.","severity":"low","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"PyPI","fixed":[],"affected":"","ecosystem":"vendor"}],"ecosystems":["vendor"],"tags":["incident","pypi","python","registry","security","self-hosted","vendor"],"not_affected_if":["no-ctx-dependency"],"how_to_check":"- Run `pip show ctx` and `pip index versions ctx` to see which version is installed and what exists on PyPI\n- Check requirements files and lockfiles for `ctx` and review any install from May 2022 onward\n- Inspect an installed ctx package for unexpected code, for example in its `setup.py` or `__init__.py`","fix":"- Remove any malicious ctx copy and reinstall from a known-good release, if one exists in your sources; the sources do not name a safe version\n- Rotate any credentials or secrets present on machines that installed the malicious ctx package\n- Pin dependencies to hashes so a replaced release cannot install silently","status":"resolved","published_at":"2022-05-24T10:00:00+00:00","first_seen_at":"2026-10-23T19:12:22+00:00","triaged_at":"2026-10-25T05:41:52+00:00","updated_at":"2026-10-25T05:41:52+00:00","category":"vendor","confidence":0.6,"triage":{"at":"2026-10-25T05:41:52Z","model":"claude-haiku-5-5","output":{"fix":"- Remove any malicious ctx copy and reinstall from a known-good release, if one exists in your sources; the sources do not name a safe version\n- Rotate any credentials or secrets present on machines that installed the malicious ctx package\n- Pin dependencies to hashes so a replaced release cannot install silently","reach":"internet","title":"PyPI: ctx project taken over through an expired email domain","impact":"high","summary":"The ctx project on PyPI was hijacked after its maintainer's email domain expired and was re-registered by someone else, who reset the account password. The attacker deleted the original releases and uploaded malicious copies that would be installed by anyone pulling ctx from PyPI.","category":"vendor","nicknames":[],"who_cares":["python","pypi","self-hosted"],"confidence":0.6,"needs_auth":"no","worst_case":"Malicious package code runs on installing machines and can read secrets","analyst_note":"Find the exact affected version range and the safe release from the incident report at https://python-security.readthedocs.io/pypi-vuln/index-2022-05-24-ctx-domain-takeover.html","how_to_check":"- Run `pip show ctx` and `pip index versions ctx` to see which version is installed and what exists on PyPI\n- Check requirements files and lockfiles for `ctx` and review any install from May 2022 onward\n- Inspect an installed ctx package for unexpected code, for example in its `setup.py` or `__init__.py`","needs_analyst":true,"not_affected_if":["no-ctx-dependency"],"who_is_affected":"Any team that installed the ctx package from PyPI during the window when the malicious copies were live is exposed, because the installed code is what runs. PyPI itself was not compromised, so the risk comes from the package contents rather than the registry. Teams that never pulled ctx from PyPI can skip this.","user_interaction":"yes","needs_special_setup":"no","severity_if_unknown":"unknown"},"cost_usd":0.000686,"input_tokens":3485,"output_tokens":674,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-05':125C,141C '-14':126C,142C '/pypi-vuln/index-2022-05-24-ctx-domain-takeover.html](https://python-security.readthedocs.io/pypi-vuln/index-2022-05-24-ctx-domain-takeover.html).':169C '05z':129C '07':87C '2022':124C,140C '40':128C '40z':145C '52':144C '6':86C 'account':48B,102C 'address':119C 'anyon':65B 'attack':51B 'channel':79C 'complet':134C 'compromis':96C,160C 'confirm':91C 'copi':59B,153C 'ctx':5A,24B,67B,73C 'delet':52B,150C 'direct':159C 'domain':35B,111C,113C 'due':103C 'eastern':89C 'els':44B 'email':34B,118C 'expir':36B,110C 'full':163C 'hijack':29B 'host':21B,115C 'inc':10A 'inc-pypi-s8vm6pwr46c2':9A 'incid':14B,164C 'instal':63B 'investig':93C 'maintain':32B 'malici':2A,58B,152C 'mitig':83C 'multipl':78C 'origin':54B,146C 'overnight':80C 'password':49B,132C 'project':6A,25B,74C 'pull':66B 'pypi':1A,8A,11A,13A,15B,27B,69B,155C 'python':16B 'python-security.readthedocs.io':168C 'python-security.readthedocs.io/pypi-vuln/index-2022-05-24-ctx-domain-takeover.html](https://python-security.readthedocs.io/pypi-vuln/index-2022-05-24-ctx-domain-takeover.html).':167C 're':40B,106C,122C 're-regist':39B,121C 're-registr':105C 'read':161C 'regist':41B,123C 'registr':107C 'registri':17B 'releas':55B,147C 'report':76C,165C 'reset':46B,133C 's8vm6pwr46c2':12A 'secur':18B 'self':20B 'self-host':19B 'singl':100C 'someon':43B 'success':135C 't18':127C,143C 'takeov':3A,70C 'upload':57B,154C 'user':101C,117C,138C 'vendor':22B 'via':92C 'would':61B","nicknames":[],"mitigations":[],"who_affected":"Any team that installed the ctx package from PyPI during the window when the malicious copies were live is exposed, because the installed code is what runs. PyPI itself was not compromised, so the risk comes from the package contents rather than the registry. Teams that never pulled ctx from PyPI can skip this.","tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2022-05-24T10:00:00+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"statuspage","external_id":"pypi:s8vm6pwr46c2","url":"https://stspg.io/pn714s4b42d3","severity":"low","published_at":"2022-05-24T10:00:00+00:00","modified_at":"2022-05-24T17:33:16+00:00","first_seen_at":"2026-10-23T19:12:22+00:00","fetched_at":"2026-10-25T14:03:24+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}