mercoledì 29 febbraio 2012

Smascherare il phishing

Subiamo un tentativo di phishing quando riceviamo una e-mail che:


  • pretende di arrivare da un'istituzione di qualche tipo (finanziaria, commerciale)
  • contiene un link fasullo che ci porta su un sito sul quale ci viene chiesto di inserire qualche dato privato (ad esempio: una username e una password)


Normalmente queste mail sono studiate per catturare la nostra attenzione, dicendo ad esempio che il nostro account di banca, carta di credito, o altre forme di pagamento è stato bloccato, per cui "è urgente" fare qualcosa, cioè clickare sul link fasullo.

Una volta clickato il link, arriviamo su una pagina di un sito costruito per "sembrare" il sito dell'istituzione, ci viene chiesto di inserire la nostra password e il gioco è fatto: così rubano le password di accesso, che useranno in seguito per azioni fraudolente.

Fortunatamente è facile smascherare un tale tentativo di phishing. Ecco come.

Questa di seguito è l'immagine di un'e-mail di phishing:



Gli elementi ci sono tutti:


  •  la mail sostiene che "qualcosa di grave è successo": è stato "bloccato" l'account della carta di credito
  • c'è un link per "fare qualcosa per aggiustare la situazione"


Primo indizio - le banche non mandano e-mail
Nessuna istituzione seria (banche, carte di credito, siti commerciali) ci invierà mai una mail che contiene il link ad un sito. Proprio per evitare tentativi di phishing, tutte le mail che riceviamo da enti seri, non contengono link. Casomai l'invito a collegarsi autonomamente al loro sito. Ma, in generale, nessuna mail NON RICHIESTA ci verrà mai inviata.

Secondo indizio - orrori ortografici
Tutte le e-mail di phishing contengono orripilanti errori di italiano, perchè normalmente sono la "traduzione automatica" di analoghe e-mail in inglese. Leggiamo attentamente: 'Si prega di non utilizzare il link all'interno di questa e-mail a ripristinare un altro conto di quanto il tuo' oppure 'Si prega di seguire attentamente le nostre indicazioni e sarà in grado di ripristinare l'accesso al conto in pochi minuti'...

Terzo indizio - link fasulli
Come funziona il phishing? Cercando di portare la persona su un sito che "finge" di essere ciò che non è. E' facile in HTML dire che un link porta da una parte, quando invece porta da un'altra. Però è anche facile capirlo: basta posizionare il mouse sul link stesso per controllare che il link porti veramente dove dice di voler portare: la freccia in verde indica "dove" il link finge di volerci portare (su www.cartasi.it) e quella in blu dove ci porta veramente (su wiki.tenfor..com)



Quarto indizio - sender fasullo
Lo stesso giochetto viene applicato al sender della mail. La mail dice di essere stata spedita da CartaSi S.p.A. Ma se guardiamo bene nei dettagli scopriamo che invece è stata spedita da e-vendax.pop.com.br


Normalmente, in un tentativo di phishing questi indizi sono sempre presenti. Ovviamente: mai clickare sul link, e men che mai inserire informazioni personali (come username, password e numero conti) su siti che non abbiamo raggiunto "volontariamente" - ad esempio partendo da un bookmark del browser.

Cosa fare, infine quando si riceve una e-mail di phishing? Sicuramente segnalarlo al provider, in questo caso GMail:




Inoltre, è sempre possibile avvisare dell'avvenuto tentativo di truffa la sezione locale della Polizia Postale, che in Italia si occupa anche di reati informatici.

giovedì 23 febbraio 2012

Pensare in REST (Thinking in REST)

La progettazione di applicazioni Web based ha subìto una silenziosa rivoluzione quando nel 2000 Roy Fielding ha pubblicato la sua ormai celebre dissertazione dal titolo: "Architectural Styles and the Design of Network-based Software Architectures", e in particolare il capitolo cinque: "Representational State Transfer (REST)".

In cosa consiste questa rivoluzione? Esiste una modalità, diciamo così, "classica" di concepire un'applicazione per computer, e questa prevede la composizione di un algoritmo più o meno complesso che prende in input una serie di dati, li trasforma e poi li rende persistenti - ad esempio salvandoli su un database. L'essere umano interagisce con l'applicazione attraverso una "interfaccia utente" che viene aggiornata a seconda del cambiamento di stato - o dell'input o dell'output. Così, in modo appunto "classico", un'applicazione è costituita di un'interfaccia utente, una logica, e uno stato - cioè dei dati persistenti.

