Nei giorni scorsi l’Agenzia per la Cybersicurezza Nazionale (ACN) ha pubblicato una segnalazione relativa ad alcune vulnerabilità individuate in n8n, la piattaforma open source per l’automazione dei workflow che utilizzo in un’installazione locale tramite Docker. …
Qualche giorno fa mi sono imbattuto in un comportamento a dir poco bizzarro sulla mia macchina Ubuntu: digitando nel browser un domain name completamente a caso, tipo http://mememem.it/ o http://nxdomain1.it/ (il nome è voluto: NXDOMAIN …
Ovvero come si scambiavano messaggi instantanei due utenti Unix prima dell’avvento di WhatsApp e Telegram. Qualche giorno fa stavo ragionando sui primi sistemi di messaggistica su ARPANET [E] e mi è tornato in mente il …
Da un po’ di tempo avevo il PC disseminato di container Docker installati qua e là, senza un vero criterio. Ho deciso che era il momento di mettere ordine e, allo stesso tempo, di costruire …
Continuo qui una serie di articoli che riguardano il funzionamento di Docker. In questo post ho condiviso la comprensione del perché Docker non possa essere pensato come un virtualizzatore hardware: non viene virtualizzata una macchina …
Ho sviluppato un piccola applicazione Android e la voglio testare sul mio dispositivo.
da dispositivo: Abilitare il debug USB (Impostazioni > Opzioni Sviluppatore > Debug USB -> ON)
da computer: da linea di comando digitare
$ adb devices
List of devices attached
QLF7N16406002695 device
Se Ubuntu non dovesse mostrare il device, dovete istruire l’OS aggiungendo il vostro utente al gruppo plugdev
sudo usermod -aG plugdev $LOGNAME
e poi bisogna aggiungere le udev rules per la ricognizione del dispositivo Android alla porta usb
apt-get install android-sdk-platform-tools-common
udev è il sottosistema di Linux che gestisce gli eventi generati dalle periferiche: esso si accorge quando tentate per esempio di collegare una pendrive USB o una scheda di rete.
Quindi in basso a dx attivare la tab Device File Explorer come in figura
Android e IntelliJ IDEA – elenco dei dispositivi collegati a USB
In alto a destra compare la tab del dispositivo con tutto il contenuto del file system:
Android e IntelliJ IDEA – Il dispositivo viene correttamente visulizzato nella lista dei device
Per installare adb
$ sudo apt-get install adb
Risorse web Android
Per installare Android Studio, seguire questo sito. Oppure, se siete utilizzatori di IntelliJ IDEA, il modulo Android è già compreso.
Sulla configurazione del device di test, questo sito.
Affinché le date e il tempo dell’applicazione Laravel siano sincronizzate con l’orologio del server occorre agire sui file di configurazione dell’applicazione. Ovviamente questo non è detto sia ciò che si desidera perché per esempio vogliamo che sia un jet lag tra il server e l’applicazione. In ogni caso, il file da modificare è uno soltanto: config/app,php:
Laravel consente di proteggere con semplicità le applicazioni dagli attacchi cross site (CSRF – Cross Site Request Forgery). I CSRF sono un tipo di sfruttamento malevolo dei programmi web in cui comandi non autorizzati vengono eseguiti al posto di un utente autenticato.
Attenzione: In particolare questi attacchi si possono verificare anche se non c’è alcuno strato di protezione con autenticazione tra il browser e il modulo HTML.
Laravel realizza nel modo che segue la protezione: esso genera automaticamente una stringa cosiddetta “gettone” (token) CFRS per ogni sessione attiva (quindi per ogni browser aperto sull’applicazione). Questo gettone viene usato per verificare che l’utente che ha fatto la richiesta sia lo stesso che ha acceduto all’inizio all’applicazione. Non serve che ci sia un’autenticazione, funziona anche per una sessione non autenticata in cui semplicemente il server invia un cookie di sessione al primo accesso anche senza necessariamente legarlo da un utente fisico nel database.
Ogni volta che si definisce una form HTML nell’applicazione, dovrebbe essere incluso un token CSFR in un campo nascosto (hidden) cosicché il middleware di protezione possa validare la richiesta. Per generarlo con Blade è facile: basta usare la direttiva @csrf per generare il campo:
Il metodo incluso nel gruppo middleware (si veda il metodo /app/Http/Middleware/VerifyCsfrToken.php) verificherà automaticamente che l’input proveniente dalla richiesta corrisponda al token salvato nella sessione.
Se non si agisce in questo modo, Laravel semplicemente blocca l’applicazione sollevando un errore HTTP 419:
Lo strumento delle migrazioni di Laravel è molto comodo per definire le tabelle di uno schema ma anche per le conseguenti ricadute positive sull’ORM Eloquent ai fini di produrre query con le join già fatte.
Mi riferisco al fatto che è possibile definire i vincoli di chiave esterna (foreign key). Solo che la definizione è un po’ “tricky”. Prendiamo questo esempio: due tabelle customers e orders con una relazione di chiave esterna da customers a orders:
Definizione della tabella customers, un solo attributo chiave, implicitamente definito con increments()C’è un attributo di riferimento a customer_id
Se faccio girare lo script di migrazione, che si incarica di creare gli oggetti nello schema del DB ottengo un errore:
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key
L’errore è abbstanza grave: abbiamo tentato di creare due chiavi: la prima con il campo id la seconda con il campo customer_id.
All’inizio credevo che fosse un problema della definizione del constraint, e così l’ho scorporato in una seconda invocazione separata: Schema::table eccetera. Invece il problema era com’è stato definito il campo, infatti ho lo stesso errore anche togliendo la definizione del contraint. Il problema è la dimensione del campo:
$table->unsignedInteger('customer_id', 10);
Ora lo spiego qui e sembra ovvio, ma trovarlo, come tutti i buoni martorei, richiede tempo: il metodo $table->unsignedInteger() ha un secondo parametro che non è affatto la dimensione del campo, che lui si regola automaticamente, ma è – disgraziatamente…
public function unsignedInteger($column, $autoIncrement = false)
{
return $this->integer($column, $autoIncrement, true);
}
… l’informazione $autoIncrement. Essendo disgrazatamente 10 == true in PHP, il campo così viene dichiarato come autoincrement e quindi come chiave primaria generando l’errore. Invece con questa dichiarazione:
La migrazione termina correttamente
In origine, in ogni caso, c’era la mia errata invocazione del metodo.
Il premio Nobel per la Fisica 2018 è stato assegnato a lavori sulle pinze laser, – ad Arthur Ashkin, una tecnologia che consente di spostare in modo estremamente preciso oggetti microscopici come i virus utilizzando la pressione elettromagnetica della luce – e sugli impulsi ultrabrevi (Mourou e Strickland). Con questa tecnica si ottengono impulsi della durata di un femtosecondo (10-15 secondi).
Per avere una idea di quanto breve sia il femtosecondo si pensi che in 1 secondo ci stanno tanti fs quanto il numero di secondi nell’età dell’universo (circa 1018):
1 s : 1 fs = Età dell’universo : 1 s
Il laser a femtosecondo, così chiamato in breve, viene utilizzato nella chirurgia dell’occhio, per la sua capacità di dosare in modo precisissimo l’energia degli impulsi.
Oggi mi sono trovato davanti un problema sconosciuto: ho aperto una finestra (nella fattispecie, l’applet Java di MirthConnect) e ho poi normalmente commutato su un’altra finestra da quel momento non vedevo più la finestra Java nell’elenco dei task che vengono visualizzati con ALT-TAB:
La finestra in foreground non c’è nell’elenco dei task.
Se minimizzo la finestra di Mirthconnect non riesco più a recuperarla… Come posso fare ad accedervi nuovamente? il Linux ci sono due bei strumenti:
wmctrlinteract with a EWMH/NetWM compatible X Window Manager: consente di fare cose meravigliose per automatizzare il desktop tramite script bash, ma in questo caso voglio solo vedere l’elenco delle finestre attive:
Come si può notare le finestre attive sono più di quelle mostrate con ALT-TAB; in particolare ho evidenziato le due finestra scomparse: mi serve accedere ad una di queste due (l’ultima)
C’è poi un secondo tool molto potente:
xdotoolfake keyboard/mouse input, window management, and more: questa utility simula l’uso della tastiera e di movimenti del mouse prodotti con uno script bash! Nel mio caso mi serve solo per sapere quale finestra è associata al processo che vedo essere quello sotto il quale gira il client Mirtchconnect
Il web come lo conosciamo oggi è un mezzo per lo più in sola lettura.
È vero che con il Web 2.0 anche gli utenti contribuiscono ai contenuti web, ma ciò avviene in modo molto diverso e molto più sofisticato rispetto a quanto immaginato inizialmente da Tim Berners-Lee.
Il suo browser WWW infatti agiva sui server web in lettura e scrittura: si poteva leggere una pagina web ma si poteva anche modificarla.
Come si “scrive” sul web ai tempi del Web 2.0
Quello che accade attualmente con il Web 2.0, ad esempio quando aggiungiamo un commento ad un articolo di un blog WordPress, è qualcosa di più complicato, ossia la scrittura in un database e non nel filesystem del server che eroga le pagine Web.
Tecnicamente quando invochiamo la funzionalità di aggiunta di un commento, invochiamo un comando di lettura di una risorsa web (comando HTTP POST) che si chiama wp-comments-post.php passando dei parametri:
POST /wp-comments-post.php HTTP/1.1
Host: www.betaingegneria.it
Connection: keep-alive
Content-Length: 184
...
comment=questo %22 il mio commento&author=My+Name&email=my.mail%40gmail.com&url=&submit=Submit+Comment&comment_post_ID=2734&comment_parent=0&akismet_comment_nonce=afb00fa731&ak_js=1535630177692
Qui, disgraziatamente, la parola post è utilizzata con due significati diversi:
POST come comando HTTP (nel senso di INVIA)
POST come articolo del blog
In questa operazione di scrittura del commento, il browser chiede (in lettura!) al server di caricare il programma wp-comments-post.php. Questa richiesta è inviata al server quando nella pagina del post clicchiamo sul link “Submit Comment” (o “Invia Commento” o qualcos’altro), assieme alla mail e il valore corrispondente alla scelta I’m not a ROBOT. Con il comando POST i parametri vengono inviati dopo il termine dell’intestazione HTTP e un doppio a capo (come illustrato sopra). Se utilizzassimo il comando di HTTP GET i parametri sarebbero contenuti nell’URL, separando il nome della risorsa dai parametri con un “?”:
GET /wp-comments-post.php?comment=questo %22 il mio commento&author=My+Name&email=my.mail%40gmail.com&url=&submit=Submit+Comment&comment_post_ID=2734&comment_parent=0&akismet_comment_nonce=afb00fa731&ak_js=1535630177692 HTTP/1.1
Al di là di questa differenza tra GET e POST è importante capire bene qui che la risorsa (nome tecnico della “pagina” PHP) wp-comments-post.php, non viene alterata, viene soltanto letta!
Quello che succede a questo punto è che il server web Apache non serve direttamente la pagina PHP al browser, anzi passa il controllo all’application server (il PHP nel caso di WordPress) il quale legge ed esegue il programma PHP wp-comments-post.php. All’interno di questo programma ci sono le istruzioni che salvano il nostro commento (“questo è il mio commento”) in un database. Il tutto è illustrato nella figura 1.
Fig. 1: Architettura Web 2.0
Successivamente, se tutto va bene, (in modo automatico) il server risponderà al browser inoltrandogli una sola intestazione (quindi non una pagina web) contenente soltanto un comando di redirect, ovvero una ingiunzione al browser di effettuare un’altra richiesta al web server perché gli serva il post che ora conterrà anche il nostro commento (vedi fig. 2).
Qui ci si soffermi a capire bene: è sempre il browser che inizia la richiesta di un contenuto. Egli agisce sempre come un cliente.
Tutto questo giro è perché la pagina HTML (il post contenente il commento) che viene consegnata dal web server al browser in realtà è il frutto di elaborazione del server applicativo PHP che legge il contenuto dell’articolo (anch’esso contenuto nel database) e gli eventuali commenti e compila un’unica pagina HTML che consegnerà ad Apache il quale la spedirà al nostro browser.
Possiamo immaginare il web server Apache, in questa architettura, semplicemente come un passa-mano:
in andata (REQUEST) riceve i parametri dal browser e li passa al server PHP
al ritorno (RESPONSE) riceve dal programma PHP il flusso HTML e la passa al nostro browser
Quindi sostanzialmente stiamo sempre facendo operazioni di lettura nel file system; le scritture vengono fatte su un DBMS.
Leggere e scrivere fisicamente sul Web
Ciò che aveva in mente Tim Berners-Lee, e che realizzò con il suo browser WWW, era una cosa profondamente diversa: le stesse risorse web dovevano essere modificabili. Quindi gli stessi file HTML contenuti nel web server! Ma questo ha un senso per un web statico in cui le pagine vengono servite al browser così come esistono nel web server. Nel cosiddetto “web dinamico” che esiste fin dalla comparsa degli script cgi-bin (quindi primi anni ’90, quando il web andava all’asilo) ciò non è più vero: non esistono pagine da servire così come sono, esistono solo programmi che producono pagine al volo sulla base dei dati di ingresso.
Quindi non ha nemmeno tanto senso il pensare di modificare le pagine, anzi: è da evitare nel modo più assoluto.
Questo approccio ha un senso quando si vuole utilizzare una infrastruttura web per pubblicare documenti statici che, tuttavia, hanno un loro ciclo di vita, possono cioè cambiare nel tempo ma in seguito ad azione di editing, di modifica da parte di uno o più utenti che sono quindi editori, gestori del contenuto di quella pagina. In quest’ottica si colloca il protocollo WebDAV che è una estensione di HTTP per questo tipo di attività.
Dunque il protocollo WebDAV realizza quanto aveva in mente Tim Berners-Lee. Ma generalmente si utilizza nelle intranet e spesso non si fa nemmeno utilizzo del browser per accedere ai contenuti, ma si impiega piuttosto un programma del tipo Finder o Esplora Risorse. La gestione dei documenti va oltre ai soli documenti HTML ma può trattarsi anche di file di testo elettronico come Word (MS Office) o Writer (LibreOffice) o PDF. La loro modifica è operata Offline, ossia modifico il documento in locale e poi lo deposito nel server andando ad alimentare la storia del documento con una nuova versione.
aggiungere, modificare e rimuovere proprietà (metadati) del file (PROPFIND, PROPPATCH)
bloccare e sbloccare (LOCK/UNLOCK) una risorsa quando si deve operare una modifica (condizione per una gestione transazionale della vita del documento – in altre parole evitiamo che più utenti mettano mano simultaneamente al documento)
cercare file (SEARCH)
Per allestire un server WebDAV occorre installare nel file server, prima di tutto, un server Web, ad esempio Apache. Poi occorre aggiungere il modulo DAV (mod_dav). Poiché i metodi di acesso DAV consentono ai client remoti di manipolare i file sul server, è necessario avere particolare cura per assicurare che il vostro server sia sicuro, prima di abiltare mod_dav.
Ogni cartella del server dove DAV è abilitato deve essere protetta da autenticazione. L’uso della HTTP Basic Authentication non è consigliata. Occorre usare almeno la HTTP Digest Authentication, che è fornita dal modulo di Apache mod_auth_digest. Quasi tutti i client WebDAV supportano questo metodo di autenticazione.
Una alternativa è la Basic Authentication sopra una connessione SSL/TLS.
Per consentire al modulo mod_dav la gestione dei file, lo User e il Group proprietari del processo UNIX che esegue Apache (nel sistema operativo Ubuntu è l’utente www-data) devono essere abilitati alla scrittura delle directory e file al disotto di queste. I nuovi file creati apparterranno all’utente User:Group. Per tale ragione è importante controllare l’accesso di questo account. Il repository DAV è considerato privato di Apache. Pertanto, la modifica di file al di fuori di Apache (ad esempio tramite FTP o comandi del sistema operativo) non dovrebbe essere permessa.
Dal PHP7 è possibile specificare il tipo di ritorno di una funzione, cioè qual è il tipo della variabile ritornata da una funzione. I tipi disponibili sono i quattro riportati nell’articolo precedente (int, string, float, bool).
// 6.php
function sum(array $array): int {
return array_sum($array);
}
$s = sum([1,2,3]);
echo gettype($s) .": ".$s . "\n";
Output:
$ php 6.php
integer: 6
A cosa ci serve dichiarare il tipo di ritorno? Per tutti i linguaggi è normale farlo e il compilatore stesso può dare indicazioni se c’è qualche incoerenza di tipo. PHP consente di farlo e il funzionamento può essere utilizzato per imporre un uso di tipi più controllato di quanto un programmatore PHP sia abituato a fare. Ad esempio possiamo definire la funzione div():
Dalla versione 7 di PHP, come visto nell’articolo precedente, abbiamo a disposizione una nuova classe che permette di gestire gli errori di tipo; in un esempio come quello sopra possiamo gestire in autonomia l’errore:
Utilizziamo tecnologie come i cookie per memorizzare e/o accedere alle informazioni del dispositivo. Lo facciamo per migliorare l'esperienza di navigazione e per mostrare annunci personalizzati. Il consenso a queste tecnologie ci consentirà di elaborare dati quali il comportamento di navigazione o gli ID univoci su questo sito. Il mancato consenso o la revoca del consenso possono influire negativamente su alcune caratteristiche e funzioni.
Funzionale
Sempre attivo
L'archiviazione tecnica o l'accesso sono strettamente necessari al fine legittimo di consentire l'uso di un servizio specifico esplicitamente richiesto dall'abbonato o dall'utente, o al solo scopo di effettuare la trasmissione di una comunicazione su una rete di comunicazione elettronica.
Preferenze
L'archiviazione tecnica o l'accesso sono necessari per lo scopo legittimo di memorizzare le preferenze che non sono richieste dall'abbonato o dall'utente.
Statistiche
L'archiviazione tecnica o l'accesso che viene utilizzato esclusivamente per scopi statistici.L'archiviazione tecnica o l'accesso che viene utilizzato esclusivamente per scopi statistici anonimi. Senza un mandato di comparizione, una conformità volontaria da parte del vostro Fornitore di Servizi Internet, o ulteriori registrazioni da parte di terzi, le informazioni memorizzate o recuperate per questo scopo da sole non possono di solito essere utilizzate per l'identificazione.
Marketing
L'archiviazione tecnica o l'accesso sono necessari per creare profili di utenti per inviare pubblicità, o per tracciare l'utente su un sito web o su diversi siti web per scopi di marketing simili.
Commenti recenti