PHP 8.0: testiamolo con il compilatore JIT

PHP

Probabilmente avrete sentito la notizia di alcuni mesi fa che il compilatore JIT verrà aggiunto a PHP 8. Già dalla versione PHP 7.0, sono state apportate modifiche per migliorare le prestazioni, ma questa sarà una nuova svolta per PHP. Questa grande funzionalità è stata sviluppata 2 anni fa, ma il lancio di PHP 8.0 è previsto tra meno di 1 anno. In questo articolo, daremo un’occhiata di cosa si tratta realmente, ma soprattutto proveremo a testarlo su Linux.

Che cos’è JIT

Forse non conoscete JIT, quindi prima spiegheremo di cosa si tratta. Probabilmente sapete già che PHP è un linguaggio interpretato a scripting server side, il che significa che non è necessario compilare il codice prima che venga eseguito (a differenza di altri linguaggi come C/C++). Invece, il modulo PHP legge il codice e lo esegue. In altre parole, non si codifica il codice per compilarlo in linguaggio macchina per eseguirlo, ma viene codificato uno script e poi inviato a PHP per essere eseguito Server Side appunto.

PHP è dotato di una macchina virtuale chiamata Zend VM. Perché chiamarla macchina virtuale? Perché si comporta come un computer durante l’esecuzione del codice stesso. È responsabile della lettura e dell’esecuzione del codice PHP. Ma prima di ciò, il codice verrà letto e tradotto da PHP in opcode, la lingua che Zend VM comprende. Quindi Zend VM sarà in grado di eseguire quel codice operativo. Questa è un’illustrazione per una facile comprensione.

Quindi abbiamo bisogno prima di uno step di parse e poi di interpretazione. Velocizzeremo il tutto, sfruttando il cosiddetto OPCache (Opcode Cache) che memorizza i risultati della fase di compilazione, quindi non sarà necessario compilare nuovamente la volta successiva. Ecco come funzionava PHP fino ad ora.

Quindi ora parliamo del compilatore JIT, significa che compileremo la sorgente (codice) in un linguaggio macchina da eseguire. JIT sta per “Just-In-Time”, il che significa servirà tempo per compilare, invece di compilare prima e poi eseguire. Quando sarà necessario avviare lo script, sarà compilato subito al momento.

Per PHP, il compilatore JIT compilerà il codice sorgente, nel codice macchina ed eseguirà quel codice invece di inviarlo a Zend VM per essere eseguito. Quindi non abbiamo più bisogno di un interprete e, naturalmente, il codice funziona anche più velocemente.

Sarà davvero più veloce?

Questa è una demo che mostra la velocità di PHP con il compilatore JIT rispetto alla vecchia versione. Nel video si utilizza un codice per creare immagini 3D.

Ma ATTENZIONE, nessuno ha mai usato PHP per creare immagini 3D

Poiché il nostro script sarà compilato nel codice macchina e sarà eseguito direttamente dalla CPU anziché dall’interprete Server Side, gli aumenti di velocità riguarderanno principalmente l’avvio del codice stesso e l’utilizzo della CPU (quindi richiede potenza della macchina). Ma l’applicazione Web non avendo tale codice, il tutto sarà delegato dal processo dall’I/O (query del database, caricamento del file, richiesta HTTP ecc.), il più delle volte l’app non fa nulla, resta solo in ascolto per mostrare i risultati dal database o dall’API, ecc. Purtroppo, ora come ora una webapp difficilmente sarà più veloce.

A cosa serve la JIT?

A partire dalla versione PHP 7.0, il problema delle prestazioni è stato uno delle grosse problematiche da risolvere, in parte anche grazie alla concorrenza dell’HHVM di Facebook (pure utilizza il compilatore JIT). OPCache, struttura i dati, ottimizzando tutto poco a poco per ottenere le massime prestazioni.

Inoltre, le prestazioni di PHP per un linguaggio server possono già essere considerate abbastanza buone, e non sarà più lento come in passato. Quindi è tempo di espandere un le capacità di PHP, verso aree come l’analisi dei dati, il rendering 3D/2D, ecc.

In passato, il codice ad alte prestazioni veniva spesso scritto come estensione in C/C++ anziché come pacchetto PHP. Ad esempio, la phpredis è sempre 6-7 volte più veloce di predis. Se il codice PHP viene compilato anziché interpretato, otterremo pacchetti con le stesse prestazioni delle estensioni scritte in C/C++.

Ecco il motivo principale per cui è stato scelto il compilatore JIT: questa è la migliore e potenziale direzione verso quale dirigersi.

Proviamoci: facciamo un test

Dopo questa doverosa introduzione, proviamolo direttamente su campo. Dal momento che non esiste ancora una versione di PHP 8.0, dovremo compilare dal codice sorgente PHP versione 7.4 ossia ancora in alpha, il master è già 8.0. Innanzitutto, scarichiamo il codice sorgente:

wget -O php.zip https://github.com/php/php-src/archive/master.zip unzip php.zip cd php-src-master

