4 strumenti per identificare un font

A chi non è mai capitato di visitare un sito e desiderare intensamente di scoprire quale font è stato utilizzato? In quest'articolo vediamo come riconoscere i font attraverso 4 utili, e sopratutto free, strumenti online!

Creare un login sicuro con PHP e MySQL pt. 1/4

Il primo di 4 articoli su come costruire un interessante forma di login in PHP e MySQL. Tema principale: la sicurezza. Codici sorgenti inclusi!

5 fondamentali API di HTML5

Forse non tutti sono a conoscenza di alcune API - Application Programing Interface - poco diffuse, ma molto utili!

Come includere CSS condizionale per IE

Affinché il nostro sito venga visualizzato correttamente anche su Internet Explorer, è necessario inserire due brevi ma fondamentali righe condizionali al nostro foglio HTML.

PHP - Individuare la lingua di chi naviga nel vostro sito

Sapevate che esiste uno snippets PHP per riconoscere automaticamente la lingua utilizzata da chi visita il vostro sito e, di conseguenza, reindirizzare automaticamente i vostri utenti?

Visualizzazione post con etichetta PHP. Mostra tutti i post
Visualizzazione post con etichetta PHP. Mostra tutti i post

giovedì 15 novembre 2012

Creare un login sicuro con PHP e MySQL pt. 4/4

Cari lettori, benvenuti nella quarta ed ultima parte di questo articolo. Vi ricordo che potete trovare la precedente parte del tutorial a questo indirizzo e, inoltre, ribadisco per l'ennesima volta il nostro intento: Il tema centrale del tutorial proposto non è tanto la grafica, che potrete ovviamente modificare e personalizzare a vostro piacimento, ma la sicurezza! Vedremo, infatti, i migliori metodi per criptare le password, per resistere ai brute force e per difenderci dalle SQL injection. In quest'ultima parte, a fine articolo, troverete il codice sorgente intero!

Il Javascript

La prima cosa sulla quale ci viene in aiuto il JavaScript è la criptazione della password. Implementeremo, infatti, l'algoritmo di hash denominato sha512 per inviare le password tra il client ed il server in maniera non leggibile. L'algoritmo sha512 può essere liberamente scaricato da pajhome.org.uk

Completato questo passaggio possiamo proseguire creando il file form.js che conterrà il seguente codice:
function formhash(form, password) {
   var p = document.createElement("input");
   form.appendChild(p);
   p.name = "p";
   p.type = "hidden"
   p.value = hex_sha512(password.value);
   password.value = "";
   form.submit();
}

L'HTML 


Tutto ciò che dobbiamo creare in HTML è un modulo con due campi di testo, denominati rispettivamente "e-mail" e "password". Il Javascript creato poc'anzi andrà, quindi, a generare un hash della password inserita nell'apposito campo.
<script type="text/javascript" src="sha512.js"></pre>
<script src="forms.js" type="text/javascript"></script>
<form action="process_login.php" method="post" name="login_form">
Email: <input name="email" type="text" /><br />
Password: <input id="password" name="password" type="password" /><br />
<input onclick="formhash(this.form, this.form.password);" type="button" value="Login" />

Proteggere le pagine private


L'ultimo, ma fondamentale, passaggio che rimane è controllare se l'utente è autenticato prima di accedere ad ogni pagina privata. Il seguente codice PHP, infatti, andrà inserito in ogni pagina che desiderate rendere privata. 
// N.B. i file da includere come functions.php e connects_db.php vanno qui!
sec_session_start();
if(login_check($mysqli) == true) {
 
   // Qui va in inserito l'intero contenuto della tua pagina protetta
 
} else {
   echo 'Spiacente, ma non sei autorizzato a visionare il contenuto di questa pagina. 
';
}

CONCLUSIONI E SORGENTI 

Prima di decretare questo articolo ufficialmente chiuso vi lascio alcune importanti considerazioni:
  • Non utilizzare mai il metodo di crittografia md5. È considerato ufficialmente non sicuro. Per maggiori informazioni vedi su wikipedia.
  • Potete ovviamente personalizzare il form di login in HTML con le dovute classi CSS
  • Potete adattare, con pochi accorgimenti, questo script ad altri tipi di database quali SQLite e PostgreSQL
