Newsgroup: it.comp.www.php
Titolo: Saltare autenticazione

Ciao a tutti,
vorrei un aiuto in quanto, ho creato una pagina di login (con due frame)
per il mio sito e in un db registro login, ip, sessionid.
Il tutto funziona, ma se l'utente inserisce nel barra Address del
browswer, dopo essersi autenticato, l'indirizzo di una determinata
pagina essa viene visualizzata.
Esiste un metodo per proteggere tale eventualità e fare in modo che la
navigazione nel sito avvenga solo tramite i bottoni costruiti senza
poter accedere direttamente alle pagine???
Grazie a tutti.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 poter accedere direttamente alle pagine???
Qualsiasi tipo di soluzione sarebbe solo un pagliativo poiche' se la
pagina deve poter essere visualizzata in un qualche modo (es dopo aver
cliccato un bottone) l'utente sara' sempre in grado di accedervi (es.
simulando di aver cliccato il bottone).
-- 
I am what I am, I do what I can
L'uomo, conscio di sbagliare, persevera.

poter accedere direttamente alle pagine???
Suppongo che tutte le tue pagine inizino con un controllo della
sessione (cioè... l'utente è loggato o no?). Potresti aggiungere in
coda a questo un altro controllo sulla pagina che ha fatto da
"referrer". Dal punto di vista della sicurezza non è una garanzia,
però potrebbe servirti per raggiungere lo scopo...
-- 
Fabio Ruini
msn: 
f_r...@hotmail.com
skype: fabio.ruini - icq: 2887596
www: 
http://www.webalice.it/fabio.ruini

 Grazie a tutti.
Puoi avere un 'ragionevole' (nel senso che è una sicurezza che si basa 
sul fatto che l'utente non conosce l'architettura interna degli scripts) 
grado di sicurezza usando bottoni in flash, in modo che l'utente non 
veda l'url che và ad aprire.
Oltre a questo genera l'url che i bottoni in flash richiameranno 
mettendo come parametro obbligatorio qualcosa del tipo:
md5 ('pippo'.$numero_bottoni_premuti.date('ymd'))
(nota= pippo è una parola segreta a tua scelta)
Per passare i dati a flash puoi usare uno script che dia output xml che 
potresti chiamare ad generaUrl.php (o generaUrl.xml.php).
In apertura di ognuna di quelle pagine farai un controllo del tipo
if ($_GET['parametro']!=md5 ('pippo'.$numero_bottoni_premuti.date
('ymd')){
	//butta fuori l'utente a calci
}
Detto questo... ma ne valeva veramente la pena? ;-)
Tac

 ha scritto nel messaggio
news:c6ce82455e0f7a4dffe...@mygate.mailgate.org...


 Grazie a tutti.
Guarda, io per un sito che sto facendo che utilizza l'autenticazione degli
utenti ho fatto cosi'.
In genere uso un sistema di templating molto banale (ma comodo): ogni pagina
che compone il sito ha uno scheletro del tipo:
<?php
require "${_SERVER['DOCUMENT_ROOT']}/common/page_start.php";
require "${_SERVER['DOCUMENT_ROOT']}/common/body_start.php";
?>
... corpo della pagina ...
<?php
require "${_SERVER['DOCUMENT_ROOT']}/common/body_end.php";
require "${_SERVER['DOCUMENT_ROOT']}/common/page_end.php";
?>
In certe pagine che l'utente puo' visitare *solo* se si e` loggato, metto
prima della prima require una variabile, ad esempio:
$only_logged = TRUE;
nello script page_start.php metto all'inizio una cosa del genere:
<?php
session_start ();
...
...
//---- CHECK IF PAGE REQUIRES TO BE LOGGED ----
if ($only_logged == TRUE && !isset ($_SESSION['user_logged']))
{
    header ("Location: http://" . $_SERVER['HTTP_HOST'] . "/home.php");
    exit;
}
...
... autenticazione utenti, ecc ...
?>
A questo punto se non sei loggato ... ciccia!!!
Spero di esserti stato di aiuto.


Il modo forse si può trovare anche se laboriosamente.
Supponiamo che il numero delle pagine del percorso sia N.
Quando l'utente si logga generi N numeri casuali
compresi tra 0 e 1000.000 ad esempio.
Ad ogni pagina associ uno di questi numeri,
memorizzandoli ad esempio in una tabella di db
o in un file di testo.
Poi gli url per accedere alle pagine saranno del tipo:
pagina1.php?numero=152635
pagina2.php?numero=546736
...
paginaN.php?numero=94637
A quel punto in ogni pagina fai il confronto tra il numero casuale
passato per indirizzo e quello memorizzato. Se sono == ok
altrimenti dai errore.
E' ovvio che i link dei bottoni li devi generare
dinamicamente in base ai numeri casuali estratti.
Sigourney

 poter accedere direttamente alle pagine???
Cioe', se ho capito bene, devi garantire che l'utente segua il percorso
imposto dal programma attraverso bottoni e ancore, impedendo che l'utente
salti da una pagina all'altra a piacimento, magari usando i bottoni
back/forw del browser. E' il tipo di interazione "modale" che si ha nei
programmi stand-alone, dove ogni finestrella ha degli appositi control
("OK", "Annulla", "Avanti", "Indietro", ecc.).
Generalmente i siti di concezione WEB-like sono organizzati per pagine, e
uno, anche se regolarmente autenticato e anche se dispone di una sessione
valida, puo' saltare da un punto all'altro.
Per risolvere questo ed altri problemi, io mi sono costruito una libreria
di funzioni che ho chiamato bt_. Con questa libreria ho costruito
applicazioni anche complesse che assomigliano piu' a ad una applicazione
stand-alone che a un sito WEB. bt_ permette di imporre all'utente di
seguire il percorso logico richiesto dal programma. Il meccanismo di
funzionamento e' spiegato diffusamente in 
http://www.icosaedro.it/bt_
In sostanza, si tratta di questo.
Ogni pagina viene generata assegnando a ogni bottone e a ogni ancora
un numero progressivo. In un apposito registro di stato del server
memorizzo l'associazione tra questo numero e la funzione da richiamare
qualora l'utente azioni quell'ancora o quel bottone. Quindi invio la
pagina al client. Quanto l'utente fa clic su un bottone o un'ancora,
il numero di questo control viene ritornato al request hanlder (RH)
del programma. Il RH e' uno script che, dato il numero del control,
recupera dal registro di stato il nome della funzione e la richiama.
Ecco ad esempio come appare un form coi bottoni "Salva" e "Annulla":
function Form()
{
    # Emetti intestazione HTTP e HTML, cornicette, sfondi, ecc.:
    Intestazione();
    # Stampa titolo pagina <H1>:
    Titolo("Esempio form di input");
    # Apri un nuovo <FORM>:
    bt_form();
    # Campi di input:
    echo("Nome: <input type=text name=nome>");
    echo("Cognome: <input type=text name=cogn>");
    # Bottoni:
    # se l'utente clicca "Annulla", chiama bt_return():
    bt_button("Annulla", "bt_return");
    # se l'utente clicca "Salva", chiama Form_Valida():
    bt_button("Salva", "Form_Valida");
    echo("</FORM>");
    # Se l'utente clicca "Maggiori info", chiama Info():
    bt_anchor("Maggiori info", "Info");
    # Chiudi la pagina HTML (signature del sito, cornicette, ecc.):
    Piede();
}
La funzione Form() invia al client questo codice (ometto le parti non
essenziali):
<HTML><BODY>
<H1>Esempio form di input</H1>
<FORM method=post action=rh.php>
Nome: <input type=text name=nome>
Cognome: <input type=text name=cogn>
<INPUT type=submit name=button1 value="Annulla">
<INPUT type=submit name=button2 value="Salva">
</FORM>
<a href=rh.php?i=3>Maggiori info</a>
</BODY></HTML>
Il registro di stato in questo caso verra' a contenere le associazioni
tra i tre control e le funzioni da chiamare:
1   bt_return()
2   Form_Valida()
3   Info()
Quindi la pagina viene inviata all'utente, mentre il registro di stato
viene salvato nella sessione di utente.
Se l'utente clicca, ad esempio, sul bottone button2, il RH chiamera'
la funzione Form_Valida(). L'utente non ha la possibilita' di chiamare
direttamente la funzione Form_Valida(), perche' ad essa non corrisponde
un URL. L'unico URL che l'utente puo' raggiungere e' solo il RH rh.php e
le uniche funzioni che si possono richiamare sono solo quelle predisposte
nel file del registro.
Ci sono poi molte altre funzionalita': il RH esegue anche il controllo
della validita' della sessione; c'e' uno stack per le funzioni di ritorno
che permette di costruire moduli di pagine riutilizzabili e permette di
predisporre percorsi tra le "pagine"; si possono aprire piu' finestre
sullo stesso programma; c'e' un concetto di variabili di configurazione,
di preferenza dell'utente, di sessione, di finestra, e altre cose molto
divertenti.
Ciao,
 ___ 
/_|_\  Umberto Salsi
\/_\/  
www.icosaedro.it

 ha scritto nel messaggio
news:pX4Uc.144835$5D1.7...@news4.tin.it...
[cut]
Scusate, ho capito male io...

 ha scritto nel messaggio
news:c6ce82455e0f7a4dffe...@mygate.mailgate.org...


 poter accedere direttamente alle pagine???
No. Non per un utente autenticato, comunque.
-- 
Fabrizio "Hermooz" Ermini

 ha scritto nel messaggio
news:2oe4aaF...@uni-berlin.de...

La soluzione che avevo proposto nel post sopra non pensi
che possa andare bene?
Sigourney

No. Non per un utente autenticato, comunque.
Discutibile... ;-)


 
aspetto un controesempio :-)
-- 
Fabrizio "Hermooz" Ermini

 
finchè la sessione è valida (=utente autenticato), una volta che hai 
generato i "numeri autenticanti", questi resteranno validi 
indipendentemente dal fatto che l'utente ci arrivi facendo clic su un 
link o scrivendo la url (con il numero appeso) direttamente nella barra, 
o bookmarkandola e richiamandola dai preferiti.
L'effetto che ottieni è quello di generare dei link che effettivamente 
non possono venire usati _con_diversa_sessione_, ma non all'interno 
della stessa.
-- 
Fabrizio "Hermooz" Ermini

aspetto un controesempio :-)
Ci provo... pur a rischio figuraccia... ;-)
Aggiungere un controllo, oltre a quello sulla validità della sessione,
sulla pagina che ha fatto da referrer? So che il referrer è facilmente
falsificabile, camuffabile, ecc... però IMHO potrebbere essere una
soluzione...



Che ne dici?
Sigourney

 sulla pagina che ha fatto da referrer? 
E se il browser dell'utente non lo invia, se il proxy lo modifica, se
il firewall lo rimuove etc. etc. etc.


 
Ok, ma questo impone una "single-use" policy che non è detto sia 
accettabile... siamo proprio sicuri che ogni tanto non sia utile, se non 
addirittura necessario, ripassare da una pagina già vista?
Ok, al di là del divertissement di studiare meccanismi di enforcing del 
referrer (che possono essere molteplici, più o meno validi: pensandoci 
un po', ne potrei mettere in piedi uno piuttosto robusto e trasparente 
all'utente e al programmatore, ma al momento non c'e' spazio sufficiente 
nel margine per scriverlo... :-) il messaggio che volevo far passare è 
che impiacciarsi con la normale navigabilità di un'applicazione http 
based è *male*. Ci sono troppi strumenti in giro per il mondo che già 
complicano la vita a chi rispetta rigorosamente gli standard (browsers, 
proxyes, load balancer, application firewall, e chi più ne ha...), 
basare un'applicazione su un funzionamento di un protocollo taroccato è 
quasi sicuramente un modo di renderla inutilizzabile a qualcuno, da 
qualche parte...
-- 
Fabrizio "Hermooz" Ermini


Sigourney

il firewall lo rimuove etc. etc. etc.
... se lo "autocrea" con una variabile di sessione?


 ... se lo "autocrea" con una variabile di sessione?
Cioe?


Cioe?
In ogni pagina si imposta una variabile di sessione:
$_SESSION['pagina'] = url della pagina della pagina corente
($PHP_SELF, SCRIPTFILENAME, o qualcosa di simile)
E poi, nella varie pagine, si imposta qualcosa del tipo:
- controllo sull'utente
a) non è loggato -> spediscilo alla pagina di login, al form, o quello
che è...
b) è loggato -> controllo sul referer
- se la variabile $HTTP_REFERER esiste ed è in un formato "corretto",
allora controlla che l'utente provenga da una delle pagine
"consentite" e, in caso positivo, mostra la pagina corrente;
- se la variabile $HTTP_REFERER non esiste o non è in un formato
"corretto", allora controlla la variabile di sessione impostata
precedentemente e, sulla base di questa, visualizzi o meno la pagina
corrente.
Spero di essermi spiegato decentemente... :-/


 Spero di essermi spiegato decentemente... :-/
Continua ad essere un sistema fallibile, l'utilizzo del Referer, in
qualsiasi situazione, non e' ne sicuro ne affidabile.


qualsiasi situazione, non e' ne sicuro ne affidabile.
Ed è appunto per quello che gli viene incontro la variabile di
sessione, come controllo aggiuntivo...


 sessione, come controllo aggiuntivo...
Certo, solo che anche la variabile delle sessioni va a farsi benedire
non appena l'utente apre due pagine.


Ci provo... 
se (ho impostato una $_SESSION['numerorandom'])
	carico numerorandom, 
	strippo l'URI, cancellando una certa variabile "go=blabla"
	concateno numerorandom e uri e ne faccio l'md5.
	se (md5_concatenazione != go)
		esco e lancio un errore
altrimenti
	genero un numerorandom
	lo metto in sessione
	per ogni link che devo offuscare calcolo l'md5 della concatenazione del
link con il numero random, aggiungo al link in questione
"go=md5_concatenazione".
Il proof of concept è in attesa di approvazione su phpclasses, se siete
interessati vi posto il link
corine
-- 
Lascia l'accetta
Accetta l'ascia
it-alt.cultura.lingua.sardu: NG in sardo e varianti

non appena l'utente apre due pagine.
In che senso, scusa? Intendi se apre due finestre del browser?


 In che senso, scusa? Intendi se apre due finestre del browser?
Si, CTRL+N


 siete interessati vi posto il link
Come passi il numero random che utilizzi come chiave nella sessione?
Via URL? Nella descrizione che hai dato, basta eliminarlo dall'url per
saltare subito al passo 2 e mandare a farsi benedire tutto il check.


 saltare subito al passo 2 e mandare a farsi benedire tutto il check.
Hai ragione, il meccanismo dovrebbe funzionare cosi' solo sulla prima
pagina, quella insomma che costituisce l'entry page (ad esempio index.php).
Negli altri casi, (ad esempio unaltrapagina.php), *deve* esistere sia la
sessione che il "go", altrimenti (immagino) solleva un errore e redirige
l'utente alla entry page.
corine

Si, CTRL+N
Ehm... ti va anche di spiegarmi il problema quale sarebbe?


 Ehm... ti va anche di spiegarmi il problema quale sarebbe?
Struttura demo dei link tra le pagine:
A -> B -> C
leggi "X -> Y" come "X linka Y"
L'utente visita la pagina A [chiamiamola A1]
    (in sessione viene salvata come possibile destinazione la pagina B)
L'utente apre una nuova pagina A (CTRL + N) [chiamiamola A2]
    (in sessione viene salvata come possibile destinazione la pagina B)
Poi apre da li la pagina B dalla pagina A1 [chiamata B1]
    (in sessione viene salvata come possibile destinazione la pagina C)
L'utente tenta di aprire la pagina B dalla pagina A2, ma non puo'
perche' secondo quanto salvato in sessione puo' accedere solo alla
pagina C


    (in sessione viene salvata come possibile destinazione la pagina B)
No... la mia idea era che nella variabile di sessione non venisse
salvata la possibile destinazione, ma la pagina corrente:
- l'utente visita la pagina A
(in sessione viene salvato l'indirizzo della pagina A)
- l'utente giunge alla pagina B
(controllo sulla variabile di sessione: la pagina A è un "mittente"
consentito, quindi visualizza la pagina e successivamente sovrascrivi
la variabile di sessione con l'indirizzo della pagina B)
- ecc...
[cut]


 salvata la possibile destinazione, ma la pagina corrente:
Il discorso vale lo stesso anche cosi', comunque c'e' il rischio che
l'utente tenti di percorrere percorsi validi che vengono rienuti tali.
Struttura demo dei link tra le pagine:
A -> B -> C
leggi "X -> Y" come "X linka Y"
L'utente visita la pagina A [chiamiamola A1]
    (in sessione viene salvata la pagina A)
Apre in una nuova pagina la pagina B [chiamata B1]
    (in sessione viene salvata la pagina B)
L'utente tenta di aprire la pagina B dalla pagina A1, ma non puo'
perche' secondo quanto salvato in sessione (B) puo' accedere solo alla
pagina C (leggi "alle pagine con provenienza B").


 l'utente tenti di percorrere percorsi validi che vengono rienuti tali.
ERRATA CORRIGE
comunque c'e' il rischio che l'utente tenti di percorrere percorsi
validi che NON vengono rienuti tali.


pagina C (leggi "alle pagine con provenienza B").
Uhm... mi sa che hai ragione...
... ma visto che sono testardo, appena ho un attimo proverň a buttare
giů qualche riga di codice... ;-)


"Esiste un metodo per proteggere tale eventualità e fare in modo che la
navigazione nel sito avvenga solo tramite i bottoni costruiti senza
poter accedere direttamente alle pagine???"
Relativamente al problema, ecco la classe:
http://www.phpclasses.org/browse/package/1810.html
-- 
nick: corine
L'ascia lascia la scia
