5 Marzo 2026

PixelYourSite Cache Poisoning e SEO Poisoning in Pixel Your Site: analisi di una vulnerabilità sottovalutata

Una vulnerabilità nel plugin WordPress Pixel Your Site consente l’iniezione persistente di domini arbitrari nel codice HTML delle pagine, aprendo scenari concreti di cache poisoning e potenziale SEO poisoning.

PixelYourSite-Vulnerability-WordPress

Introduzione

Pixel Your Site (PYS) è uno dei plugin WordPress più diffusi per la gestione dei pixel di tracciamento e delle integrazioni con le principali piattaforme di advertising e analytics. Viene utilizzato per configurare e gestire facilmente strumenti come Facebook Pixel, Google Analytics, TikTok Pixel, Google Ads e altre piattaforme di marketing, senza richiedere modifiche manuali al codice del sito. Grazie alla sua semplicità di configurazione e alla capacità di centralizzare diversi sistemi di tracking, il plugin ha raggiunto una diffusione significativa nell’ecosistema WordPress, con oltre 500.000 installazioni attive e una presenza capillare soprattutto su siti eCommerce e progetti orientati al marketing digitale.

PixelYourSite-0day

Proprio questa ampia diffusione rende particolarmente rilevante qualsiasi problema di sicurezza presente nel codice del plugin. Durante un’analisi tecnica approfondita del suo funzionamento interno, è emersa una vulnerabilità che consente a un attaccante di iniettare domini o stringhe di testo arbitrarie all’interno dell’HTML generato dal sito. L’aspetto più critico è che questo comportamento può essere sfruttato da chiunque, senza alcuna autenticazione o accesso privilegiato al sito target. In altre parole, non è necessario essere amministratori, utenti registrati o avere qualsiasi tipo di accesso alla piattaforma WordPress per sfruttare il problema.

La situazione diventa ancora più problematica quando il sito utilizza un sistema di caching, una configurazione estremamente comune nei siti WordPress in produzione. Plugin di cache come WP Super Cache, W3 Total Cache, WP Rocket o LiteSpeed Cache — oppure sistemi di caching a livello CDN come Cloudflare — memorizzano le pagine HTML generate dal server per ridurre il carico e migliorare le prestazioni. In presenza della vulnerabilità, questo meccanismo può trasformare un input controllato dall’attaccante, normalmente limitato alla singola richiesta HTTP, in un contenuto persistente che verrà servito a tutti i visitatori successivi fino alla scadenza della cache. Di fatto, una singola richiesta malevola può “avvelenare” la versione cached di una pagina, rendendo l’iniezione visibile a migliaia di utenti e anche ai crawler dei motori di ricerca.

Come ha evidenziato Michele Genito, noto esperto WordPress italiano che ha portato alla luce il problema e ne ha divulgato i dettagli tecnici, la vulnerabilità presenta implicazioni ben più serie di quanto possa sembrare a prima vista. Nonostante la segnalazione sia stata inoltrata ai canali di sicurezza competenti, il team di Wordfence ha rigettato la segnalazione classificandola come non rilevante dal punto di vista della sicurezza. Secondo questa valutazione, il comportamento osservato sarebbe riconducibile al fatto che il campo Referer è intrinsecamente controllabile dal client e quindi non rappresenterebbe di per sé una vulnerabilità.

Questa nostra analisi tecnica dimostra invece perché tale interpretazione risulti, a nostro avviso, incompleta e superficiale. Il problema non risiede semplicemente nella possibilità di manipolare il referrer — cosa effettivamente nota da sempre nel contesto HTTP — ma nella combinazione di diversi fattori architetturali: l’utilizzo diretto di input non fidati, la loro esposizione nel markup HTML servito a tutti gli utenti tramite JavaScript inline e, soprattutto, l’effetto moltiplicatore introdotto dai sistemi di caching. È proprio questa combinazione che trasforma un dato temporaneo per-request in un contenuto persistente e potenzialmente sfruttabile in scenari di cache poisoning e SEO manipulation.

