PDA

View Full Version : [PHP] sicurezza form, sessioni, referer


Gremo
04-09-2005, 22:18
ciao a tutti :)
per un esame sto approfondendo php. mi interessa particolarmente la sicurezza dei form e l'integrità dei databse, quindi vi chiedo:

1) le sessioni sono sicure?ho visto che firefox ad esempio memorizza l'id di sessione in un cookie, ma in teoria le sessioni sono file di testo lato server, giusto?quindi nessun problema con browser vecchi o che non accettano cookie?risultano quindi sicure al 100% per memorizzare dati importanti?

2) $_SERVER['HTTP_REFERER']: lo uso per controllare che il form da cui provengono i dati "risiede" nel mio sito...ma ho letto che è possibile imbrogliare, se si come?con che difficoltà?

qualche trucchetto per aumentare la sicurezza dei form o basta il referer e le sessioni?

Gremo
04-09-2005, 23:08
ok, il referer può essere facilmente spoofato...come tutelarsi? qualche idea su su che io sono alle prime armi :D

Ste_000
05-09-2005, 11:25
al posto del referer io userei tranquillamente le sessioni ...ne imposti una nelle pagine che ti servono e poi controlli la sessione quando apri un'altra pagina !...oppure memorizzi nella sessione il path dello script e controlli sia uguale :)

Gremo
05-09-2005, 16:12
al posto del referer io userei tranquillamente le sessioni ...ne imposti una nelle pagine che ti servono e poi controlli la sessione quando apri un'altra pagina !...oppure memorizzi nella sessione il path dello script e controlli sia uguale :)

mhm...mi sai che ho trovato il modo di "fregare" la mia sessione che controlla i dati del form...

qualche altra idea??su questo forum non erano tutti "programmatori"? :rolleyes:

cionci
05-09-2005, 16:27
ciao a tutti :)
per un esame sto approfondendo php. mi interessa particolarmente la sicurezza dei form e l'integrità dei databse, quindi vi chiedo:

1) le sessioni sono sicure?ho visto che firefox ad esempio memorizza l'id di sessione in un cookie, ma in teoria le sessioni sono file di testo lato server, giusto?quindi nessun problema con browser vecchi o che non accettano cookie?risultano quindi sicure al 100% per memorizzare dati importanti?

2) $_SERVER['HTTP_REFERER']: lo uso per controllare che il form da cui provengono i dati "risiede" nel mio sito...ma ho letto che è possibile imbrogliare, se si come?con che difficoltà?

qualche trucchetto per aumentare la sicurezza dei form o basta il referer e le sessioni?
1) le sessioni sono sicure se non si conosce l'id di sessione, se si conosce (visto che circola in chiaro ad ogni richiesta verso il server), si può tranquillamente imbrogliare...
Se un browser non supporta i cookie, l'id viene progagato automaticamente dal server nelle richieste GET...

2) Anche il REFERER è una informazione in chiaro che passa nella richiesta HTTP e viene generato dal browser...con una richiesta ad hoc scritta "a mano" (non necessariamente, ma acnhe tramite un programma) si può tranquillamente imbrogliare.

Puoi controllare l'ip e salvarlo nella sessione... Questo ti può servire... Esiste anche lo spoofing (ovvero imbrogliare sulla sorgente dei pacchetti con pacchetti IP fatti ad hoc), ma in ogni caso, a meno che chi fa lo spoofing "stia nel mezzo" fra client e server e faccia uno sniffing dei pacchetti di ritorno, è una comunicazione solo verso il server...
Il problema dello spoofing si può quindi aggirare con sistemi di controllo post autenticazione... Facendo l'esempio di un e-commerce prima della conferma d'ordine basterebbe chiedere un codice alfanumerico sempre diverso visualizzato all'interno di una immagine (un po' come fanno in molti forum, lo puoi realizzare con le librerie gd)... Questo evita anche problemi relativi a bot, a meno che non abbiano un sistema di analisi delle immagini per ricavarne il testo...in tal caso basta rendere l'immagine più confusa (con linee orizzonatali, verticali e oblique casuali o con font casuali)...

