Newsgroup: it.comp.www.php
Titolo: Sovrascrittura sessioni

Dopo il login andato a buon fine, mi sovrascrive le sessioni. Nel senso
che tutti gli utenti connessi hanno lo stesso nome.
Da cosa può dipendere?

Da cosa può dipendere?
Posta il codice
Francesco Mazzi
Webmaster di AltroPC.it - 
http://www.altropc.it
 
Staff di E-Xoopport - 
http://www.e-xoopport.it

Francesco Mazzi ha scritto:

Io lo posto, ma è parecchio intrecciato e strutturato male :P ma
almeno fino a poco fa fungeva...
<?php
//Apre la sessione
session_start();
//Stampa gli ultimi 5 annunci
function get_lastnews()
{
	global $db;
	$html = "<br /><table border='0' width='480' align='center'
cellspacing='1' cellpadding='5' style='border: .1em solid #F5CB71;'>";
	$html .= "<th id='intestazione'>Autore</th><th
id='intestazione'>Data</th><th id='intestazione'>Testo</th>";
	$query = mysql_query("SELECT * FROM news ORDER BY data DESC LIMIT 0,5
");
	while($rows = mysql_fetch_array($query))
	{
		$html .= "<tr><td valign='top'
align='center'>".$rows['autore']."</td><td valign='top' align='center'
width='130'>".get_date($rows['data'], "yes")."</td><td
align='justify'>".$rows['testo']."</td></tr>";
	}
	$html .= "</table><br />";
	return ($html);
}
//Aggiorna durante il login
function update_login()
{
	//Imposta l'orario attuale
	$now = time();
	//Recupera l'ip
	$ip = $_SERVER['REMOTE_ADDR'];
	//Recupera il nome
	$nome = $_SESSION['nome'];
	@mysql_query("INSERT INTO logs_ip (nome, ip, data) VALUES ('$nome',
'$ip', '$now')");
	@mysql_query("UPDATE users SET ultimo_accesso='$now',
ultimo_azione='$now', ultimo_aggiorna='$now' WHERE nome = '$nome'");
}
//Imposta il login
function set_login($valori)
{
	//Recupera le variabili necessarie
	global $city_name;
	//Imposta le variabili di sessione
	$_SESSION['nome'] = $valori['nome'];
	if($valori['master']==1)
		$_SESSION['master']=1;
	$_SESSION['sex'] = $valori['sex'];
	//Se ha un mestiere
	if($valori['mestiere_id']!=NULL AND $valori['mestiere_ruolo']!=NULL)
		$_SESSION['simbolo'] =
$valori['mestiere_id']."/".$valori['mestiere_ruolo'];
	//Se ha un clan
	elseif($valori['clan_id']!=NULL AND $valori['clan_ruolo']!=NULL)
		$_SESSION['simbolo'] = $valori['clan_id']."/".$valori['clan_ruolo'];
	//Se non ha nè un mestiere, nè un clan, imposta come simbolo
l'araldica
	else
		$_SESSION['simbolo'] = "0/".$valori['araldica_ruolo'];
	$session_id = SID; #id della sessione
	//Aggiorna i dati
	update_login();
	//Imposta le variabili dell'utente
	$id = $valori['id']; #Id account
	$ultimo_accesso = get_date($valori['ultimo_accesso'],"yes"); #Ultimo
accesso
	$nome = $valori['nome']; #Nome PG
	$araldica = $valori['araldica_nome']; #Araldica
	$anzianità = $valori['anzianità']; #Punti anzianità
	$msg_nonletti = $valori['msg_nonletti']; #Messaggi non letti
	$attacco = $valori['attacco']; #Attacco pg
	$difesa = $valori['difesa']; #Difesa pg
	$resistenza = $valori['resistenza']; #Resistenza pg
	$destrezza = $valori['destrezza']; #Destrezza pg
	$intelligenza = $valori['intelligenza']; #Intelligenza pg
	$pv = $valori['pv']; #Punti vita pg
	$exp = $valori['exp']; #Punti esperienza pg
	//Restituisce le ultime 5 news
	$block_text = get_lastnews();
$block_text .= <<<HEREDOC
<script type="text/javascript">
	function entra()
  	{
		var newWindow =
window.open('game/game.php','$city_name','toolbar=0,menubar=0,directories=0,location=0,scrollbars=0,status=0,resizable=1');
		newWindow.focus();
		location.href = 'index.php?act=sei_entrato';
  	}
	function popup(page)
  	{
		var popup =
window.open('index_files/opzione_'+page,'','toolbar=0,menubar=0,directories=0,location=0,scrollbars=1,status=0,resizable=0,height=210,width=300');
	}
</script>
<table width='480' border="0" cellspacing="5" cellpadding="0"
align="center">
	<tr>
		<td><img src="img/cavaliere.gif" /></td>
		<td align="justify">Bentornato, $nome. Il tuo ultimo accesso risale
al $ultimo_accesso.
			Hai accumulato $anzianità punti anzianità, che equivalgono
all'araldica di $araldica. Hai $msg_nonletti nuova/e missiva/e da
leggere.<br /><br />
HEREDOC;
if($araldica == "Straniero")
	$block_text .= "<b>AVVISO:</b> sei uno straniero, all'ingresso della
città o al molo del porto ti sarà confiscata ogni arma che ti verrà
restituita solo all'uscita dal Ducato.<br /><br />";
$block_text .= <<<HEREDOC
			<center><input type="button" value="Entra nel gioco"
onclick="entra()" /></center>
		</td>
	</tr>
	<tr>
		<td colspan="2" align="center"><br /><a
href="javascript:popup('noautologin.php')">Disabilita autologin</a> |
<a href="javascript:popup('cambiapwd.php?id=$id')">Modifica
password</a> | <a
href="javascript:popup('controllaip.php?$session_id')">Controlla
accessi e IP</a><br /><br /></td>
	</tr>
	<tr>
		<td colspan="2">
			<!-- INIZIO SOTTOTABELLA PARAMETRI PG -->
			<table border="0" width='480' cellspacing='1' cellpadding="5"
align="center" style="border: .1em solid #F5CB71;">
				<tr><th id="intestazione">Attacco</th><th
id="intestazione">Difesa</th><th id="intestazione">Resistenza</th><th
id="intestazione">Destrezza</th><th
id="intestazione">Intelligenza</th><th id="intestazione">P.V.</th><th
id="intestazione">Exp</th></tr>
				<tr><td align="center">$attacco</td><td
align="center">$difesa</td><td align="center">$resistenza</td><td
align="center">$destrezza</td><td align="center">$intelligenza</td><td
align="center">$pv</td><td align="center">$exp</td></tr>
			</table>
			<!-- FINE SOTTOTABELLA PARAMETRI PG -->
		</td>
	</tr>
</table>
HEREDOC;
	return($block_text);
}
//Controlla il login
function check_login($email, $pwd)
{
	//Recupera il form e il titolo del gioco
	global $form, $title;
	//Imposta i dati ricevuti
	$email = strip_tags(addslashes($email));
	//Esegue la query con i dati inseriti
	$query = mysql_query("SELECT * FROM users WHERE email = '$email' AND
pwd = '$pwd'");
	//Conta il numero di risultati ottenuti...
	$rows = mysql_num_rows($query);
	//Se c'è una riga (dati corretti)
	if($rows==1)
	{
		//Se l'utente ha richiesto l'autologin, lo imposta tramite cookie
(valore: 1 anno)
		if(isSet($_POST['autologin']) AND $_POST['autologin']=="yes")
		{
			//Imposta l'email
			setcookie('email', $email, time()+(60*60*24*365));
			//Imposta la password
			setcookie('pwd', $pwd, time()+(60*60*24*365));
		}
		//Trasforma i dati in array
		$valori = mysql_fetch_array($query);
		//Se l'utente non è stato nè bannato, nè sospeso e l'account è
attivo
		//EFFETTUA IL LOGIN!
		if($valori['tipo_ban']==NULL AND $valori['status']==1)
		{
			//Setta la sessione e restituisce i dati del login
			$block_text = set_login($valori);
		}
		//Altrimenti, se l'utente è stato bannato o sospeso
		elseif($valori['tipo_ban']!=NULL)
		{
			//Se l'utente è stato bannato
			if($valori['tipo_ban']==1)
				$block_text = "<div id=\"alert\"><b>ERRORE:</b> il tuo account è
stato bannato!<br />Autore: ".$valori['autore_ban']."<br />Motivo:
".$valori['motivo_ban']."</div>";
			//Se l'utente è stato sospeso
			else
			{
				//Prende il tempo attuale in secondi
				$now = time();
				//Se la sospensione non è ancora finita
				if($valori['durata_ban']>$now)
					$block_text = "<div id=\"alert\"><b>ERRORE:</b> il tuo account è
stato sospeso fino al ".get_date($valori['durata_ban'], "yes")."!<br
/>Autore: ".$valori['autore_ban']."<br />Motivo:
".$valori['motivo_ban']."</div>";
				//Se la sospensione è finita
				else
				{
					$block_text = "<div id=\"alert\"><b>AVVISO:</b> il tuo account era
stato sospeso fino al ".get_date($valori['durata_ban'], "yes").".<br
/>La sospensione è scaduta, quindi il tuo account è stato sbloccato.
Ora puoi rieffettuare il login.<br /><br /><center><a
href=\"index.php?act=entra\">Entra nel $title</a></center></div>";
					$query = mysql_query("UPDATE users SET tipo_ban=NULL,
durata_ban=NULL, autore_ban=NULL, motivo_ban=NULL WHERE email =
'$email' AND pwd = '$pwd'");
				}
			}
		}
		//Altrimenti, se l'account non è ancora attivo...
		else
			$block_text = "<div id=\"alert\"><b>AVVISO:</b> il tuo account non
è stato ancora attivato. Controlla nella tua casella di posta,
troverai un'email per completare l'iscrizione!</div>".$form;
	}
	else
	//Se non c'è nessuna riga (login incorretto)
	{
		$block_text = '<div id="alert"><b>ERRORE:</b> email o password
errata!<br />Fai attenzione alla distinzione tra maiuscole e
minuscole!</div>'.$form;
	}
	return($block_text);
}
$block_title = "Entra";
//Imposta l'indirizzo della pagina
$self = $_SERVER['REQUEST_URI'];
$form = <<<HEREDOC
<script type="text/javascript">
<!--
<!-- Controlla i dati immessi nel form -->
function control(form)
{
	<!-- Controlla che il campo email non sia vuoto -->
	if(form.email.value=="")
	{
		alert("Devi inserire un indirizzo email!");
		return false;
	}
	<!-- Controlla che il campo password non sia vuoto -->
	if(form.pwd.value=="")
	{
		alert("Devi inserire una password!");
		return false;
	}
	if(form.email.value!="") AND (form.pwd.value!="")
	{
		return true;
	}
}
<!-- Se si è spuntato l'autologin avverte l'utente -->
function check()
{
	if(document.forms["entra"].autologin.checked)
	{
		alert("Hai attivato l'autologin. Verranno salvati due cookie sul tuo
computer e al prossimo accesso non sarà necessario inserire nuovamente
i dati per la connessione");
	}
}
<!-- Porta alla pagina per il recupero password -->
function recupera_pwd()
{
	location.href = "index.php?act=recupera_pwd";
}
// -->
</script>
<table border="0" align="center" cellspacing="5" cellpadding="0"
width="0%">
<tr>
	<td valign="middle"><img src="img/statua.gif" /></td>
	<td>
		<table border="0" align="center" cellspacing="5" cellpadding="0"
width="0%">
		<!-- INIZIO FORM -->
		<form method="POST" action="$self" name="entra" onsubmit="return
control(this)">
			<tr>
				<th colspan="2" align="left">LOGIN<hr color="#F5CB71" size="1"
/></th>
			</tr>
			<tr>
				<th align="left">Email:</th><td><input type="text" name="email"
size="30"/></td>
			</tr>
			<tr>
				<td colspan="2" id="small">Inserisci l'indirizzo email con cui sei
iscritto</td>
			</tr>
			<tr>
				<th align="left">Password:</th><td><input type="password"
name="pwd" size="30"/></td>
			</tr>
			<tr>
				<td colspan="2" id="small">Inserisci la password. Puoi recuperarla
<a href="index.php?act=recupera_pwd">qui</a></td>
			</tr>
			<tr>
				<td align="right"><input type="checkbox" name="autologin"
value="yes" onclick="check()" style="border: 0px;"/></td><td>Attiva
autologin</td>
			</tr>
			<tr>
				<td colspan="2"><center><input type="submit" name="entra"
value="Entra nel $title_game" /> <input type="button" value="Recupero
pwd" onclick="recupera_pwd()"/></center></td>
			</tr>
			<tr>
				<td colspan="2" id="small"><hr color="#F5CB71" size="1" />Se non
sei ancora iscritto puoi farlo cliccando <a
href="index.php?act=iscriviti">qui</a></td>
			</tr>
		</form>
		</table>
		<!-- FINE FORM -->
	</td>
</tr>
</table>
HEREDOC;
//Se è già aperta una sessione (utente connesso)
if(isSet($_SESSION['nome']) AND $_SESSION['nome']!="")
	$block_text = '<div id="alert"><b>ERRORE:</b> spiacente, ma risulti
già connesso!</div>';
//Se sono presenti i cookie (autologin)
elseif(isSet($_COOKIE['email']) AND isSet($_COOKIE['pwd']))
{
	//CONTROLLA IL LOGIN
	$block_text = check_login($_COOKIE['email'], $_COOKIE['pwd']);
}
//Se è stato compilato il form effettua il login
elseif(isSet($_POST['entra']))
{
	//Controlla che siano stati inseriti i dati
	//se javascript è attivato
	//Se i dati sono stati inseriti
	if($_POST['email']!="" AND $_POST['pwd']!="")
	{
		include_once "game/functions/functions_eregi.php";
		if(eregi_mail($_POST['email'])==FALSE) #Controlla la validità
dell'indirizzo email
			$block_text = '<div id="alert"><b>ERRORE:</b> l\'indirizzo email
inserito non è valido!</div>'.$form;
		elseif(eregi_pwd($_POST['pwd'])==FALSE) #Controlla la validità della
password
			$block_text = '<div id="alert"><b>ERRORE:</b> la password inserita
non è valida!</div>'.$form;
		else #Se è tutto ok, procede con il login
		{
			//Imposta la password in md5
			$pwd = md5($_POST['pwd']);
			//CONTROLLA IL LOGIN
			$block_text = check_login($_POST['email'], $pwd);
		}
	}
	//Altrimenti, se i dati non sono stati inseriti
	else
		$block_text = '<div id="alert"><b>ERRORE:</b> devi inserire indirizzo
email e password!</div>'.$form;
}
//Altrimenti, mostra il form per il login
else
	$block_text = $form;
?>
Vedi se ci capisci qualcosa...

 >Da cosa può dipendere?
non ho controllato tutto il codice ma intanto inizierei con
 if (!session_id())
 {
    session_start();
 }
e non con
session_start();
poi hai dei problemi con l'sql injection  quindi farei dei controlli sui 
valori passati tramite i post e cookies 
(
http://se.php.net/manual/it/function.mysql-real-escape-string.php
) .  tra 
l'altro, impostare email e psw in chiaro nei cookies non mi pare molto 
carino :P
 

 carino :P
Per quanto riguarda i cookie hai ragione, ma questa è solo una beta
per vedere se funziona (e infatti) :)
Per quanto riguarda i post, invece, dov'è l'errore?

Per quanto riguarda i post, invece, dov'č l'errore?
non c'e' un errore vero e proprio.  c'e' un problema di sicurezza.    ti 
faccio un esempio con la tua query
SELECT * FROM users WHERE email = '$email' AND pwd = '$pwd'
tutto va bene finche' in email o pwd non uso gli apici.    prova ad 
immaginare cosa succede se $pwd="pippo' OR '1'='1"   (questa e' la cosa piu' 
banale).  la tua query si trasforma in:
SELECT * FROM users WHERE email = '
x...@xxx.com
'' AND pwd = 'pippo' OR 
'1'='1'
quindi si riesce a loggarsi senza problemi.
il problema sono gli apici (ho visto anche casi in cui non erano necessari 
neanche gli apici x cambiare la query :O ).
a questo punto, puoi fare molteplici controlli sulla stringa che ti arriva 
dal post (usa l'immaginazione) oppure piu' semplicemente usi
$pwd=mysql_real_escape_string($_POST['pwd']) ;
   oppure x essere piu' pignoli
$pwd=(isset($_POST['pwd']))?mysql_real_escape_string($_POST['pwd']):"";
al che' la query sopra verrebbe trasformata in:
SELECT * FROM users WHERE email = '
x...@xxx.com
'' AND pwd = 'pippo\' OR 
\'1\'=\'1'
spero di essermi spiegato

 spero di essermi spiegato
Ah, beh certo che ho capito. Ma non ho applicato la funzione addslashes
() (che credo equivalga a mysql_real_escape_string()), semplicemente
perchè la query non usa il valore di $_POST direttamente, ma il suo
equivale in md5 :P
Quindi anche se nel modulo inserisco una apice, viene md5ato, quindi
non dovrebbe essere un problema.
O sbaglio?

O sbaglio?
rimane l'email ;)

DNS ha scritto:

Giusto.