Il meccanismo: come PYS espone il TrafficSource nel DOM

Il plugin genera una variabile JavaScript globale pysOptions tramite wp_localize_script(), che viene renderizzata inline nel sorgente HTML di ogni pagina:

<script id="pys-js-extra">
var pysOptions = {
    ...
    "tracking_analytics": {
        "TrafficSource": "google.com",
        "TrafficLanding": "https://esempio.it/pagina/",
        "TrafficUtms": { ... },
        "TrafficUtmsId": { ... }
    },
    ...
};
</script>

Il campo TrafficSource contiene il dominio di provenienza del visitatore. Questo valore viene determinato server-side dalla funzione getTrafficSource() definita in includes/functions-common.php e inserito nell’array di opzioni in includes/class-events-manager.php alla riga 188:

$options['tracking_analytics'] = array(
    "TrafficSource"  => getTrafficSource(),
    "TrafficLanding" => sanitize_url($_COOKIE['pys_landing_page'] ?? $_SESSION['LandingPage'] ?? 'undefined'),
    "TrafficUtms"    => getUtms(),
    "TrafficUtmsId"  => getUtmsId(),
);

L’array viene poi serializzato nel DOM:

wp_localize_script('pys', 'pysOptions', $data);

Analisi della funzione vulnerabile

Ecco la funzione getTrafficSource() nella sua interezza:

function getTrafficSource () {
    $referrer = "";
    $source = "";
    try {
        if (isset($_SERVER['HTTP_REFERER'])) {
            $referrer = $_SERVER['HTTP_REFERER'];  // [1] Input non sanitizzato
        }

        $direct = empty($referrer);
        $internal = $direct ? false : (substr($referrer, 0, strlen(site_url())) === site_url());
        $external = !$direct && !$internal;
        $cookie = sanitize_text_field(
            !isset($_COOKIE['pysTrafficSource']) ? null : $_COOKIE['pysTrafficSource']
        );  // [2] Cookie controllabile dall'utente
        $session = sanitize_text_field(
            !isset($_SESSION['TrafficSource']) ? null : $_SESSION['TrafficSource']
        );

        if (!$external) {
            $source = $cookie || $session ? $cookie ?? $session : 'direct';
        } else {
            $source = ($cookie && $cookie === $referrer)
                   || ($session && $session === $referrer)
                    ? $cookie ?? $session
                    : $referrer;  // [3] Referrer usato direttamente
        }

        if ($source !== 'direct') {
            $parse = parse_url($source);
            if (isset($parse['host'])) {
                return $parse['host'];  // [4] Protezione parziale
            } elseif ($source == $cookie || $source == $session) {
                return $source;  // [5] BYPASS: valore restituito senza parse_url
            } else {
                return defined('REST_REQUEST') && REST_REQUEST ? 'REST API' : "direct";
            }
        } else {
            return defined('REST_REQUEST') && REST_REQUEST ? 'REST API' : $source;
        }
    } catch (\Exception $e) {
        return "direct";
    }
}

I punti critici

  • [1] $_SERVER[‘HTTP_REFERER’] non sanitizzato. L’header HTTP Referer è interamente controllabile dal client. Qualsiasi valore può essere inviato con una semplice richiesta curl.
  • [2] Cookie pysTrafficSource controllabile. Il cookie è impostato lato client dal JavaScript del plugin stesso, quindi un attaccante può impostarlo con qualsiasi valore. sanitize_text_field() rimuove i tag HTML ma non impedisce l’inserimento di domini arbitrari o testo non-HTML.
  • [3] Referrer usato come source. Quando il referrer è esterno e non corrisponde ai valori in cookie/sessione, viene usato direttamente come $source.
  • [4] parse_url() come protezione parziale. Il codice tenta di estrarre solo l’host dal valore, ma questa protezione è facilmente aggirabile.
  • [5] Il bypass critico. Quando $source corrisponde al cookie o alla sessione, il valore viene restituito integralmente senza passare per parse_url(). Questo significa che un valore arbitrario memorizzato nel cookie pysTrafficSource può finire direttamente nell’HTML.