Un sistema del genere può essere molto valido sotto tanti punti di vista, ma non per la sicurezza dei contenuti (esiste sempre lo sniffing)...per quello si è obbligati ad usare un canale criptato, che risolve anche molti dei precedenti problemi, ma ne apre altri...come ad esempio quelli relativi alle certification authority ed alla distribuzione delle chiavi... Dieffie-Hellman rulez

Come puoi vedere non è una cosa così semplice ;)

cionci
05-09-2005, 16:29
qualche altra idea??su questo forum non erano tutti "programmatori"? :rolleyes:
Se avessi visto prima questo post non avrei postato... :rolleyes:
E te sei un programmatore ? Allora perchè non sai queste cose (che tra l'altro non riguardano la programmazione)...

Gremo
05-09-2005, 16:41
1) le sessioni sono sicure se non si conosce l'id di sessione, se si conosce (visto che circola in chiaro ad ogni richiesta verso il server), si può tranquillamente imbrogliare...
Se un browser non supporta i cookie, l'id viene progagato automaticamente dal server nelle richieste GET...


grazie per la lunga risposta :)
la mia intezione era discutere seriamente la questione.

SESSIONI: sarò io che ho progettato male la struttura delle pagine ma, in breve:
pagina input.php con form (action se stessa).
1)quando l'utente invia il form, la pagina lo valida
2)se è valido setta $_SESSION['form_valido']=TRUE;
3)mostra un nuovo piccolo form di conferma ("processa.php")
4)ovviamente i dati sono questa volta input nascosti

pagina processa.php

if(isset($_POST['conferma']) && isset($_SESSION['form_valido'])) {
//inserisci nel db, i dati sono validi
}



non va bene. se si usa ad esempio opera (non ie) basta fare così...
1)inserire input corretti nel primo form (senza confermarne l'invio alla pagina processa.php)
2)salvare la pagina, cambiare gli input nascosti in input questa volta non validi
3)inviare il form così modificato.

per opera infatti, 2 tab rappresentano la stessa sessione. quindi, la pagina salvata su hd con input non validi sarà accettata ugualmente, perchè il punto 1 ha fatto scrivere nella sessione il valore 'form_valido' = TRUE
che ne pensi?


2) Anche il REFERER è una informazione in chiaro che passa nella richiesta HTTP e viene generato dal browser...con una richiesta ad hoc scritta "a mano" (non necessariamente, ma acnhe tramite un programma) si può tranquillamente imbrogliare.

ho letto che anche con telnet è possibile imbrogliare, quindi non prendo in considerazione il fatto di controllare il referer


Puoi controllare l'ip e salvarlo nella sessione... Questo ti può servire... Esiste anche lo spoofing (ovvero imbrogliare sulla sorgente dei pacchetti con pacchetti IP fatti ad hoc), ma in ogni caso, a meno che chi fa lo spoofing "stia nel mezzo" fra client e server e faccia uno sniffing dei pacchetti di ritorno, è una comunicazione solo verso il server...
Il problema dello spoofing si può quindi aggirare con sistemi di controllo post autenticazione... Facendo l'esempio di un e-commerce prima della conferma d'ordine basterebbe chiedere un codice alfanumerico sempre diverso visualizzato all'interno di una immagine (un po' come fanno in molti forum, lo puoi realizzare con le librerie gd)... Questo evita anche problemi relativi a bot, a meno che non abbiano un sistema di analisi delle immagini per ricavarne il testo...in tal caso basta rendere l'immagine più confusa (con linee orizzonatali, verticali e oblique casuali o con font casuali)...

Un sistema del genere può essere molto valido sotto tanti punti di vista, ma non per la sicurezza dei contenuti (esiste sempre lo sniffing)...per quello si è obbligati ad usare un canale criptato, che risolve anche molti dei precedenti problemi, ma ne apre altri...come ad esempio quelli relativi alle certification authority ed alla distribuzione delle chiavi... Dieffie-Hellman rulez