Le prime applicazioni Web complesse, rese possibili dalle primigenie tecnologie di trasformazione dinamica dell'HTML, lato server con ASP o PHP ad esempio e lato client con DOM/Javascript, implementavano questo modello classico. Vale a dire, presentavano all'utente un'interfaccia grafica con la quale inserire i dati, offrivano una serie di comandi associati a una logica di esecuzione, e infine persistevano i risultati su un database.

Il problema di questo approccio è che l'applicazione diventa un monolite che si può utilizzare solamente nel modo in cui è stata inizialmente concepita.

Con l'aumentare delle necessità di servizi Web, con l'aumentare dei device eterogenei che vi accedono - dai computer ai telefonini, dai videogiochi alle lavastoviglie - questo tipo di approccio è diventato controproducente: l'applicazione monolitica impedisce di utilizzare i dati e le informazioni che è in grado di veicolare appunto perché è concepita per essere utilizzata in un solo modo, che è quello inizialmente concepito dai suoi autori. La conseguenza di tutto ciò è che ogni nuova esigenza di accedere ad un dato o ad un servizio veicolato dall'applicazione necessita di un cambiamento nel codice applicativo o, peggio, nella creazione di una nuova applicazione ad hoc.

Oggi le aziende spendono moltissime risorse IT proprio perché hanno a che fare con applicazioni monolitiche che non riescono a "servire" il dato in maniera abbastanza neutra.

L'idea alla base del protocollo REST inventato da Roy Fielding è che le applicazioni Web devono essere progettate in modo tale per cui immettendo direttamente le URL (che così diventano URI) su un browser si ottengano immediatamente i dati che servono, e che queste URL possano essere "combinate" tra loro in un workflow per ottenere un'applicazione, allo stesso modo con cui nelle architetture SOA noi combiniamo i "servizi" per ottenere sempre nuove applicazioni.

La URL così richiamata deve essere in grado di rispondere in formato "neutro", possibilmente veicolando solamente "i dati", senza cioè alcuna informazione "grafica" di supporto. Le URL stesse devono specificare il formato dei dati che richiedono: se la URL finisce per ".xml" il dato verrà restituito in XML, per ".json" in JSON, e, naturalmente, di default rispondere con un HTML human readable.

Per finire un esempio. Supponiamo di scrivere un videogioco Web, magari per Facebook. Avremo da qualche parte una struttura dati che prende tutte le informazioni relative al giocatore (Player). Questa struttura dati raccoglie e persiste lo "stato" del giocatore durante il gioco. La modalità classica consiste nello scrivere un'applicazione che, a seconda dei comandi dati via web dal giocatore, cambia lo stato e aggiorna di conseguenza la tabella "Player". Esagerando, l'applicazione potrebbe essere costituita da un'unica "pagina" che, a seconda del comando HTTP ricevuto, risponde in un modo o in un altro. Ovviamente, così facendo, nessuno, ad esempio, potrebbe costruire un altro gioco a partire dai dati correnti dei giocatori: perché le informazioni di stato dei giocatori sono "chiuse", e utilizzabili solo dalla "pagina" di cui parlavamo prima.

Se volessimo applicare il protocollo REST all'entità "Giocatore" (Player), come prima cosa dovremmo definire le "URL" che accedono a ciascuna informazione del giocatore, e le URL che vanno a modificare lo stato del giocatore stesso. Ad esempio:

GET    /player/list(.:format)        player#list
POST   /player/list(.:format)        player#list
GET    /player(.:format)             player#index
POST   /player(.:format)             player#create
GET    /player/new(.:format)         player#new
GET    /player/:id/edit(.:format)    player#edit
GET    /player/:id(.:format)         player#show
PUT    /player/:id(.:format)         player#update
DELETE /player/:id(.:format)         player#destroy