L’attacco: Cache Poisoning + SEO Poisoning

Cache Poisoning + SEO Poisoning è una tecnica di attacco che sfrutta i sistemi di caching dei siti web per inserire contenuti malevoli o manipolati all’interno delle pagine memorizzate in cache. Un attaccante invia una richiesta appositamente costruita che altera l’output HTML generato dal server; se la pagina viene salvata nella cache in quel momento, la versione manipolata verrà servita a tutti i visitatori successivi. Quando il contenuto iniettato include domini o riferimenti esterni indesiderati, l’attacco può trasformarsi in SEO poisoning, influenzando l’interpretazione della pagina da parte dei motori di ricerca e associando il sito vittima a domini spam, malware o contenuti indesiderati.

Prerequisiti

  • Il sito target utilizza Pixel Your Site (qualsiasi versione attuale)
  • Il sito ha un sistema di cache attivo (WP Super Cache, W3 Total Cache, WP Rocket, LiteSpeed Cache, Cloudflare Page Cache, Varnish Cache ecc.)
  • La pagina target non è ancora in cache (o la cache è appena scaduta)

Scenario di attacco base

# L'attaccante visita la pagina nel momento in cui la cache viene rigenerata
curl -s -H "Referer: https://sito-pornografico.xxx" \
     https://sitovittima.it/pagina-importante/ > /dev/null

Da questo momento, la risposta HTML viene memorizzata nella cache con il TrafficSource impostato al dominio dell’attaccante. Tutti i visitatori successivi — inclusi i crawler dei motori di ricerca — vedranno:

var pysOptions = {
    "tracking_analytics": {
        "TrafficSource": "sito-pornografico.xxx",
        ...
    }
};

Scenario avanzato: cookie injection

# L'attaccante imposta il cookie con testo arbitrario
curl -s -b "pysTrafficSource=testo-offensivo-qualsiasi" \
     -H "Referer: testo-offensivo-qualsiasi" \
     https://sitovittima.it/ > /dev/null

Poiché il referrer corrisponde al cookie, il codice entra nel branch [5] e restituisce il valore senza validazione del formato dominio. sanitize_text_field() rimuove i tag HTML, ma qualsiasi stringa di testo non-HTML passa indisturbata.

Impatti concreti

  • Negative SEO. Un competitor o un attaccante può associare domini in blacklist (pornografia, malware, gambling) al sito vittima. I crawler dei motori di ricerca analizzano il contenuto completo della pagina, incluso il JavaScript inline.
  • Competitor sabotage. Inserire il dominio di un competitor diretto crea false associazioni, potenzialmente interpretabili dai motori di ricerca come relazioni tra i due siti.
  • Defacement soft. Pur non essendo un XSS (perché wp_localize_script esegue escaping dei valori), il contenuto è visibile nel sorgente HTML.
  • Persistenza. L’attacco persiste per tutta la durata della cache. Con configurazioni comuni (cache di 12–24 ore), una singola richiesta malevola può avvelenare la pagina per un’intera giornata.

Perché non è “solo un referrer”

La risposta tipica a questa classe di problemi è: “il referrer è sempre controllabile, non è una vulnerabilità”. Questa affermazione è corretta in isolamento, ma ignora il contesto.

  • Il referrer viene persistito nell’output HTML.
  • La cache amplifica l’impatto.
  • Non serve autenticazione.
  • Il costo dell’attacco è zero.

Fix proposto