Come puoi vedere non è una cosa così semplice ;)


non saprei neppure dove cominciare

Gremo
05-09-2005, 16:43
Se avessi visto prima questo post non avrei postato... :rolleyes:
E te sei un programmatore ? Allora perchè non sai queste cose (che tra l'altro non riguardano la programmazione)...

era una piccola provocazione suvvia :D
possibile che non si siano mai affrontati questi temi, e che a nessuno importi?

cionci
05-09-2005, 17:05
grazie per la lunga risposta :)
la mia intezione era discutere seriamente la questione.

SESSIONI: sarò io che ho progettato male la struttura delle pagine ma, in breve:
pagina input.php con form (action se stessa).
1)quando l'utente invia il form, la pagina lo valida
2)se è valido setta $_SESSION['form_valido']=TRUE;
3)mostra un nuovo piccolo form di conferma ("processa.php")
4)ovviamente i dati sono questa volta input nascosti

pagina processa.php

if(isset($_POST['conferma']) && isset($_SESSION['form_valido'])) {
//inserisci nel db, i dati sono validi
}



non va bene. se si usa ad esempio opera (non ie) basta fare così...
1)inserire input corretti nel primo form (senza confermarne l'invio alla pagina processa.php)
2)salvare la pagina, cambiare gli input nascosti in input questa volta non validi
3)inviare il form così modificato.

per opera infatti, 2 tab rappresentano la stessa sessione. quindi, la pagina salvata su hd con input non validi sarà accettata ugualmente, perchè il punto 1 ha fatto scrivere nella sessione il valore 'form_valido' = TRUE
che ne pensi?

Salva i dati inviati della form non come input nascosti, ma come variabili di sessione...

Ad esempio:

In ogni pagina di risposta ad una form metti:

if($_SESSION["CONFERMA"] == 1)
{
//sei nella pagina che inserisce i dati nel database
$_SESSION["CONFERMA"] = 0;
//inserisci i dati nel database
}
else
{
$_SESSION["CONFERMA"] = 0;
//controlla i dati della form
if(dati validi)
{
//inserisci nelal sessione i dati inviati tramite la form
$_SESSION["Var1"] = $_POST["Var1"];
$_SESSION["Var2"] = $_POST["Var2"];
$_SESSION["Var3"] = $_POST["Var3"];
$_SESSION["Var4"] = $_POST["Var4"];

.....

$_SESSION["CONFERMA"] = 1;
//visualizza la pagina di conferma che tramite un pulsante andrà
//a richiamare questa stessa pagina senza paramtri (comunque senza i
//parametri della form
}
}


ho letto che anche con telnet è possibile imbrogliare, quindi non prendo in considerazione il fatto di controllare il referer
Telnet può fare tutto e niente... E' semplicemente un input di testo che viene inviato su una porta remota... La stessa cosa la puoi fare da php o da qualsisi linguaggio minimamente evoluto...
non saprei neppure dove cominciare
Comincia inanzi tutto dalle librerie GD per creare l'immagine...
Il testo (estratto casualmente) visualizzato nell'immagine devi salvarlo nella sessione al momento della visualizzazione dell'immagine...
Tramite una form l'utente nella stessa pagina dovrà inserire il codice che vede scritto nell'immagine per confermare l'operazione... Ovviamente tu verificherai il testo inserito confrontando con quello salvato nella sessione, se l'esito è positivo effettui la scrittura nel DB...
Comunque attento questo sistema abbassa l'usabilità del sito, quindi mettila soltanto nei punti critici (ad esempio per la conferma di un ordine e non per l'inserimenti di un prodotto nel carrello)...

Riguardo al controllo dell'ip...ti emtte tutto a disposizione PHP... Invece che $_SERVER["REFERER"] puoi controllare $_SERVER["REMOTE_ADDR"] (se mi ricordo bene), che è l'indirizzo IP del client... Puoi anche controllarli entrambi... Se proprio vuoi amssimizzare la sicurezza...

Riguardo alla connessione criptata...dipende tutto dal server web che deve prevederla... In tal caso non ci sono problemi...dal tuo punto di vista non cambia niente...