Come al solito, per qualsiasi incomprensione o dubbio potete commentare questo articolo o inviarmi un email a noframe@lucapipolo.it. Infine potete effettuare da qui il download completo di tutto il codice sorgente!

mercoledì 14 novembre 2012

Creare un login sicuro con PHP e MySQL pt. 3/4

Benvenuti nella terza parte di questo articolo. Vi ricordo che potete trovare la precedente parte del tutorial a questo indirizzo e, inoltre, ribadisco nuovamente il nostro intento: Il tema centrale del tutorial proposto non è tanto la grafica, che potrete ovviamente modificare e personalizzare a vostro piacimento, ma la sicurezza! Vedremo, infatti, i migliori metodi per criptare le password, per resistere ai brute force e per difenderci dalle SQL injection. Anche in questa terza parte, a fine articolo troverete anche il codice sorgente pronto all'uso!

La pagina process_login.php

In questa pagina andremo, prima di tutto, ad inserire il codice della procedura di login che lavorerà in parallelo con la pagina functions.php. Ecco il file:
include 'db_connect.php';
include 'functions.php';
sec_session_start(); // Inizializziamo la sessione sicura 
if (isset($_POST['email'], $_POST['p'])) {
    $email    = $_POST['email'];
    $password = $_POST['p']; // Passiamo la password criptata
    if (login($email, $password, $mysqli) == true) {
        // Se il login riesce
        echo 'Hai effettuato l\'accesso!';
    } else {
        // Se il login fallisce
        header('Location: ./login.php?error=1');
    }
} else {
    // Se la variabile non viene inviata alla pagina corretta
    echo 'Richiesta non valida!';
}

La pagina logout.php

Immediatamente dopo aver creato la procedura di login, dovremmo occuparci di costruire quella per il logout. La procedura per il logout deve contenere pochi e semplici passaggi: aprire una sessione sicura, distruggerla e redirectare l'utente verso un'altra pagina. Vediamo come:
include 'functions.php';
sec_session_start();
$_SESSION = array();
// prelevo i parametri di sessione
$params   = session_get_cookie_params();
// Cancello i cookie
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
// Distruggo la sessione
session_destroy();
header('Location: ./');

La pagina di registrazione 

Il seguente è il codice che dovrete utilizzare nel caso, all'interno di una pagina di registrazione, necessitate di codificare la password.
// Raccolgo la password dal form
$password = $_POST['p']; 
// Creo un salto unico
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
$password = hash('sha512', $password.$random_salt);
 
// Aggiungo i dati raccolti alla query
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password, salt) VALUES (?, ?, ?, ?)")) {    
   $insert_stmt->bind_param('ssss', $username, $email, $password, $random_salt); 
   // Eseguo la query
   $insert_stmt->execute();
}

CONCLUSIONI E SORGENTI

Così anche la terza delle quattro parti di questo tutorial è giunta al termine. Per qualsiasi incomprensione o dubbio potete commentare questo articolo o inviarmi un email a noframe@lucapipolo.it. Potete anche scaricare tutto il codice sorgente da questo link. Alla prossima!

martedì 13 novembre 2012

Creare un login sicuro con PHP e MySQL pt. 2/4

Cari lettori, benvenuti nella seconda parte di questo articolo. Vi ricordo che potete trovare la prima parte del tutorial a questo indirizzo e, inoltre, ribadisco nuovamente il nostro intento: Il tema centrale del tutorial proposto non è tanto la grafica, che potrete ovviamente modificare e personalizzare a vostro piacimento, ma la sicurezza! Vedremo, infatti, i migliori metodi per criptare le password, per resistere ai brute force e per difenderci dalle SQL injection. Anche in questa seconda parte, a fine articolo troverete anche il codice sorgente pronto all'uso!

La pagina functions.php


Tutto il codice seguente farà parte di una pagina chiamata functions.php che conterrà, per l'appunto, tutte le funzioni che andremo poi ad includere e richiamare nelle altre pagine del nostro sito.