Quindi installiamo le dipendenze. Useremo Ubuntu Server, se usate altre distro troverete lo stesso pacchetto da soli.

apt-get install autoconf bison dpkg-dev file g++ gcc libc-dev make pkg-config re2c libxml2-dev libsqlite3-dev

Generiamo il file di build ./buildconf;

Quindi eseguire ./configure per impostare la build. Selezionate le opzioni per compilare PHP. Puoi scegliere un percorso da installare aggiungendo –prefix = <dir_install>. Di default installerà /usr/local/bin, quindi se avete già installato un’altra versione, ricordatevi di configurarlo. PHP verrà installato nel percorso <dir_install>/bin/php. Aggiungete il percorso per il file di configurazione con –with-config-file-path e –with-config-file-scan-dir se lo desiderate.

./configure --help 

Ad esempio, eseguo ./configure come di seguito:

./configure --prefix=/opt --with-config-file-path=/opt/php –with-config-file-scan-dir=/opt/php/conf.d

Montiamo

make -j$(nproc)
make install

Quindi controlliamo eseguendo :

php -v

da shell dovrebbe risultare:

PHP 8.0.0-dev (cli) (built: Jul 15 2019 02:22:59) ( NTS ) 
Copyright (c) The PHP Group Zend Engine v4.0.0-dev, 
opyright (c) Zend Technologies     
with Zend OPcache v8.0.0-dev, Copyright (c), by Zend Technologies

Il compilatore JIT fa parte dell’estensione OPCache, quindi abilitiamolo prima di utilizzarlo. Aggiungiamo queste righe al file php.ini:

opcache.jit_buffer_size=32M
opcache.jit=1235

Ora proveremo a eseguire un file PHP con l’opzione

-dopcache.jit_debug = 1

Vedremo il codice assembly compilato. Ad esempio, con un file come questo:

<?php

$a = 0;

for ($i = 0; $i < 10000; $i++) {
$a += $i;
}

echo $a;

Sarà compilato nel codice assembly come di seguito:

JIT$/php-src-master/hello.php: ; (/php-src-master/hello.php)
         sub $0x10, %rsp
         lea 0x50(%r14), %rdi
         cmp $0xa, 0x8(%rdi)
         jnz .L1
         mov (%rdi), %rdi
         cmp $0x0, 0x18(%rdi)
         jnz .L12
         add $0x8, %rdi
 .L1:
         test $0x1, 0x9(%rdi)
         jnz .L13
 .L2:
         mov $0x0, (%rdi)
         mov $0x4, 0x8(%rdi)
  ; ...
  

Ora proviamo il benchmark per vedere se realmente è più veloce. Nel codice sorgente, c’è un file Zend/bench.php che possiamo testare. In questo file ci sono molti codici calcolati (hash, loop .etc). Questo è il risultato ottenuto (riformattato per un facile confronto):

Sicuramente risulta più veloce, non è affatto strano. Proveremo a confrontare un’altra app web, un progetto Laravel e confrontato con lo strumento ApacheBench

ab -t10 -c10 http://test.localhost/

Questo è il risultato ottenuto:

PHP 7.3: 131.37 req/s
PHP 8.0 + JIT: 133.57 req/s

In breve , dalla versione 8 sarà significativamente più veloce, ma per il momento, la maggior parte del codice PHP esistente nel mondo, manterrà degli standard che risultano ancora approssimativamente lenti. Tuttavia, nuovi sviluppi si apriranno per la nuova versione PHP compilata JIT.

Se avete bisogno di maggiori aggiornamenti, oppure chiarimenti su come configurare adeguatamente un server web, non esitate a contattarmi in privato, sono in grado di risolvere qualunque problema riscontriate nelle vostre configurazioni.

Non affidatevi al caso, ma in tema di Sviluppo Applicazioni Web (in questo caso WebApp Development) affidatevi sempre ad una Persona di Competenza.

Vulnerabilità confermata PHPUnit su Prestashop

prestashop

Da inizio Gennaio 2020 è stato scoperto un malware chiamato XsamXadoo Bot. Questo malware può essere utilizzato per avere accesso a un negozio online e prenderne direttamente il controllo.

Pensiamo che il bot abbia utilizzato una vulnerabilità nota dello strumento PHP PHPUnit, segnalata come (CVE-2017-9841). https://security-tracker.debian.org/tracker/CVE-2017-9841.
Sebbene questa vulnerabilità sia specifica per Server Linux e PHP v 5.x e inferiori, un aggiornamento a una versione superiore potrebbe mitigare il problema, ma non risolverlo definitivamente. Ecco cosa fare in questi casi.

Verificare se il sito web è vulnerabile

Per sapere se il negozio Prestashop è vulnerabile a un attacco, questo è quello che si deve fare. Se non siete a vostro agio nella manipolazione dei file nei vostri server, contattate una persona qualificata e competente in materia; agire senza una minima preparazione potrebbe compromettere la stabilità se non la funzionalità del vostro sito e negozio Prestashop.

  1. Sul vostro server, cercate la directory “/Vendor” al livello principale del sito PrestaShop
  2. Se la directory /Vendor contiene un’altra directory “/phpunit”, potreste essere vulnerabili a un attacco esterno.
  3. Basta semplicemente eliminare la directory “/phpunit” e il suo contenuto.