cionci
05-09-2005, 17:08
Anche questo ti dovrebbe interessare: http://freephp.html.it/articoli/view_articolo.asp?id=123

Gremo
05-09-2005, 17:19
Anche questo ti dovrebbe interessare: http://freephp.html.it/articoli/view_articolo.asp?id=123

interessante, il minimo (addslashes) lo conoscevo :)

la tua soluzione è interessante (e funziona senz'altro), ma ho trovato un interessante articolo (che ti invito a leggere....)
http://www.advosys.ca/papers/form-tampering.html

in breve questo tipo suggerisce di:
1) calcolare il digest nei campi nascosti in input
2) inserire tale digest a sua volta come input nascosto
3) nella pagina che processa il form, calcolare nuovamente il digest dei campi nascosti e verificare che esso coincida con il digest inserito come input nascosto nel form.
in questo modo siamo sicuri che il form è stato prodotto da noi,senza possibilità alcuna che altri l'abbiano modificato

mi sembra una soluzione elegante e neanche tanto complicata.
ora devo solo scegliere :muro:

cionci
05-09-2005, 17:23
E se si scrive una richiesta ad hoc con i campi modificati ed il digest modificato in base ai nuovi campi ???? :D

Gremo
05-09-2005, 17:23
E se si scrive una richiesta ad hoc con i campi modificati ed il digest modificato in base ai nuovi campi ???? :D

il digest è calcolato secondo una chiave segreta memorizzata lato server ;)
e se usi un sha512 mi sembra un pò difficile trovare la chiave :D

cionci
05-09-2005, 17:33
il digest è calcolato secondo una chiave segreta memorizzata lato server ;)
Il digest non ha chiave per definizione...certo, tu puoi anteporre (o postporre) un testo segreto al testo da cui derivi il digest... Questo risolve parzialmente la questione... A questo punto basta indovinare il testo segreto (cosa difficile, ma non impossibile, visto che il form funge da verifica e lo puoi richiamare quante volte vuoi)... E se ti hackerano il server e riescono a recuparere il sorgente della pagina ? In questo modo scoprono il testo segreto...

Gremo
05-09-2005, 17:53
Il digest non ha chiave per definizione...certo, tu puoi anteporre (o postporre) un testo segreto al testo da cui derivi il digest... Questo risolve parzialmente la questione... A questo punto basta indovinare il testo segreto (cosa difficile, ma non impossibile, visto che il form funge da verifica e lo puoi richiamare quante volte vuoi)... E se ti hackerano il server e riescono a recuparere il sorgente della pagina ? In questo modo scoprono il testo segreto...

le funzioni di cuoi parlo sono l'estensione mhash. l'hash (digest, signature) è calcolato in base alla chiave....
se gli hacker leggono la chiave pazienza...:D

sarebbe cmq interessante vedere quale dei due metodi offre maggiore sicurezza, sessione o digest
cmq inserisco qui il codice necessario per sperimentare questa tecnica

<?php
/* DEFINISCE CHIAVE, TIPO DI ALGORITMO INTERFACCIA PER CALCOLARE IL DIGEST DI UN MESSAGGIO.
UTILIZZATO DAI FORM PER VERIFICARE L'INTEGRITA' DEI DATI NASCOSTI:
[1]IL DIGEST VIENE CALCOLATO IN BASE AI DATI NASCOSTI DEL FORM E ALLA CHIAVE, E AGGIUNTO A SUA VOLTA COME DATO NASCOSTO
[2]A FORM INVIATO, VIENE RICALCOLATO IL DIGEST SU DI ESSI E PARAGONATO ALLA SIGNATURE DEL FORM PER CONTROLLARNE L'INTEGRITA' */

define ("CHIAVE", "220f3fdbba9cf0ced56e1c4bc639e1ad");
define ("ENC_TIPO", MHASH_SHA256);

function calcola_HMAC($string) {
return bin2hex(mhash(ENC_TIPO, $string, CHIAVE));
}
?>