Questa tabella fornisce un verbo HTTP e una URL associata. Queste URL, se chiamate con il rispettivo verbo HTTP, sono già in grado di descrivere le funzionalità di base con cui l'utente può ottenere le informazioni sui giocatori! La prima fornisce una lista dei giocatori, la seconda modifica la lista, la terza ottiene informazioni generiche, la quarta e la quinta inseriscono nuovi giocatori, la sesta permette di modificare i dati di uno specifico giocatore e via dicendo...

Se chiamo /player/list ottengo una pagina HTML, /player/list.json un array di giocatori, /player/list.xml un documento XML. Applicazioni sempre diverse accedono agli stessi dati in maniera omogenea. In questo modo, se l'applicazione è ben scritta, sarà sempre possibile immaginare nuovi modi per accedere ai dati, e produrre applicazioni nuove senza dover modificare il codice lato server.

Chiaramente, progettare un'architettura Web in modalità REST comporta un ribaltamento del modo di pensare: invece che partire dalle esigenze "funzionali", bisogna partire dai dati, e dal modo con cui si può manipolarli. Ma il vantaggio di farlo fin dall'inizio, con disciplina, produrrà significativi risparmi nella gestione evolutiva dell'applicazione, e darà l'opportunità di costruire nuovi modi d'uso di applicazioni esistenti praticamente senza sforzo.

Oggi esistono molti framework che producono applicazioni Web RESTful. Il più famoso è "Ruby On Rails". Seguono "Bowler" per Scala, "Jersey" per Java. E molti altri stanno nascendo.


martedì 24 gennaio 2012

Interoperabilità tra Scala e Java

Scala è interoperabile con Java, poiché entrambi i linguaggi producono Java bytecode. Questo significa che tutte le seguenti frasi sono vere:
  • Codice Scala può essere eseguito da una Java Virtual Machine
  • Codice Java può essere "visto" da codice Scala
  • Codice Scala può esserre "visto" da codice Java
Supponiamo di avere ad esempio la seguente classe di business in Scala, una generica struttura che rappresenta l'astrazione di un numero razionale. E' costruita passando numeratore e denominatore, ad esempio Rational(2,3) è due terzi (2/3).
 package net.alessiosaltarin.rationals  
   
 class Rational(n: Int, d: Int) {  
   require(d != 0)  
   
   private val g = this.gcd(n.abs, d.abs)  
   val numer: Int = (n / g)  
   val denom: Int = (d / g)  
   println("Created " + this.toString())  
   
   def this(n: Int) = this(n, 1)  
   
   override def toString = this.numer + "/" + this.denom  
   
   def +(that: Rational): Rational =  
     new Rational(  
       this.numer * that.denom + that.numer * this.denom,  
       this.denom * that.denom)  
   
   def *(that: Rational): Rational =  
     new Rational(this.numer * that.numer, this.denom * that.denom)  
   
   private def gcd(a: Int, b: Int): Int =  
     if (b == 0) a else gcd(b, a % b)  
 }  
   
 object RationalComputer {  
   
   def performSum(r1: Rational, r2: Rational): String =  
     (r1 + r2).toString()  
   
   def performMultiply(r1: Rational, r2: Rational): String =  
     (r1 * r2).toString()  
   
 }  
   
 object RationalFactory {  
   
   def create(rationalStr: String): Rational =  
     {  
       val indexOfSlash = rationalStr indexOf '/'  
       val n = nrParse(rationalStr.substring(0, indexOfSlash))  
       val d = nrParse(rationalStr.substring(indexOfSlash + 1))  
       new Rational(n, d)  
     }  
   
   private def nrParse(nstr: String): Integer = Integer.parseInt(nstr)  
 }  
Se vogliamo offrire a questo codice una user interface, che non sia Web, abbiamo ben poche possibilità, se vogliamo rimanere nell'ambito di Scala, e cioè quelle di usare il wrapping delle librerie Swing scritto in Scala, vale a dire: http://www.scala-lang.org/api/current/scala/swing/package.html Il problema di questo approccio è che alla data di questo post manca totalmente un editor visuale che generi in output un codice Scala. Quello che abbiamo, invece, sono degli editor visuali che generano codice Swing in Java, ad esempio:
  • Netbeans Matisse
  • Eclipse Visual Editor