1. Inizializzare una sessione sicura in PHP
Prima di tutto, chiariamo uno dei concetti fondamentali sulla sicurezza delle sessioni. L'utilizzo della funzione predefinita "session_start ();" nella parte superiore di ogni pagina che si desidera rendere privata, non è sufficiente ad una sicurezza totale! Il metodo più efficace consiste, invece, nel creare una funzione chiamata "sec_session_start", che inizializzerà una sessione sicura in PHP. Anche in questo caso questa funzione andrà richiamata in ogni pagina che vorrete proteggere. Diamo un'occhiata al codice prima di procedere a commentarlo:

function sec_session_start() {
        $session_name = 'sec_session_id'; // Diamo un nome alla sessione
        $secure = false; // Impostate su true se utilizzate l'HTTPS
        $httponly = true; // Questa variabile impedisce al JS di accedere all'ID di sessione
 
        ini_set('session.use_only_cookies', 1); // Forza la sessione ad utilizzare unicamente i cookies
        $cookieParams = session_get_cookie_params(); // Preleva i parametri correnti dei cookies
        session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); 
        session_name($session_name); // Setta il nome di sessione come dalla variabile
        session_start(); // Inizializzo la sessione
        session_regenerate_id(true); // Rigenero la sessione sovrascrivendo la precedente
}
Questa funzione rende impossibile sovrascrivere l'ID della sessione tramite javascript (ad esempio nel caso di attacco XSS). Infatti la "session_regenerate_id ()" è una funzione che rigenera l'id di sessione ad ogni reload della pagina, aiutando a prevenire il dirottamento di sessione.

N.B. Se utilizzi questo codice su una pagina protetta da HTTPS la variabile '$secure' va settata su true.

2. Il login sicuro

È giunto finalmente il momento di vedere il codice della funzione che si occupa del login vero e proprio.
function login($email, $password, $mysqli)
{
    // Utilizare dichiarazioni pre-formate ci protegge dalle SQL injection 
    if ($stmt = $mysqli->prepare("SELECT id, username, password, salt FROM members WHERE email = ? LIMIT 1")) {
        $stmt->bind_param('s', $email); // Leghiamo il valore dell'email al parametro
        $stmt->execute(); // Eseguiamo la query
        $stmt->store_result();
        $stmt->bind_result($user_id, $username, $db_password, $salt); // preleviamo il risultato
        $stmt->fetch();
        $password = hash('sha512', $password . $salt); // codifichiamo la password con un codice unico
        
        if ($stmt->num_rows == 1) { // Se l'utente esiste
            // Controlliamo che l'utente non abbia effettuato troppi tentativi di accesso
            if (checkbrute($user_id, $mysqli) == true) {
                // Se l'account è bloccato
                // Inviamo un email all'account per avvertirlo
                return false;
            } else {
                if ($db_password == $password) { // Controlliamo la password
                    // Se la password è corretta
                    
                    $ip_address               = $_SERVER['REMOTE_ADDR']; // Preleviamo l'indirizzo IP dell'utente
                    $user_browser             = $_SERVER['HTTP_USER_AGENT']; // Risaliamo al browser utilizzato dall'utente
                    // Seguono i codici per la protezione XSS
                    $user_id                  = preg_replace("/[^0-9]+/", "", $user_id);
                    $_SESSION['user_id']      = $user_id;
                    $username                 = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username);
                    $_SESSION['username']     = $username;
                    $_SESSION['login_string'] = hash('sha512', $password . $ip_address . $user_browser);
                    // Login effettuato con successo
                    return true;
                } else {
                    // Se la password non è corretta
                    // Registriamo i dati del tentativo nella sessione
                    $now = time();
                    $mysqli->query("INSERT INTO login_attempts (user_id, time) VALUES ('$user_id', '$now')");
                    return false;
                }
            }
        } else {
            // Non esistono utenti
            return false;
        }
    }
}
3. Controllo dei tentativi di brute force

