Programmazione

Manifest V2 è morto in Chrome 150: guida pratica alla migrazione verso Manifest V3

Dario Fadda Luglio 8, 2026

Manifest V2 è ufficialmente morto: cosa cambia da Chrome 150

Con il rilascio di Chrome 150 (fine giugno 2026), Google ha chiuso anche l’ultimo varco rimasto aperto sul Manifest V2: il flag sperimentale che permetteva, a chi lo attivava manualmente, di continuare a eseguire estensioni legacy. Il percorso di deprecazione era iniziato molto prima — le prime disattivazioni erano comparse già nei canali pre-stable di Chrome 127 a metà 2024, la rimozione del criterio enterprise che consentiva alle aziende di rimandare il cambio era arrivata con Chrome 139, e da Chrome 138 il Manifest V2 risultava già disabilitato su tutti i canali per gli utenti privati. Chrome 150 chiude il cerchio: da qui in avanti, chi mantiene un’estensione in Manifest V2 non ha più alcuna via di fuga lato utente, solo il downgrade manuale a una versione precedente del browser, un’operazione sconsigliata perché rinuncia a tutte le patch di sicurezza successive.

Per chi sviluppa o mantiene estensioni Chrome — plugin aziendali, ad blocker interni, tool di produttività distribuiti via policy — il messaggio è netto: la riscrittura in Manifest V3 non è più rimandabile. Vediamo cosa cambia concretamente e come affrontare la migrazione senza sorprese.

Perché Google ha fatto questa scelta

Manifest V3 nasce da un problema reale: il modello di background page persistente di V2 teneva in memoria un intero processo per ogni estensione installata, con un impatto misurabile su RAM e batteria. Inoltre l’API webRequest, che permetteva alle estensioni di intercettare e modificare ogni richiesta di rete in tempo reale con codice arbitrario, è da anni uno dei vettori più sfruttati per iniettare codice malevolo o dirottare il traffico dell’utente. Sostituendola con un sistema dichiarativo, Chrome elimina una classe intera di vulnerabilità, al costo di una minore flessibilità per gli sviluppatori legittimi (è il motivo per cui alcuni ad blocker complessi, come le versioni più sofisticate di uBlock Origin, hanno dovuto ripensare parte della loro logica di filtro).

Le tre modifiche strutturali che servono per migrare

1. Da background page a service worker

In Manifest V2 il background script veniva dichiarato così:

{
  "manifest_version": 2,
  "background": {
    "scripts": ["background.js"],
    "persistent": true
  }
}

In Manifest V3 il campo diventa singolare e punta a un service worker, non più a un processo persistente:

{
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  }
}

La differenza non è solo sintattica. Un service worker viene terminato da Chrome dopo circa 30 secondi di inattività e riavviato al bisogno: qualsiasi variabile in memoria (contatori, cache, stato di sessione) viene persa a ogni ciclo. Il codice va quindi ristrutturato per:

  • registrare tutti i listener di eventi (chrome.runtime.onMessage, chrome.alarms.onAlarm, ecc.) in modo sincrono, nella prima esecuzione dello script — se li registri dentro una callback asincrona rischi che il service worker si riattivi senza agganciare l’evento;
  • spostare qualunque stato che deve sopravvivere ai riavvii su chrome.storage.local o chrome.storage.session, mai su variabili globali;
  • sostituire i timer lunghi basati su setTimeout/setInterval con l’API chrome.alarms, l’unica garantita a sopravvivere alla terminazione del worker.

2. Da webRequest a declarativeNetRequest

Questo è il cambiamento che rompe più estensioni esistenti. In V2 potevi intercettare ogni richiesta e decidere via codice cosa farne:

chrome.webRequest.onBeforeRequest.addListener(
  (details) => ({ cancel: details.url.includes("ads") }),
  { urls: ["<all_urls>"] },
  ["blocking"]
);