La buona notizia è che, stanti le premesse di cui sopra, codice Scala può essere visto da Java come se fosse una "libreria" esterna (e viceversa, tra l'altro). Possiamo infatti pensare di realizzare un'interfaccia di questo tipo:
attraverso l'editor visuale che preferiamo, generare il codice Java equivalente, e poi eseguirlo. Per farlo possiamo seguire due approcci, entrambi validi: eseguire dalla macchina virtuale Scala il codice Scala e il codice Java interpretarlo come bytecode esterno, oppure eseguire da una qualsiasi macchina virtuale Java il codice dell'interfaccia grafica e da questo richiamare il bytecode compilato da Scala come una libreria esterna. Chiaramente, è il secondo approccio quello più interessante. Infatti nella pratica avremo a disposizione macchine virtuali Java, ottimizzate a seconda dell'uso. Perché questo approccio sia percorribile, occorre costruirsi un proxy Java in grado di richiamare il codice di business in Scala. Il proxy conterrà i metodi richiamati direttamente dall'interfaccia - nell'esempio, il pulsante di 'esegui operazione'. Ad esempio:
 package net.alessiosaltarin.javaproxy;  
   
 import net.alessiosaltarin.rationals.Rational;  
 import net.alessiosaltarin.rationals.RationalFactory;  
 import net.alessiosaltarin.rationals.RationalComputer;  
   
 public class ProxyLogic  
 {  
   public static String performOperation(Operation op,   
                           String rationalOne,   
                           String rationalTwo)  
   {  
     Rational r1 = RationalFactory.create(rationalOne);  
     Rational r2 = RationalFactory.create(rationalTwo);  
     String result;  
       
     switch (op)  
     {  
          case ADD:  
          default:  
               result = RationalComputer.performSum(r1, r2);  
               break;  
                 
          case SUBTRACT:  
               throw new UnsupportedOperationException();  
                 
          case MULTIPLY:  
               result = RationalComputer.performMultiply(r1, r2);  
               break;  
                 
          case DIVIDE:  
               throw new UnsupportedOperationException();  
     }  
       
     return result;  
   }    
 }  
Il codice sopra richiama il codice Scala - il namespace
net.alessiosaltarin.rationals.Rational
Come fa? Semplicemente lo trova nel percorso del codice compilato come Java bytecode, a patto di avere la libreria Scala
scala-library.jar
nel classpath corrente. Supponendo che la classe RationalGUI sia quella generata dal tool visuale, il codice eterogeneo Scala/Java verrà eseguito dalla JVM in questo modo:
java -cp scala-library.jar;[jre,...] net.alessiosaltarin.javaproxy.RationalGUI
Utilizzando ad esempio Eclipse, è possibile aprire due progetti, uno in Scala e uno in Java, e in quello Java che contiene il metodo main, referenziare come libreria esterna il codice Scala custom e la libreria scala-library.jar.

venerdì 30 dicembre 2011

Il negozio di scarpe di mio nonno



"Io appartengo a una grande azienda che produce scarpe..." disse l'ingegner Carozzi. "In questi tempi di crisi, l'azienda sta andando molto male, e sta cominciando a licenziare. Io mi guardo intorno, e credo di aver capito perchè l'azienda in cui lavoro sta fallendo: è perché noi siamo dei bravi venditori, siamo degli ottimi manager, ma non ci capiamo un gran che di scarpe! Anzi, nelle riunioni aziendali si sente spesso dire con una punta di orgoglio dai nostri capi che loro non ci capiscono molto di scarpe, del resto loro sono bravi dirigenti, bravi venditori, non importa che vendano scarpe oppure lustrini natalizi. Non importerà, d'accordo, intanto però l'azienda sta fallendo." L'ingegner Carozzi si scostò un attimo per accendersi la pipa. Fuori stava cominciando a nevicare. "Io dico queste cose con cognizione di causa, sapete." Fece una pausa di riflessione, poi continuò: "Mio nonno aveva un negozio di calzature in centro. Il suo negozio era sempre pieno di gente! E tutti erano molto sorpresi che il negozio di mio nonno fosse sempre pieno. Perché dovete sapere che mio nonno aveva un carattere difficile, era un burbero, un uomo molto pragmatico, era l'esatto contrario di un buon venditore. Lui era capace di dire a un cliente che aveva messo gli occhi su una scarpa molto costosa, che quella scarpa non era per lui, di lasciar perdere, di uscire dal negozio e risparmiare i suoi soldi. Il negozio di scarpe di mio nonno era sempre pieno perché la gente sapeva che quell'uomo burbero era davvero un intenditore di scarpe! Questo perché prima di essere un negoziante era stato un calzolaio. La gente sapeva che quando andava da lui poteva chiedere un consiglio sulla scarpa adatta a lui, e ricevere una risposta del tutto sincera e competente. La gente in quegli anni doveva risparmiare su tutto: non poteva permettersi un acquisto sbagliato! E sapeva che mio nonno gli avrebbe venduto la scarpa giusta. E il suo negozio era sempre pieno! Nonostante lui fosse un burbero, avesse un carattere difficile e non fosse tagliato per il mestiere di commerciante." L'ingegner Carozzi si voltò verso i suoi interlocutori, sorrise loro con un sorriso amaro, poi si voltò e se ne andò per la sua strada.

mercoledì 31 agosto 2011

Navigazione e geolocalizzazione

Sono a P., una città a me sconosciuta, per un meeting. Ho bisogno di una farmacia - mi sono dimenticato le aspirine a casa! Fortunatamente ho con me il mio cellulare Android. Ecco cosa faccio:

1) Apro Google. Siccome ho attivato il geolocalizzatore, la pagina visualizzata riporta chiaramente che mi trovo a P.
2) Seleziono Places
3) Da lì digito "Farmacia". Appare un elenco delle farmacie, in ordine di vicinanza.
4) Scelgo la prima e visualizzo la mappa, con le informazioni in tempo reale del traffico.
5) Ok, il traffico è leggero. Maps mi dice che ci arriverò in cinque minuti in macchina e in nove minuti a piedi! Sono in macchina, ci vado in macchina.
6) Clicko sul Navigatore, che immediatamente attiva il GPS. La voce di una signorina, in bell'italiano, mi racconta la strada da fare, nominando anche le vie.

