TL; DR
Tra il 6° maggio e il 7 maggio 2026, un singolo editore npm, pelavelle, ha distribuito otto pacchetti senza dipendenze utilizzando nomi che seguivano lo stesso schema dall'aspetto interno: 24712-pl*.
I pacchetti inclusi 24712-pl3469, 24712-pl4712, 24712-pl5006, 24712-plv2e 24712-plv3. Il prefisso numerato suggerisce fortemente un attacco di confusione delle dipendenze npm rispetto a uno spazio dei nomi di pacchetto interno o a uno schema di ID di pacchetto.
Tutti gli otto pacchetti fratelli erano già stati rimossi da npm dall'editore tra 2026-05-06T21:52Z and 2026-05-07T00:31ZI metadati diretti del registro hanno confermato che i file tarball ora restituiscono un errore HTTP 404.
Tuttavia, il cluster rimane importante.
Il campione canonico, 24712-pl5006:0.0.1, contiene a postinstall.js script che viene eseguito durante npm installInvece di rubare variabili d'ambiente generiche, cerca specificamente AWS_LAMBDA_RUNTIME_API, la variabile d'ambiente utilizzata dai runtime di AWS Lambda.
Se lo script trova AWS_LAMBDA_RUNTIME_API, chiama l'endpoint dell'API Lambda Runtime:
Tale chiamata tenta di consumare il successivo evento di invocazione Lambda in sospeso prima che il gestore Lambda legittimo possa elaborarlo.
L'evento catturato, inclusi intestazioni, ID richiesta, contesto account e fino a 8 KB di corpo della richiesta, viene quindi inviato a un endpoint phone-home controllato dall'attaccante tramite lo script phoneHome() funzione.
Il sistema di allerta precoce antimalware (MEW) di Xygeni ha classificato il campione canonico come probabilmente dannoso con un punteggio di 91.3/100.
Stiamo monitorando questo come un attacco di confusione delle dipendenze npm con comportamento di dirottamento in fase di esecuzione di AWS Lambda.
Il Cluster: otto pacchetti, un unico editore.
L'account dell'editore pelavelle è stato utilizzato il seguente indirizzo email:
pelavelle@clovercode.com
L'account aveva un'email non verificata, no SCM verifica e un basso punteggio di reputazione pari a 5.
L'editore ha rilasciato otto pacchetti correlati in un breve intervallo di tempo tra le 20:45 e le 22:36 del 6 maggio 2026. I nomi dei pacchetti seguono tutti la stessa struttura:
24712-pl*
Questo schema è il segnale chiave. Non sembra un'utilità pubblica per sviluppatori. Piuttosto, sembra uno schema di denominazione interno dei pacchetti.
| # | CONFEZIONE | Versione Maligna | Creato, UTC | Inedito, UTC | Carico utile confermato | Installa Hook |
|---|---|---|---|---|---|---|
| 1 | esploratore del cosmo | 1.1.3 | 2026-05-01T18:26Z | 2026-05-01T19:01Z | Dedotto, stesso editore/cluster | preinstallazione, presunta |
| 2 | signalsdk-web | 1.0.0, 10.0.0 | 2026-05-04T13:57Z | 2026-05-04T18:51Z | inferito | preinstallazione, presunta |
| 3 | ms.analytics-web | 99.0.0, 99.9.13 | 2026-05-04T18:47Z | 2026-05-05T10:07Z | inferito | preinstallazione, presunta |
| 4 | icone.generate | 99.9.13 | 2026-05-05T10:02Z | 2026-05-05T12:57Z | inferito | preinstallazione, presunta |
| 5 | tracciamento della latenza | 99.9.0 | 2026-05-05T11:57Z | 2026-05-05T12:57Z | inferito | preinstallazione, presunta |
| 6 | tracciamento della latenza interna | Versioni rimosse dal record di registro | 2026-05-06T06:02Z | 2026-05-06T08:35Z | inferito | preinstallazione, presunta |
| 7 | carboniteapp | 99.9.0 | 2026-05-06T05:49Z | 2026-05-06T08:35Z | Sì, flusso di codice completo dello scanner | preinstallazione: node index.js |
| 8 | carbonite-interno | 99.9.0 | 2026-05-06T06:14Z | 2026-05-06T08:36Z | Sì, flusso di codice completo dello scanner | preinstallazione: node index.js |
Numero totale di versioni nell'intero cluster: 19 tuple di pacchetti di versione.
Il campione canonico, 24712-pl5006:0.0.1, è stato pubblicato il 2026-05-06T22:36:34Z e scansionato da MEW di Xygeni pipeline prima dell'evento di rimozione dalla pubblicazione.
Conteneva quattro file, tra cui package/postinstall.js, con 3,335 byte di codice sorgente totale.
Il canonico commit hash era:
83e0efbfd110abb2398a06196fb698565a3f6cc6
Perché lo schema del nome è importante
I nomi dei pacchetti sono l'indicatore più forte dell'intento.
Iniziano tutti con lo stesso prefisso:
24712-pl
Poi aggiungono suffissi numerici o che indicano la versione:
24712-pl3469
24712-pl4712
24712-pl4713
24712-pl5004
24712-pl5005
24712-pl5006
24712-plv2
24712-plv3
Questo non assomiglia alla normale convenzione di denominazione pubblica di npm. Sembra piuttosto un prefisso di namespace interno o uno schema di identificazione del pacchetto interno.
Ciò rende il cluster coerente con un attacco di confusione delle dipendenze npm.
In un attacco di confusione delle dipendenze, l'attaccante pubblica un pacchetto pubblico con un nome che corrisponde, o sembra corrispondere, a una dipendenza interna. Se il gestore di pacchetti o l'ambiente di compilazione del sistema target risolve il pacchetto pubblico anziché quello privato, il codice controllato dall'attaccante viene eseguito all'interno dell'ambiente target.
OWASP descrive la confusione di dipendenza come un vettore di attacco che inganna i gestori di pacchetti e i proxy, inducendoli a scaricare un pacchetto pubblico dannoso anziché il pacchetto interno previsto con lo stesso nome.
Per un contesto più approfondito su come funziona questa classe di attacchi, consultare la guida di Xygeni su mancanza di blocco della versione e confusione sulle dipendenze e il nostro post su identificazione e gestione degli attacchi di dipendenza software.
Cosa succede al momento dell'installazione?
Il pacchetto canonico dichiara un postinstall gancio:
{
"scripts": {
"postinstall": "node postinstall.js || true"
}
}
Migliori postinstall Il ciclo di vita fa parte del sistema di script dei pacchetti di npm. La documentazione di npm spiega che i pacchetti possono definire script del ciclo di vita in package.json, inclusi gli eventi integrati del ciclo di vita dell'installazione.
Migliori || true è importante.
Il sistema ignora gli errori, quindi l'installazione va comunque a buon fine anche se il dirottamento fallisce. Questo aiuta il pacchetto a evitare di interrompere la compilazione e riduce la probabilità che gli sviluppatori o i sistemi di integrazione continua (CI) si accorgano del comportamento dannoso attraverso un'installazione fallita.
Il carico utile viene eseguito durante npm installNon è richiesto alcun importazione da parte dello sviluppatore. Nessun percorso dell'applicazione deve richiamare il pacchetto.
L'installazione in sé è sufficiente.
Comportamento del payload: dirottamento del runtime di Lambda
Migliori postinstall.js Lo script esegue una sequenza mirata.
Innanzitutto, legge l'ambiente del processo padre da Linux /proc:
const raw = fs.readFileSync(`/proc/${pid}/environ`, 'utf8');
Successivamente estrae l'endpoint di runtime di AWS Lambda:
const match = raw.match(/AWS_LAMBDA_RUNTIME_API=([^\0]+)/);
Se l'API di runtime viene trovata, lo script la memorizza:
runtimeApi = match[1];
Successivamente, invia un primo segnale attraverso phoneHome():
await phoneHome({ step: 'waiting', runtimeApi, ts: ... });
Quel primo beacon rivela l'endpoint dell'API di runtime di Lambda.
Successivamente, lo script analizza l'host e la porta dell'API di runtime:
const [host, portStr] = runtimeApi.split(':');
Infine, richiama il percorso dell'API AWS Lambda Runtime utilizzato per recuperare la successiva invocazione:
http.request({
host,
port,
path: '/2018-06-01/runtime/invocation/next',
method: 'GET',
timeout: 90000
}, ...);
Questo è il fulcro dell'attacco.
Lo script tenta di intercettare il successivo evento di invocazione Lambda prima che il gestore Lambda legittimo possa elaborarlo. Anche la guida di runtime personalizzata di AWS descrive il passaggio "recupera un evento" come una chiamata all'API di invocazione successiva.
Cosa viene esfiltrato
Se lo script intercetta una chiamata, invia il risultato all'endpoint di chiamata controllato dall'attaccante.
I campi esfiltrati comprendono:
| Settore | Significato |
|---|---|
step | Fase di esecuzione, come ad esempio waiting, next_error, o captured |
runtimeApi | Endpoint API di runtime Lambda |
accountSid | Contesto dell'account AWS acquisito |
requestId | ID della richiesta di invocazione Lambda |
isOwnAccount | Confronto booleano con il valore dell'account configurato nello script. |
statusCode | Stato della risposta API in fase di esecuzione |
headers | Intestazioni di risposta dell'invocazione |
body | Corpo dell'invocazione catturato, suddiviso in 8,000 caratteri |
La chiamata chiave per l'esfiltrazione è la phoneHome(data) funzione che codifica i dati in formato JSON e li invia tramite una richiesta HTTP POST.
L'URL esatto della destinazione del telefono di casa non è stato conservato nelle prove troncate disponibili. Pertanto, npm dovrebbe conservare internamente il tarball non pubblicato in modo che il letterale host C2 possa essere estratto prima che la cancellazione sia finalizzata.
Perché questo è pericoloso
Questo non è un beacon npm generico.
Il carico utile è progettato attorno AWS Lambda modello di esecuzione.
Se un pacchetto vulnerabile viene installato all'interno di un ambiente di esecuzione Lambda, ad esempio durante la creazione di un'immagine di distribuzione, l'installazione di un layer Lambda o un processo wrapper di inizializzazione, l'ambiente potrebbe essere esposto AWS_LAMBDA_RUNTIME_API.
Una volta che lo script ha quel valore, può chiamare:
/2018-06-01/runtime/invocation/next
Tale endpoint restituisce il successivo evento di invocazione in sospeso.
Di conseguenza, l'attaccante potrebbe essere in grado di acquisire:
- Corpi di richiesta
- Headers
- ID richiesta
- contesto dell'account AWS
- Dati della richiesta firmata
- PII del cliente
- Dati degli eventi S3
- Payload specifici dell'applicazione
- contesto del servizio interno
Il gestore legittimo potrebbe non visualizzare mai l'evento consumato.
Questo trasforma uno script di installazione npm in un primitivo di intercettazione di eventi Lambda.
Anche se il pacchetto non viene mai implementato in un ambiente Lambda reale, il comportamento può comunque rivelare informazioni utili ai sistemi di sviluppo o di integrazione continua. /proc/<pid>/environ potrebbe esporre variabili d'ambiente presenti nei processi padre, che possono includere chiavi AWS, URL di database, token CI o credenziali di distribuzione.
Ecco perché la scansione delle dipendenze non può fermarsi alle CVE note. I team hanno bisogno anche di rilevare i pacchetti dannosi, analizzare gli script di installazione e applicare le policy del registro. Per ulteriori informazioni, leggere Perché la scansione delle dipendenze è importante per i team DevOps and Protezione da malware: perché l'antivirus non riesce a fermare gli attacchi alla supply chain.
Classificazione Xygeni MEW
Xygeni MEW ha scansionato il campione canonico 24712-pl5006:0.0.1 prima dell'evento di rimozione dalla pubblicazione.
Lo scanner ha restituito:
91.3 / 100
probablyMalicious
threshold: 80
Le prove includevano tre elementi critici e un elemento di alto livello che confermavano il flusso di dati di dirottamento in fase di esecuzione di Lambda.
| Gravità | Prova | Significato |
|---|---|---|
| critico | /proc/<pid>/environ read | Legge l'ambiente del processo padre |
| critico | AWS_LAMBDA_RUNTIME_API estrazione | Destinazioni: endpoint di runtime Lambda |
| critico | /runtime/invocation/next richiesta | Tentativi di consumare un evento di invocazione Lambda reale |
| Alto | postinstall copione | Esegue durante l'installazione di npm |
Il comportamento è estremamente specifico e di grande impatto. Il pacchetto non necessita di ampie funzionalità malware perché l'endpoint di runtime di Lambda è già un bersaglio potente.
Xygeni MEW è progettato per questo tipo di caso: rilevare comportamenti sospetti e dannosi dei pacchetti prima che si trasformino in un incidente a valle. Per una visione più ampia degli attuali modelli di minaccia di npm e PyPI, vedere Uno sguardo più da vicino agli attacchi alla supply chain del software nel 2025.
Perché il modello di auto-cancellazione è importante
Tutti e otto i pacchetti sono stati ritirati dalla casa editrice nel giro di un breve lasso di tempo.
In questo contesto, tale comportamento risulta sospetto.
Il cluster è apparso, è stato eseguito se selezionato tramite un percorso di risoluzione delle dipendenze vulnerabile, e poi è scomparso. Questo è coerente con un'operazione di pulizia da parte dell'attaccante dopo una prova di concetto riuscita o interrotta, oppure dopo che l'organizzazione bersaglio ha rilevato il problema.
La rimozione della pubblicazione crea una lacuna di visibilità per i difensori.
I dati pubblici di npm potrebbero non includere più i file tar.gz. Alcune versioni dei pacchetti non possono essere scaricate nuovamente. Tuttavia, gli ambienti interessati potrebbero ancora disporre di copie memorizzate nella cache, riferimenti ai file di blocco, log di integrazione continua o artefatti del gestore di pacchetti.
Ecco perché la conservazione a livello di registro è importante.
npm dovrebbe conservare internamente i file tar non pubblicati per un tempo sufficiente a estrarre l'URL esatto del server di posta, confermare l'identità del payload correlato e supportare la gestione degli incidenti.
Indicatori di compromissione e rilevamento
Editore e account
| Settore | Valore |
|---|---|
| nome utente npm | pelavelle |
| e-mail dell'editore npm | pelavelle@clovercode.com |
| email verificata | Nodo |
| SCM verificato | Nodo |
| punteggio di reputazione dell'editore | 5 |
| Schema di denominazione dei pacchetti | ^24712-pl[0-9a-z]+$ |
| prefisso dello spazio dei nomi interno | 24712-pl |
Nomi dei pacchetti interessati
24712-pl3469
24712-pl4712
24712-pl4713
24712-pl5004
24712-pl5005
24712-pl5006
24712-plv2
24712-plv3
Esempio canonico
| Settore | Valore |
|---|---|
| CONFEZIONE | 24712-pl5006 |
| Versione | 0.0.1 |
| Pubblicato il | 2026-05-06T22:36:34Z |
| Commit hash | 83e0efbfd110abb2398a06196fb698565a3f6cc6 |
| UUID di scansione Xygeni | f80e4244-86d2-4a58-be59-7c56988a0f9f |
| Punti | 91.3 / 100 |
| Giudizio | probablyMalicious |
Installa Hook
{
"scripts": {
"postinstall": "node postinstall.js || true"
}
}
Indicatori di runtime Lambda
Campi del payload esfiltrato
step
runtimeApi
accountSid
requestId
isOwnAccount
statusCode
headers
body
Il corpo del testo è suddiviso in blocchi di 8,000 caratteri.
Note di rilevamento
Diverse regole possono catturare questo attacco di confusione delle dipendenze npm e probabili varianti.
Innanzitutto, contrassegna gli script npm install che leggono l'ambiente del processo padre da /proc:
/proc//environ
Questo comportamento è raramente legittimo per una dipendenza npm durante l'installazione.
In secondo luogo, avvisa sugli script di installazione dei pacchetti che fanno riferimento a:
AWS_LAMBDA_RUNTIME_API
Durante l'installazione, questa variabile d'ambiente non deve essere accessibile da pacchetti npm di terze parti.
In terzo luogo, blocca o rivedi gli script di installazione che richiamano:
/2018-06-01/runtime/invocation/next
Questo è l'endpoint dell'API AWS Lambda Runtime per ricevere la successiva invocazione. Uno script di installazione delle dipendenze non ha alcun motivo legittimo per utilizzarlo.
In quarto luogo, cercate i riferimenti nei file di blocco ai nomi dei pacchetti interessati:
package-lock.json
yarn.lock
pnpm-lock.yaml
npm-shrinkwrap.json
Qualsiasi corrispondenza dovrebbe attivare una revisione della confusione di dipendenza.
Quinto, avviso sull'espressione regolare del nome del pacchetto:
^24712-pl[0-9a-z]+$
soprattutto quando l'editore è pubblico, ha una reputazione scarsa, non è verificato o si trova al di fuori del registro interno previsto.
Infine, aggiungi CI/CD guardrails intorno agli script di installazione. Questo è particolarmente importante perché gli script del ciclo di vita di npm possono essere eseguiti durante l'installazione del pacchetto, prima che gli sviluppatori importino qualsiasi cosa. Per ulteriori informazioni su CI/CD modelli di rilevamento, vedere Xygeni I 10 principali indicatori di compromesso in CI/CD Pipelines and Sicurezza Guardrails per CI/CD Pipelines.
Azioni di registro suggerite
Questo cluster era già stato rimosso dall'elenco al momento della stesura del rapporto, ma la rimozione dall'elenco non elimina il rischio.
Azioni consigliate lato npm:
- Confermare se le rimozioni dalla pubblicazione siano state effettuate da un utente malintenzionato per ripulire il sistema, piuttosto che per una legittima azione del responsabile della manutenzione.
- Sospendere o bannare l'account dell'editore
pelavelle. - Aggiungi
pelavelle@clovercode.com, i nomi dei pacchetti e l'espressione regolare del nome del pacchetto per le blacklist di abusi e della catena di fornitura di npm. - Conservare i file tar non pubblicati in un archivio interno per le analisi forensi.
- Estrarre l'esatto
phoneHome()URL di destinazione dai file tarball dei pacchetti conservati. - Verificare se tutti i pacchetti fratelli condividono lo stesso payload.
- Informare le organizzazioni interessate qualora i dati di telemetria relativi al download o all'installazione del pacchetto indichino una vulnerabilità.
Lista di controllo per la risposta al compromesso
Se un pacchetto interessato compare nei file di blocco, nei log CI, nelle cache dei pacchetti, nei layer Lambda, nelle immagini di distribuzione o negli artefatti di build, consideralo come un potenziale evento di esecuzione dovuto a confusione di dipendenze.
Risposta consigliata:
- Identifica la posizione in cui è stato installato il pacchetto: workstation locale, runner CI, build del layer Lambda, immagine di distribuzione o ambiente di runtime.
- Conserva i file di blocco, la cache npm, i log di compilazione, gli artefatti di distribuzione e i livelli delle immagini dei container.
- Verificare se l'installazione è avvenuta all'interno di un ambiente in cui
AWS_LAMBDA_RUNTIME_APIera stabilito. - Esamina i log HTTP in uscita per elementi sconosciuti
phoneHome()destinazioni durante la finestra di installazione. - Analizza i log di invocazione di Lambda per individuare eventi persi, mancanti o anomali.
- Ruota le credenziali esposte all'ambiente di installazione, in particolare le chiavi AWS, i token CI, le credenziali di distribuzione e gli URL dei database.
- Esamina i layer Lambda e le immagini di distribuzione per individuare le copie memorizzate nella cache del pacchetto.
- Applica il blocco privato del registro di sistema per i prefissi dei pacchetti interni.
- Blocca la risoluzione pubblica di npm per i nomi di pacchetti che sembrano interni.
- Aggiungi guardrails per
preinstall,installepostinstallscript.
Come Xygeni aiuta a rilevarlo precocemente
Questa campagna rappresenta esattamente il tipo di caso in cui i team di sicurezza hanno bisogno di qualcosa di più della tradizionale scansione delle vulnerabilità.
Potrebbe non esserci CVEPotrebbe non esistere alcuna versione vulnerabile nota. Potrebbe non esserci alcun pacchetto persistente da esaminare dopo che l'editore lo ha ripulito.
Al contrario, i team necessitano di visibilità in tempo reale sul comportamento dei pacchetti.
Xygeni aiuta combinando:
- Rilevamento precoce di malware attraverso i registri pubblici.
- Rilevamento di dipendenze sospette per individuare confusione tra dipendenze e typosquatting.
- Analisi dello script di installazione per
preinstall,installepostinstallcomportamenti. - CI/CD guardrails per bloccare i pacchetti rischiosi prima che raggiungano gli ambienti di compilazione o distribuzione.
- visibilità della catena di fornitura del software attraverso le dipendenze, pipelinee manufatti.
- Applicazione delle policy per i nomi dei pacchetti interni e per i pacchetti pubblici non attendibili.
Ciò è importante perché l'impatto di un attacco di confusione delle dipendenze npm Non si limita ai laptop degli sviluppatori. Può raggiungere i runner CI, le immagini di build, i layer Lambda, i container di distribuzione e gli ambienti adiacenti al runtime.
Per un contesto più ampio su AppSec e sulla catena di fornitura, vedere Al di là di SCA: Proteggere la catena di fornitura del software and Software Supply Chain Security Automazione.
Cosa dovrebbero imparare i difensori
Questa campagna dimostra come la confusione sulle dipendenze possa andare oltre i semplici beacon di prova di esecuzione.
Il carico utile non si limita a confermare che npm install eseguito. Tenta di interagire con l'API AWS Lambda Runtime e di catturare un evento di invocazione reale.
Si tratta di un'escalation significativa.
Per i team che utilizzano architetture serverless, la risoluzione delle dipendenze è parte integrante del modello di minaccia in fase di esecuzione. Un pacchetto npm pubblico con un nome che sembra interno può diventare una porta d'accesso al contesto di esecuzione di Lambda, ai dati delle richieste e ai metadati dell'account cloud.
La lezione fondamentale è chiara: i prefissi dei pacchetti interni devono essere protetti, limitati e bloccati in registri attendibili. Gli script di installazione devono essere trattati come superficie di attacco eseguibile, soprattutto in CI/CD, creazione di container, livelli Lambda e distribuzione pipelines.
CISLe linee guida di A sulla catena di fornitura del software sottolineano la necessità di proteggere il software, applicare controlli di sicurezza e rispondere alle vulnerabilità in modo continuativo durante tutto il processo di sviluppo. In questo caso, ciò significa considerare la risoluzione dei pacchetti, gli script di pacchetto e gli ambienti di compilazione serverless come controlli di sicurezza di primaria importanza.
Segnalato a npm per l'applicazione delle restrizioni a livello di account, l'inserimento nella lista nera e la conservazione dei file tar non pubblicati.