Per i più esperti potete usare il seguente comando da Shell linux del server, lanciandolo dal path della directory principale del sito Prestashop /vendor

find . -type d -name "phpunit" -exec rm -rf {} \;

Attenzione: non toccate nient’altro o potreste pregiudicare la funzionalità dell’intero sito. Altri file e directory (ad es. /Vendor/symfony/symfony/src/Symfony/Bridge/PhpUnit/ o .xml) sono sicuri, non vanno eliminati.

Dopo aver controllato la directory principale di PrestaShop, ripetete gli stessi passaggi all’interno di tutte le directory dei moduli:

  1. In ogni directory di un modulo, verificate se esiste una directory /Vendor
  2. All’interno della /Vendor di ciascun modulo, verificate se esiste una directory “/phpunit”.
  3. Se la directory di un modulo contiene questa directory “/phpunit”, questo modulo può rendervi vulnerabili a un attacco esterno.
  4. Basta semplicemente eliminare la directory “/phpunit” e il suo contenuto.

Sempre per gli esperti utilizzate lo stesso comando dalla directory principale, /modules//vendor

find . -type d -name "phpunit" -exec rm -rf {} \;

Controllate di nuovo che nessuna directory /Vendor contenga una directory “/phpunit”

La cancellazione della directory “/phpunit” dalla cartella di un modulo non avrà alcuna conseguenza sul funzionamento del modulo stesso. Questo semplice passaggio proteggerà il vostro negozio online da questa vulnerabilità critica, sempre che il vostro sito Web non sia già stato compromesso. Se non avete trovato alcun modulo contenente questa directory “/phpunit”, il negozio non è vulnerabile.

Cosa può succedere se il negozio è compromesso?

Questa vulnerabilità consente a un utente malintenzionato di accedere al vostro sito web: ad esempio, un utente malintenzionato può potenzialmente rubare i vostri dati e prendere le autorizzazioni per eseguire qualsiasi comando indistintamente dal vostro permesso e/o autorizzazione.

Secondo la nostra analisi, la maggior parte degli aggressori inserisce nuovi file nel filesystem o modifica file già esistenti, come AdminLoginController.php.

Ecco un elenco non esaustivo di file dannosi noti che potrebbero indicare un negozio compromesso:

  • XsamXadoo_Bot.php
  • XsamXadoo_deface.php
  • 0x666.php
  • f.php
  • Xsam_Xadoo.html

Potete verificare se i file core di PrestaShop sono stati modificati visualizzando la sezione “Elenco dei file modificati” nella parte inferiore della pagina “Parametri avanzati> Informazioni” nel Back Office di Prestashop. Tuttavia, questo controllo potrebbe non essere sufficiente poiché il sito potrebbe essere già stato compromesso. Quindi è utile eseguire delle procedure corrette:

  • Controllate attentamente che l’attacco non abbia lasciato alcun file sul vostro server, ad esempio file nascosti nel mezzo e/o con caratteristiche ereditarie.
  • Prendete in considerazione la possibilità di chiedere a tutti gli utenti dei negozi di modificare la propria password, inclusi anche gli utenti del back office, così come gli account dei clienti. Assicuratevi comunque prima, che nessun file compromesso sia ancora presente nel negozio.

Se ritenete che il vostro sito Web sia già stato compromesso, vi consigliamo di contattare SUBITO un esperto di sicurezza.

Cosa sta facendo in merito PrestaShop per risolvere questa vulnerabilità?

Stando alle loro dichiarazioni, tutti i partner e gli ambasciatori PrestaShop sono stati informati e dovrebbero aver già reso sicuri i negozi su cui hanno il controllo.

Tutti i moduli PrestaShop sono stati aggiornati e ora sono al sicuro. Attualmente stanno anche controllando ogni altro modulo disponibile su PrestaShop Addons, per verificare che non contengano la directory vulnerabile “phpunit”.

La sicurezza dei negozi online è al centro delle nostre preoccupazioni. Valutiamo e stiamo assicurando che l’impatto con questo malware sia più lieve possibile. Vi aggiorneremo regolarmente su questo argomento.

Per informazioni più dettagliate e per esperti o di chi ne ha rigorosa competenza, consigliamo di consultare il post ufficiale di Prestashop che può aiutare in modo più dettagliato sulla forma e sull’incidenza che ha il negozio on Line con questo malware:
https://build.prestashop.com/news/critical-security-vulnerability-in-prestashop-modules/

Download Modulo di verifica automatica di vulnerabilità:
https://www.presta-addons.com/free/m4check.zip

Download Modulo automatico di fix alla vulnerabilità phpunit:
https://www.myprestastore.com/downloads/module-prestashop-auto-clean-phpunit/