Il tutto con un Android senza nessuno speciale software a pagamento, con una configurazione "out-of-the-box". Niente male!

Il prossimo passo è andare in un supermercato, fare la spesa, e uscire senza pagare alla cassa - ma ritrovandosi il conto esatto addebitato sulla carta di credito. (Il che non è propriamente fantascienza...)

venerdì 24 giugno 2011

Fammi ripetere con parole mie

Come Software Architect, la lezione più preziosa è stata imparare che io e lo sponsor del progetto - o meglio, si dovrebbe dire gli stakeholder - parliamo lingue differenti.

Abbiamo del resto una formazione differente, esperienze differenti, e significative difformità nei punti di vista.

Per questo la chiave del successo di un progetto software, oggi, è la chiarezza di comunicazione tra chi fornisce la tecnologia - l'Architect, appunto - e chi intende utilizzarla per raggiungere i suoi scopi di business.

Ecco perché è fondamentale che l'Architect si chieda sempre: ho capito quali sono gli obiettivi di questo progetto? Esiste uno strumento formidabile: dopo aver letto un documento, aver partecipato a una riunione, avere ascoltato le parole degli stakeholder, fermarsi un attimo e dire: "Ok, ora fammi ripetere con parole mie". Vediamo cosa ho capito davvero.

Altrettando fondamentale è chiarire fin dall'inizio che cosa la tecnologia può offrire, e che cosa non può offrire. E' bene fin da subito spianare il campo da miti e leggende. (E lo so che è difficile: è bello all'inizio avere uno sponsor che ci guarda come Bilbo Baggins guardava Gandalf nello Hobbit!)

Direi quindi che sono due le chiavi importanti per il successo di un progetto software enterprise:

1) Voglio capire bene quali sono gli obiettivi da ottenere con il sistema
2) Voglio comunicare bene cosa un sistema è in grado di offrire (e cosa no)

Le questioni tecniche, i disegni architetturali, i dettagli implementativi vengono molto dopo.

venerdì 17 giugno 2011

Basta Database!

Una domanda che non fareste mai ad un Cliente, che ha un sistema informativo con un suo potentissimo sistema di RDBMS (database relazionale, normalmente Oracle o MS Sql Server), è: "Ok, ma a cosa ti serve?"