if ($source !== 'direct') {
    $parse = parse_url($source);
    if (isset($parse['host'])) {
        $host = $parse['host'];
    } elseif ($source == $cookie || $source == $session) {
        $parse_stored = parse_url($source);
        $host = isset($parse_stored['host']) ? $parse_stored['host'] : $source;
    } else {
        return defined('REST_REQUEST') && REST_REQUEST ? 'REST API' : "direct";
    }

    $host = preg_replace('/[^a-zA-Z0-9.\-]/', '', $host);

    if (empty($host) || !preg_match(
        '/^([a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/',
        $host
    )) {
        return "direct";
    }

    return $host;
}

Cosa cambia

  • Eliminazione del bypass. Anche i valori provenienti da cookie e sessione vengono processati tramite parse_url().
  • Sanitizzazione dei caratteri. Un preg_replace rimuove qualsiasi carattere non valido per un nome di dominio.
  • Validazione del formato. Una regex verifica che il risultato sia un dominio sintatticamente valido.

Conclusioni

La vulnerabilità risiede nella combinazione di tre fattori: input non fidato (Referer e cookie) persistito nell’output HTML tramite wp_localize_script(), assenza di validazione del formato e amplificazione tramite cache che rende l’iniezione persistente.

Non si tratta di un XSS tradizionale, ma classificare una vulnerabilità esclusivamente in base alla tassonomia OWASP classica significa ignorare vettori di attacco reali. Il cache poisoning combinato con SEO poisoning è un rischio concreto, documentato, e in questo caso trivialmente sfruttabile.

Un plugin installato su centinaia di migliaia di siti dovrebbe trattare qualsiasi dato proveniente dal client come potenzialmente malevolo — specialmente quando quel dato finisce nel markup servito a tutti i visitatori.

Hai dei dubbi? Non sai da dove iniziare? Contattaci !

Abbiamo tutte le risposte alle tue domande per aiutarti nella giusta scelta.

Chatta con noi

Chatta direttamente con il nostro supporto prevendita.

0256569681

Contattaci telefonicamente negli orari d’ufficio 9:30 – 19:30

Contattaci online

Apri una richiesta direttamente nell’area dei contatti.

