{"id":"MAL-2026-17421","kind":"package","aliases":["MAL-2026-17421"],"related":[],"title":"Malicious code in spo365-graph (PyPI)","description":"---\n_-= Per source details. Do not edit below this line.=-_\n\n## Source: amazon-inspector (091649f7b927b27a5bd7a35b53784433050bf58e0dc11acc95316b650a13f60b)\nSPO365-GRAPH presents itself as a SharePoint Online Graph client, but the shipped library module SPO365_GRAPH/SPO365_GRAPH.py consists entirely of stub methods returning placeholder values; all real logic lives in setup.py and executes at install time. On `pip install`, setup.py decodes a zlib+base64 blob (_SERVICE_CONFIG) into a configuration dict holding an AWS STS endpoint, a hardcoded RoleArn, an RSA public key, upload/webhook URLs, a proxy host, and an embedded Lambda source. It then reads ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN from the environment, requests a GitHub Actions OIDC JWT with audience sts.amazonaws.com, and calls STS AssumeRoleWithWebIdentity against the attacker's hardcoded RoleArn to obtain temporary credentials under the attacker's trust policy. Using those credentials it submits a CloudFormation CreateStack request whose TemplateBody embeds an AWS::Lambda::Function with Code.ZipFile sourced from the obfuscated config (_cfg['vs']) and a hardcoded role/function name, polls DescribeStacks for Outputs, then base64-decodes the collected outputs, wraps them with hybrid RSA-OAEP + AES-256-CBC using the embedded public key, and uploads the ciphertext via PUT to _cfg['ru'] with a POST fallback to _cfg['fu'], optionally through a hardcoded HTTP proxy at _cfg['px']. Author metadata is a disposable proton.me address. The naming, stub library, and obfuscation of every operational parameter are a cover story for a CI/CD-targeted OIDC-to-AWS credential abuse and remote-code-execution dropper.\n\n## Source: kam193 (ea8dd7600717964f4ca8f8b1134f867f4bf69f1538243d5c7da752eefed99fe1)\nDuring installation, the package deploys a rogue AWS Lambda function to collect credentials from Secret Manager as well as collect other data. Data are then exfiltrated. The malicious code was introduced in version 1.1.2.\n\n\n---\n\nCategory: MALICIOUS - The campaign has clearly malicious intent, like infostealers.\n\n\nCampaign: 2026-10-spo365-graph\n\n\nReasons (based on the campaign):\n\n\n - The package overrides the install command in setup.py to execute malicious code during installation.\n\n\n - exfiltration-cloud-tokens\n\n\n - targetted-attack\n\n\n - exfiltration-credentials","summary":null,"severity":"critical","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"spo365-graph","fixed":[],"affected":"= 1.0.0; = 1.1.0; = 1.1.1; = 1.1.2","ecosystem":"pypi"}],"ecosystems":["pypi"],"tags":["malicious","package"],"not_affected_if":[],"how_to_check":null,"fix":null,"status":"open","published_at":"2026-10-01T18:58:14+00:00","first_seen_at":"2026-10-26T20:51:59+00:00","triaged_at":"2026-10-26T21:08:21+00:00","updated_at":"2026-10-26T21:08:21+00:00","category":"package","confidence":null,"triage":null,"analyst_status":null,"analyst_note":null,"search":"'-10':319C '-17421':10A,13A '-2026':9A,12A '-256':202C '091649f7b927b27a5bd7a35b53784433050bf58e0dc11acc95316b650a13f60b':32C '1.1.2':306C '2026':318C 'abus':263C 'action':110C,116C,127C 'address':240C 'ae':201C 'amazon':30C 'amazon-inspector':29C 'assumerolewithwebident':136C 'attack':139C,149C,348C 'audienc':131C 'author':234C 'aw':87C,166C,261C,280C 'base':324C 'base64':77C,189C 'base64-decodes':188C 'blob':78C 'call':134C 'campaign':310C,317C,327C 'categori':307C 'cbc':203C 'cfg':176C,216C,223C,232C 'ci/cd-targeted':257C 'ciphertext':212C 'clear':312C 'client':43C 'cloud':344C 'cloudform':159C 'code':2A,267C,301C,339C 'code.zipfile':170C 'collect':192C,284C,292C 'command':333C 'config':80C,175C 'configur':83C 'consist':51C 'cover':253C 'createstack':160C 'credenti':146C,155C,262C,285C,351C 'data':294C,295C 'decod':74C,190C 'deploy':277C 'describestack':184C 'detail':21C 'dict':84C 'dispos':238C 'dropper':269C 'ea8dd7600717964f4ca8f8b1134f867f4bf69f1538243d5c7da752eefed99fe1':272C 'edit':24C 'emb':164C 'embed':104C,206C 'endpoint':89C 'entir':52C 'environ':123C 'everi':248C 'execut':66C,268C,337C 'exfiltr':298C,343C,350C 'exfiltration-cloud-token':342C 'exfiltration-credenti':349C 'fallback':221C 'fu':224C 'function':168C,282C 'github':126C 'graph':6A,16A,35C,42C,322C 'graph/spo365_graph.py':50C 'hardcod':91C,141C,180C,228C 'hold':85C 'host':101C 'http':229C 'hybrid':197C 'id':111C,117C 'infosteal':316C 'inspector':31C 'instal':68C,72C,274C,332C,341C 'intent':314C 'introduc':303C 'jwt':129C 'kam193':271C 'key':96C,208C 'lambda':105C,167C,281C 'librari':47C,244C 'like':315C 'line':27C 'live':62C 'logic':61C 'mal':8A,11A 'malici':1A,17B,300C,308C,313C,338C 'manag':288C 'metadata':235C 'method':55C 'modul':48C 'name':182C,242C 'oaep':200C 'obfusc':174C,246C 'obtain':144C 'oidc':128C,259C 'oidc-to-aw':258C 'onlin':41C 'oper':249C 'option':225C 'output':186C,193C 'overrid':330C 'packag':18B,276C,329C 'paramet':250C 'per':19C 'pip':71C 'placehold':57C 'polici':152C 'poll':183C 'post':220C 'present':36C 'proton.me':239C 'proxi':100C,230C 'public':95C,207C 'put':214C 'px':233C 'pypi':7A 'read':109C 'real':60C 'reason':323C 'remot':266C 'remote-code-execut':265C 'request':113C,119C,124C,161C 'return':56C 'rogu':279C 'role/function':181C 'rolearn':92C,142C 'rsa':94C,199C 'rsa-oaep':198C 'ru':217C 'secret':287C 'servic':79C 'setup.py':64C,73C,335C 'sharepoint':40C 'ship':46C 'sourc':20C,28C,106C,171C,270C 'spo365':5A,15A,34C,49C,321C 'spo365-graph':4A,14A,33C,320C 'stori':254C 'sts':88C,135C 'sts.amazonaws.com':132C 'stub':54C,243C 'submit':157C 'target':347C 'targetted-attack':346C 'templatebodi':163C 'temporari':145C 'time':69C 'token':112C,118C,120C,345C 'trust':151C 'upload':210C 'upload/webhook':97C 'url':98C,114C 'use':153C,204C 'valu':58C 'version':305C 'via':213C 'vs':177C 'well':290C 'whose':162C 'wrap':194C 'zlib':76C","nicknames":[],"mitigations":[],"who_affected":null,"tier":null,"verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-01T18:58:14+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"osv-malicious","external_id":"MAL-2026-17421","url":"https://osv.dev/vulnerability/MAL-2026-17421","severity":"critical","published_at":"2026-10-01T18:58:14+00:00","modified_at":"2026-10-08T20:30:04+00:00","first_seen_at":"2026-10-26T20:51:59+00:00","fetched_at":"2026-10-26T20:51:59+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"}