Come a cosa serve un database? (Ti guardano come un poveretto, con tanto di occhi sgranati)... Ma non lo sai che in un database ci sono tutti i dati aziendali? Ma non lo sai che è il cuore del sistema informatico? Ma non lo sai che nessuno nemmeno osa pensare di non averne uno...

Mentre sento queste cose mi aggiro curioso tra gli utenti (solitamente disperati) di un tale eccellente sistema: sono lì che combattono con infinite tabelle, piene di dati ridondanti e infinitamente inutili, che per essere tirati fuori hanno bisogno di uno stranissimo linguaggio, perlopiù incomprensibile alle logiche umane, chiamato SQL.

La maggior parte delle aziende, per cercare di tirar fuori qualcosa da quei mostri lì, compra sistemi di Datawarehouse e Business Intelligence che costano loro un ordine di grandezza in più...

Mi aggiro tra sistemisti che sognano vacanze ai Caraibi e mondi senza computer - soprattutto senza database - e tra manager che guardano fuori dalla finestra cercando di capire con quali soldi pagare l'espertone Oracle (o quello che volete) che gli risolverà il loro maggior problema, e cioè: perché ho milioni di dati inutili e non trovo mai quelli che mi servono?

A cosa serve un database? "Ad archiviare i dati". Sono scettico. "A gestire le transazioni..." ok, ci avviciniamo. "Ad estrarre dai miei dati le informazioni che servono per il mio business..." Ah no! Ecco il punto!

Il punto è che la tecnologia delle basi di dati è nata quando i computer erano relativamente lenti, soprattutto i dischi, poco capienti e le applicazioni molto costose da scrivere, perché difficili da creare e debuggare. Perciò si è inventato un sistema altamente efficace nell'archiviare i dati (scrittura) e nel recuperarli (lettura), e questo a scapito della loro intelligibilità e facilità d'uso.

Il sistema relazionale inventato da Cobb è un sistema efficace con computer poco potenti e capienti, esattamente il contrario dei computer di cui disponiamo oggi.

Oggi possiamo tranquillamente immaginare (e realizzare!) un sistema informativo complesso senza database sotto. "E come fai ad archiviare i tuoi dati?" Li scrivo sul disco, ovvio. Sì ma in che formato?

Ecco una buona domanda. Le cui risposte possono essere almeno tre, e ricoprire con ciò gran parte delle necessità di archiviazione di un'applicazione anche di media/grande complessità.

Prima possibilità: flat file. Salviamo tutti i nostri dati in file di testo in formato flat. Esempi: il win.ini, YAML, SQLite, TextDB ecc. ecc. (http://en.wikipedia.org/wiki/Flat_file_database)

Seconda possibilità: chi ha necessità di immagazzinare relazioni gerarchiche di tipo padre-figlio, o strutture fortemente innestate, può usare il formato di testo più potente in assoluto: XML. Il che è però fin troppo per la stragrande maggioranza delle applicazioni.

Terza possibilità: ok, proprio non potete fare a meno di Oracle! Almeno lasciatelo scrivere a chi lo sa fare, e voi non sporcatevi le mani. Utilizzate dunque uno strumento di ORM - object relational mapping - che ha il compito di serializzare, deserializzare e ricercare i vostri oggetti di business in un normale database relazionale.

Quest'ultima possibilità è quella secondo me più interessante, e che spero prenda piede nelle applicazioni enterprise del prossimo lustro. L'articolo che più concisamente descrive la tecnica è questo.
Seguito dall'ottima voce su Wikipedia.

In soldoni, nelle applicazioni moderne, le attività di DDL (Data Definition Language) e DML (Data Manipulation Language) debbono essere demandate ad un apposito strato software (l'ORM appunto) che le svolge al meglio e in modo "trasparente" per l'utente. In questo caso ciò che conta maggiormente nell'applicativo non è più il modello concettuale dei dati, ma il modello concettuale degli oggetti (sottinteso, di business, cioè a dire: web services, remote procedure calls e quant'altro). Il vantaggio consiste, di fatto, nella drastica diminuzione delle risorse necessarie al disegno e allo sviluppo della base dati - fino quasi ad annullarle.

Per Java, il miglior strumento ORM è senz'altro Hibernate, mentre per il mondo Microsoft è l'Entity Framework

Entrambi sono ottimi punti di partenza per dire definitivamente addio agli odiati database.