Il brute force, come forse saprete, è una tecnica nella quale il malintenzionato che vuole accedere all'area riservata prova migliaia e migliaia di password generate casualmente o prelevate da un dizionario attraverso un programma automatico. La nostra funzione farà si che, dopo 5 tentativi errati di login, l'utente in questione risulterà bloccato. Vediamo come:
function checkbrute($user_id, $mysqli) {
   // Preleviamo l'orario corrente
   $now = time();
   // Tutti i tentativi di login vengono immagazzinati per 2 ore dal primo tentativo 
   $valid_attempts = $now - (2 * 60 * 60); 
 
   if ($stmt = $mysqli->prepare("SELECT time FROM login_attempts WHERE user_id = ? AND time > '$valid_attempts'")) { 
      $stmt->bind_param('i', $user_id); 
      // Eseguiamo la query
      $stmt->execute();
      $stmt->store_result();
      // Se ci sono stati più di 5 tentativi
      if($stmt->num_rows > 5) {
         return true;
      } else {
         return false;
      }
   }
}
Vi ricordo che altri modi per impedire l'uso del brute force sono: inserire un test CAPTCHA oppure ritardare temporaneamente la possibilità di accedere ad ogni tentativo di login fallito.

4. Controllo dello stato di accesso

Il controllo dello stato di accesso avviene selezionando le variabili di sessione "user_id" e "login_string". La variabile "login_string" ha immagazzinato al suo interno gli IP degli utenti, le informazioni del browser e la password criptata.
function login_check($mysqli) {
   // Controllo che tutte le variabili siano state settate
   if(isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {
     $user_id = $_SESSION['user_id'];
     $login_string = $_SESSION['login_string'];
     $username = $_SESSION['username'];
     $ip_address = $_SERVER['REMOTE_ADDR']; // Prelevo l'IP dell'utente. 
     $user_browser = $_SERVER['HTTP_USER_AGENT']; // Prelevo i dati del browser
 
     if ($stmt = $mysqli->prepare("SELECT password FROM members WHERE id = ? LIMIT 1")) { 
        $stmt->bind_param('i', $user_id); // Leghiamo "$user_id" al parametro
        $stmt->execute(); // Eseguiamo la query
        $stmt->store_result();
 
        if($stmt->num_rows == 1) { // Se l'utente esiste
           $stmt->bind_result($password); // Preleviamo la variabile dal risultato
           $stmt->fetch();
           $login_check = hash('sha512', $password.$ip_address.$user_browser);
           if($login_check == $login_string) {
              // Login effettuato con successo
              return true;
           } else {
              // Altrimenti: non loggato
              return false;
           }
        } else {
            // Altrimenti: non loggato
            return false;
        }
     } else {
        // Altrimenti: non loggato
        return false;
     }
   } else {
     // Altrimenti: non loggato
     return false;
   }
}

CONCLUSIONI E SORGENTI

Così si conclude la seconda delle quattro parti di questo tutorial. Per qualsiasi incomprensione o dubbio potete commentare questo articolo o inviarmi un email a noframe@lucapipolo.it. Potete anche scaricare tutto il codice sorgente da questo link. Alla prossima!

lunedì 12 novembre 2012

Creare un login sicuro con PHP e MySQL pt. 1/4

Cari amici oggi vi propongo il primo di 4 articoli su come costruire un interessante forma di login in PHP e MySQL. Il tema centrale del tutorial proposto non è tanto la grafica, che potrete ovviamente modificare e personalizzare a vostro piacimento, ma la sicurezza! Vedremo, infatti, i migliori metodi per criptare le password, per resistere ai brute force e per difenderci dalle SQL injection. A fine articolo troverete anche il codice sorgente pronto all'uso!

Impostare il server locale

In questo primo articolo vedremo come configurare il nostro database MySQL e come effettuare una connessione sicura ad esso. Ovviamente vi ricordo, per chi non avesse praticità nel campo della programmazione client/server che, per provare le vostre pagine dinamiche in locale sul vostro pc, necessitate di PHP 5 e di MySQL 4.1.3 o successive release. Se siete utenti OSX vi rimando a questo articolo per effettuare l'installazione di XAMPP, altrimenti se utilizzate Windows, potete seguire questa semplice guida.

Configurare il database MySQL

1. Entriamo nella schermata di phpMyAdmin da uno di questi link.
N.B. Vi ricordo che per aprire la schermata di phpMyAdmin dovete avere il server XAMPP avviato! Se non sapete farlo o non lo avete ancora installato leggete la prima parte di questo articolo e seguite le guide nei link!

2. Cliccate sulla scheda SQL per accedere al pannello che ci permette di eseguire query. Vi apparirà una schermata come quella in figura


In questa casella di testo andremo ad inserire il codice per creare il nostro database:
CREATE DATABASE `secure_login` ;
Cliccate su 'esegui' per validare la query.

3. Creiamo un utente che abbia solo i permessi UPDATE, INSERT e SELECT. Questo passaggio impedirà che, nel caso un malintenzionato riesca ad accedere al vostro database MySQL, non avrà i permessi per eliminare o distruggere le vostre tabelle. Il codice per la creazione è il seguente:
CREATE USER 'sec_user'@'localhost' IDENTIFIED BY 'aZz7nmYt';
GRANT SELECT, INSERT, UPDATE ON `secure_login`.* TO 'sec_user'@'localhost';
In questo caso ho configurato i dati dell'utente in questo modo:

        username: sec_user
        password: aZz7nmYt

Ovviamente potete modificare questi dati con quelli di vostro piacimento. L'unico consiglio che vi do è quello di utilizzare password complesse. Per essere sicuri al 100% utilizzate questo generatore casuale online: http://bit.ly/TAZi5r.

4. Creiamo una tabella e denominiamola 'members'.
CREATE TABLE `secure_login`.`members` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
  `username` VARCHAR(30) NOT NULL, 
  `email` VARCHAR(50) NOT NULL, 
  `password` CHAR(128) NOT NULL, 
  `salt` CHAR(128) NOT NULL
) ENGINE = InnoDB;
Come potete vedere la tabella è formata da 5 campi: id, username, email, password e salt.