In V3 questo pattern “blocking” non è più disponibile per le estensioni pubbliche: devi descrivere le regole in modo dichiarativo e lasciare che sia Chrome, non il tuo JavaScript, ad applicarle — un dettaglio che tra l’altro migliora anche le performance, perché elimina la latenza di andata e ritorno verso lo script:

{
  "permissions": ["declarativeNetRequest"],
  "declarative_net_request": {
    "rule_resources": [{
      "id": "ruleset_1",
      "enabled": true,
      "path": "rules.json"
    }]
  }
}

Con rules.json strutturato così:

[
  {
    "id": 1,
    "priority": 1,
    "action": { "type": "block" },
    "condition": {
      "urlFilter": "||ads.example.com",
      "resourceTypes": ["script", "image", "xmlhttprequest"]
    }
  }
]

Se hai bisogno di generare regole a runtime (per esempio in base a una blocklist scaricata dinamicamente), puoi ancora farlo, ma tramite l’API dedicata invece che intercettando il traffico:

chrome.declarativeNetRequest.updateDynamicRules({
  addRules: [ /* nuove regole */ ],
  removeRuleIds: [1, 2, 3]
});

3. Content Security Policy più rigida

Manifest V3 vieta il caricamento di codice remoto e l’uso di eval() o di stringhe passate a setTimeout. Ogni script deve essere incluso nel pacchetto dell’estensione al momento della submission. Se la tua estensione scarica script da un CDN esterno per aggiornare la logica senza ripassare dallo store, quella pratica va eliminata: è esattamente il tipo di comportamento che V3 vuole rendere impossibile.

Un percorso di migrazione pragmatico

Per un’estensione di media complessità, un ordine di lavoro che funziona bene nella pratica:

  1. Aggiorna manifest_version a 3 e correggi gli errori di validazione più ovvi (campi rinominati, permessi da dichiarare esplicitamente in host_permissions invece che in permissions).
  2. Converti il background script in service worker e verifica con i DevTools dell’estensione (chrome://extensions → “Ispeziona service worker”) che i tuoi eventi vengano ricevuti anche dopo un riavvio forzato del worker.
  3. Mappa ogni regola di webRequest blocking in una regola dichiarativa equivalente; per i casi che non si lasciano esprimere in modo dichiarativo (analisi del body della richiesta, per esempio) valuta se il caso d’uso può spostarsi lato server o va accettato come limite architetturale.
  4. Testa il ciclo di vita del service worker esplicitamente, non solo la logica funzionale: è la causa più comune di bug “intermittenti” post-migrazione.

Cosa fare se dipendi da un’estensione ancora in V2

Se in azienda usate ancora plugin legacy indispensabili, l’unica strada supportata da Google è il downgrade manuale a Chrome 148 (l’ultima build con supporto V2 completo), disabilitando i servizi “Google Updater” e “Google Updater Internal” da Windows per bloccare l’aggiornamento automatico, e aggiungendo flag da riga di comando al collegamento per bypassare la logica di deprecazione. È un compromesso rischioso, perché rinuncia a tutte le patch di sicurezza rilasciate da quel momento in poi, e va considerato solo come misura temporanea mentre si pianifica la migrazione o la sostituzione dell’estensione. Alcuni browser basati su Chromium, come Firefox (che usa un motore diverso ma supporta ancora API equivalenti a webRequest) o Opera, hanno dichiarato l’intenzione di mantenere più a lungo il supporto a funzionalità simili a V2: per estensioni interne aziendali può essere un’alternativa da valutare, con le dovute cautele su compatibilità e manutenzione nel lungo periodo.

Fonte: 4sysops.com

💬 Unisciti alla discussione!


Questo è un blog del Fediverso: puoi trovare quindi questo articolo ovunque con @blog@spcnet.it e ogni commento/risposta apparirà qui sotto.

Se vuoi commentare su Manifest V2 è morto in Chrome 150: guida pratica alla migrazione verso Manifest V3, utilizza la discussione sul Forum.
Condividi la tua esperienza, confrontati con altri professionisti e approfondisci i dettagli tecnici nel nostro 👉 forum community