DISCLAIMER, Note Legali e Copyright. Red Hat, Inc. detiene i diritti su Red Hat®, RHEL®, RedHat Linux®, e CentOS®; AlmaLinux™ è un marchio di AlmaLinux OS Foundation; Rocky Linux® è un marchio registrato di Rocky Linux Foundation; SUSE® è un marchio registrato di SUSE LLC; Canonical Ltd. detiene i diritti su Ubuntu®; Software in the Public Interest, Inc. detiene i diritti su Debian®; Linus Torvalds detiene i diritti su Linux®; FreeBSD® è un marchio registrato di The FreeBSD Foundation; NetBSD® è un marchio registrato di The NetBSD Foundation; OpenBSD® è un marchio registrato di Theo de Raadt; Oracle Corporation detiene i diritti su Oracle®, MySQL®, MyRocks®, VirtualBox® e ZFS®; Percona® è un marchio registrato di Percona LLC; MariaDB® è un marchio registrato di MariaDB Corporation Ab; PostgreSQL® è un marchio registrato di PostgreSQL Global Development Group; SQLite® è un marchio registrato di Hipp, Wyrick & Company, Inc.; KeyDB® è un marchio registrato di EQ Alpha Technology Ltd.; Typesense® è un marchio registrato di Typesense Inc.; REDIS® è un marchio registrato di Redis Labs Ltd; F5 Networks, Inc. detiene i diritti su NGINX® e NGINX Plus®; Varnish® è un marchio registrato di Varnish Software AB; HAProxy® è un marchio registrato di HAProxy Technologies LLC; Traefik® è un marchio registrato di Traefik Labs; Envoy® è un marchio registrato di CNCF; Adobe Inc. detiene i diritti su Magento®; PrestaShop® è un marchio registrato di PrestaShop SA; OpenCart® è un marchio registrato di OpenCart Limited; Automattic Inc. detiene i diritti su WordPress®, WooCommerce®, e JetPack®; Open Source Matters, Inc. detiene i diritti su Joomla®; Dries Buytaert detiene i diritti su Drupal®; Shopify® è un marchio registrato di Shopify Inc.; BigCommerce® è un marchio registrato di BigCommerce Pty. Ltd.; TYPO3® è un marchio registrato di TYPO3 Association; Ghost® è un marchio registrato di Ghost Foundation; Amazon Web Services, Inc. detiene i diritti su AWS® e Amazon SES®; Google LLC detiene i diritti su Google Cloud™, Chrome™, e Google Kubernetes Engine™; Alibaba Cloud® è un marchio registrato di Alibaba Group Holding Limited; DigitalOcean® è un marchio registrato di DigitalOcean, LLC; Linode® è un marchio registrato di Linode, LLC; Vultr® è un marchio registrato di The Constant Company, LLC; Akamai® è un marchio registrato di Akamai Technologies, Inc.; Fastly® è un marchio registrato di Fastly, Inc.; Let’s Encrypt® è un marchio registrato di Internet Security Research Group; Microsoft Corporation detiene i diritti su Microsoft®, Azure®, Windows®, Office®, e Internet Explorer®; Mozilla Foundation detiene i diritti su Firefox®; Apache® è un marchio registrato di The Apache Software Foundation; Apache Tomcat® è un marchio registrato di The Apache Software Foundation; PHP® è un marchio registrato del PHP Group; Docker® è un marchio registrato di Docker, Inc.; Kubernetes® è un marchio registrato di The Linux Foundation; OpenShift® è un marchio registrato di Red Hat, Inc.; Podman® è un marchio registrato di Red Hat, Inc.; Proxmox® è un marchio registrato di Proxmox Server Solutions GmbH; VMware® è un marchio registrato di Broadcom Inc.; CloudFlare® è un marchio registrato di Cloudflare, Inc.; NETSCOUT® è un marchio registrato di NETSCOUT Systems Inc.; ElasticSearch®, LogStash®, e Kibana® sono marchi registrati di Elastic N.V.; Grafana® è un marchio registrato di Grafana Labs; Prometheus® è un marchio registrato di The Linux Foundation; Zabbix® è un marchio registrato di Zabbix LLC; Datadog® è un marchio registrato di Datadog, Inc.; Ceph® è un marchio registrato di Red Hat, Inc.; MinIO® è un marchio registrato di MinIO, Inc.; Mailgun® è un marchio registrato di Mailgun Technologies, Inc.; SendGrid® è un marchio registrato di Twilio Inc.; Postmark® è un marchio registrato di ActiveCampaign, LLC; cPanel®, L.L.C. detiene i diritti su cPanel®; Plesk® è un marchio registrato di Plesk International GmbH; Hetzner® è un marchio registrato di Hetzner Online GmbH; OVHcloud® è un marchio registrato di OVH Groupe SAS; Terraform® è un marchio registrato di HashiCorp, Inc.; Ansible® è un marchio registrato di Red Hat, Inc.; cURL® è un marchio registrato di Daniel Stenberg; Facebook®, Inc. detiene i diritti su Facebook®, Messenger® e Instagram®. Questo sito non è affiliato, sponsorizzato o altrimenti associato a nessuna delle entità sopra menzionate e non rappresenta nessuna di queste entità in alcun modo. Tutti i diritti sui marchi e sui nomi di prodotto menzionati sono di proprietà dei rispettivi detentori di copyright. Ogni altro marchio citato appartiene ai propri registranti. MANAGED SERVER® è un marchio registrato a livello europeo da MANAGED SERVER SRL, con sede legale in Via Flavio Gioia, 6, 62012 Civitanova Marche (MC), Italia e sede operativa in Via Enzo Ferrari, 9, 62012 Civitanova Marche (MC), Italia.

SOLO UN ATTIMO !

Ti sei mai chiesto se il tuo Hosting faccia schifo ?

Scopri subito se il tuo hosting provider ti sta danneggiando con un sito lento degno del 1990 ! Risultato immediato.

Close the CTA
Torna in alto