5. Creiamo una tabella per memorizzare i tentativi di login per ogni singolo utente. Questo è il modo in cui si bloccheremo i tentativi di attacchi brute force.
CREATE TABLE `secure_login`.`login_attempts` (
  `user_id` int(11) NOT NULL,
  `time` VARCHAR(30) NOT NULL 
) ENGINE=InnoDB
6. Creiamo un utente di prova in questo modo:
INSERT INTO `secure_login`.`members` VALUES(1, 'test_user', 'test@example.com', '00807432eae173f652f2064bdca1b61b290b52d40e429a7d295d76a71084aa96c0233b82f1feac45529e0726559645acaed6f3ae58a286b9f075916ebf66cacc', 'f9aab579fc1b41ed0c44fe4ecdbfcdb4cb99b9023abb241a6db833288f4eea3c02f76e0d35204a8695077dcf81932aa59006423976224be0390395bae152d4ef');
I parametri utilizzati in questo esempio sono:

        username: test_user
        email: test@example.com
        password: 6ZaxN2Vzm9NUJT2y

Creiamo la pagina di connessione al database

Creiamo la prima delle nostre pagine PHP e chiamiamola db_connect.php. Questa conterrà il codice che useremo per la connessione al nostro database mySQL. Ovviamente possiamo includere questo file su qualsiasi pagina che si desidera collegare al database. Il codice da inserire è:
define("HOST", "localhost"); // L'host al quale volete connettervi.
define("USER", "sec_user"); // L'username del database
define("PASSWORD", "aZz7nmYt"); // La password del database
define("DATABASE", "secure_login"); // Il nome del database.
 
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);

CONCLUSIONI E SORGENTI

Così si conclude la prima delle quattro parti di questo tutorial. Per qualsiasi incomprensione o dubbio potete commentare questo articolo o inviarmi un email a noframe@lucapipolo.it. Potete anche scaricare tutto il codice sorgente da questo link. Alla prossima!

venerdì 12 ottobre 2012

PHP - Individuare la lingua di chi naviga nel vostro sito


Sapevate che esiste uno snippets PHP per riconoscere automaticamente la lingua utilizzata da chi visita il vostro sito e, di conseguenza, reindirizzare automaticamente i vostri utenti?

Questo snippets può rivelarsi fondamentale nella creazione di siti multilingua, sopratutto per evitare l'utilizzo delle ormai abusate icone a bandierina.
<?php  
   $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);  
   echo $lang;  
?>  

Come possiamo vedere. il nostro selettore utilizza la funzione $_SERVER ed il parametro HTTP_ACCEPT_LANGUAGE. In pratica lo script risale automaticamente alla lingua impostata dal browser e, usando la funzione substr, isola i primi due caratteri ottenendo, così, la sigla della lingua.

Ovviamente potete usare questo codice per reindirizzare automaticamente i vostri visitatori verso la versione tradotta del vostro portale.