# LOGIN Prüfen ob User angemeldet ist



## Steusi (6. März 2009)

Hallo Leute ich erstelle gerade ein Login-Script, meine Frage ist nun, was sollte ich auf jeder Seite prüfen, damit ich mir sicher bin das der User auch angemeldet ist?
Sollte man noch eine zusätzliche Session-Variable erzeugen? Reicht es nur zu prüfen, ob die Existiert oder auch ob sie mit dem DB-Eintrag überein stimmt?

Jetzt habe ich es in meinen Augen sehr unsicher:

Von meinem Login-Formular werden die Eingabedaten mit meiner DB verglichen:


```
##########################_____Datenbank auslesen_____###########################


// Eingegebene Date prüfen, ob diese in der Datenbank enthalten sind
$sql = "SELECT ".  
    "Id, Nickname, Kennwort, Rechte, login ".  
  "FROM ".  
    "benutzerdaten ".  
  "WHERE ".  
    "(Nickname like '".$_POST["Nickname"]."') AND ".  
    "(Kennwort = '".md5 ($_POST["Kennwort"])."')";  
$result = mysql_query ($sql);  

if (mysql_num_rows ($result) > 0)  
{  
  // Benutzerdaten in ein Array auslesen.  
  $data = mysql_fetch_array ($result);  

#####################_____Sessionvariabeln definieren_____#######################

  // Sessionvariablen erstellen und registrieren aus den Arrayelementen
  $_SESSION["user_id"] = $data["Id"];  
  $_SESSION["user_nickname"] = $data["Nickname"];
  $_SESSION["user_password"] = $data["Kennwort"]; 
  $_SESSION["user_rechte"] = $data["Rechte"];  
  $_SESSION["user_login"] = $data["login"];
```

Auf jeder Seite wird nur geprüft, ob die ID gesetzt ist, also brauch man nur eine ID setzten und kommt auf fast alle Seiten, wie regelt man das optimaler?

```
<?php  
session_start ();  
if (!isset ($_SESSION["user_id"]))  {
  header ("Location: http://localhost/ORDNER/formular_login.php?session=1");  
}  
?>
```


----------



## Dennis Wronka (6. März 2009)

Ich persoenlich speichere lediglich die UserID in der Session.
Das reicht meiner Meinung nach auch vollkommen aus, denn das Session-Array kann ja vom User nicht manipuliert werden (ausser man hat irgendwelche Code der ganz abartige Sachen mit User-Eingaben anstellt).

Zudem laufen Sessions bei mir nicht ueber das normale Session-Management von PHP sondern ueber eine eigene Klasse, welche nicht nur die SessionID zur Identifikation der Session nutzt, sondern zusaetzlich auch noch User-Agent und IP.

Natuerlich sind dies alles Daten die auch gefaelscht werden koennen, dennoch ist es sicherer als sich nur auf die SessionID zu verlassen.
Zudem ist es meiner Meinung nach eh nicht moeglich diese Geschichte 100% abzusichern, denn wenn Du was in der Session speicherst muss es ja mit irgendwas abgeglichen werden. Und es macht meiner Meinung nach wenig Sinn Username und Passwort in der Session zu speichern und bei jedem Seitenaufruf wieder mit der DB abzugleichen, denn durch erfolgreiches Login, welches ja erst zur Aufnahme dieser Daten in der Session fuehrte, wurde ja bereits bestaetigt dass diese Daten korrekt sind.

Andererseits ist es keine gute Idee diese Daten in einem Cookie zu speichern, vor allem da die meisten Seiten unverschluesselt kommunizieren.

Wie gesagt, es bleibt im Grunde nur die Moeglichkeit den User ueber so viele Kriterien wie moeglich an seine Session zu binden. In meinem Falle sind dies zur Zeit die SessionID, der User-Agent und die IP.

Ob Dir das ausreicht, oder ob Du noch mehr Punkte pruefen willst ist natuerlich Dir ueberlassen.
Es sei nur nochmal erwaehnt dass all diese Daten, egal was Du Dir zusaetzlich noch aus der Nase ziehst, gefaelscht werden koennen.


----------



## Steusi (6. März 2009)

> Zudem ist es meiner Meinung nach eh nicht moeglich diese Geschichte 100% abzusichern, denn wenn Du was in der Session speicherst muss es ja mit irgendwas abgeglichen werden. Und es macht meiner Meinung nach wenig Sinn Username und Passwort in der Session zu speichern und bei jedem Seitenaufruf wieder mit der DB abzugleichen, denn durch erfolgreiches Login, welches ja erst zur Aufnahme dieser Daten in der Session fuehrte, wurde ja bereits bestaetigt dass diese Daten korrekt sind.


Genau das habe ich mir auch gedacht!!

Mit User-Agent habe ich mich noch nicht beschäftigt, werde ich mir erstmal angucken.

Aber du hast schon recht, wer eine Session fälschen kann, schafft es auch die IP zu knacken. Dann reicht es wohl doch, aber User-Agent werd ich mir trotzdem man angucken.


----------



## Dennis Wronka (6. März 2009)

Falls Du eine MySQL-Datenbank im Hintergrund hast koenntest Du Dir auch meine Klasse SQLSession anschauen. Das ist die Klasse die ich fuer Sessions nutze.


----------



## Steusi (6. März 2009)

So sieht es aus:

```
if ((!isset ($_SESSION["user_id"])) && (!isset($_SESSION["user_agent"])) && ($_SESSION["user_agent"] == $_SERVER['HTTP_USER_AGENT']))  {
  header ("Location: http://localhost/...../formular_login.php?session=1");  
}
```

Ja ich habe ne DB im Hintergrund!
Ich dachte immer bei einem IP-Wechsel ist die Session automatisch beendet

Du prüfst mit deiner Funktion "readsession" ja auch nur ob alle Daten mit den Daten in der DB übereinstimmen:
id=$sessionid
useragent=$_SERVER['HTTP_USER_AGENT']
ip=$_SERVER['REMOTE_ADDR']

Gut, aber muss man die Daten (USER_AGENT und REMOTE_ADDR) bei jedem Login neu in die DB einbinden? 
Ich werd die Daten nur für die Session anlegen, aber nicht noch extra mitspeichern, weil diese sich ja immer ändern. Eine History benötige ich nicht extra, da ich alle Loginaufrufe mit diesen Daten in eine log-Datei (txt) abspeichere.


----------



## kuddeldaddeldu (6. März 2009)

Hi,

ich würde ehrlich gesagt erstmal die Datenbankabfragen sicherer gestalten, bevor ich anfange, IP und UserAgent zu prüfen (nicht, dass das nicht sinnvoll ist...).

Nur mal so am Rande...

LG


----------



## Steusi (6. März 2009)

Kannst du mir bitte mal ein Schlagwort zukommen lassen?
Wie genau soll ich die Datenbankabfragen sicherer machen? Oder meinst du eher das einfügen der Userdaten in die DB?


----------



## kuddeldaddeldu (6. März 2009)

Hi,



Steusi hat gesagt.:


> Kannst du mir bitte mal ein Schlagwort zukommen lassen?



Klar: SQL-Injection

Das betrifft alle Datenbankabfragen, in denen Du vom User übermittelte Daten benutzt.

LG


----------



## Steusi (6. März 2009)

Ja der Begriff sagt mir was, aber dabei geht es doch um Variablenübergabe an die DB.
Ich muss mir noch mal eine Klasse mit strenger Typenkontrolle basteln, das meinst du damit. Aber ich habe schon relativ viel abgesichert, aber es geht noch einiges...


----------



## kuddeldaddeldu (6. März 2009)

Steusi hat gesagt.:


> aber dabei geht es doch um Variablenübergabe an die DB.



Ja. Das sag ich doch.



Steusi hat gesagt.:


> Ich muss mir noch mal eine Klasse mit strenger Typenkontrolle basteln, das meinst du damit. Aber ich habe schon relativ viel abgesichert, aber es geht noch einiges...



Also in obiger Abfrage ist quasi Null Komma gar nichts abgesichert. Du steckst da den übergebenen Nicknamen einfach völlig unbehandelt rein...

LG


----------



## Dennis Wronka (6. März 2009)

Steusi hat gesagt.:


> Ja ich habe ne DB im Hintergrund!
> Ich dachte immer bei einem IP-Wechsel ist die Session automatisch beendet


Soweit ich weiss ist es so, dass Du eine Session mitnehmen kannst solang Du eine gueltige SessionID vorweisen kannst. Dass ist ja gerade was das Session-Hijacking relativ einfach macht.



Steusi hat gesagt.:


> Gut, aber muss man die Daten (USER_AGENT und REMOTE_ADDR) bei jedem Login neu in die DB einbinden?


Nein, das uebernimmt die Session-Klasse fuer Dich.



Steusi hat gesagt.:


> Ich werd die Daten nur für die Session anlegen, aber nicht noch extra mitspeichern, weil diese sich ja immer ändern. Eine History benötige ich nicht extra, da ich alle Loginaufrufe mit diesen Daten in eine log-Datei (txt) abspeichere.


Wie gesagt, die Daten zur Session werden von der Klasse verwaltet. Eigentlich sollten abgelaufene Sessions auch nach einer Weile geloescht werden, ob das so richtig funktioniert kann ich aber zur Zeit nicht mit Bestimmtheit sagen.



Steusi hat gesagt.:


> Ja der Begriff sagt mir was, aber dabei geht es doch um Variablenübergabe an die DB.
> Ich muss mir noch mal eine Klasse mit strenger Typenkontrolle basteln, das meinst du damit. Aber ich habe schon relativ viel abgesichert, aber es geht noch einiges...


Es geht darum dass Du verhinderst dass der User unerwuenschten SQL-Code in Deine Abfrage einbauen kann.
In meiner Klasse wird dies durch den Aufruf von $this->db->escape_string() geregelt, welche einen Wrapper um Funktionen wie mysql_real_escape_string() darstellt.


----------



## Steusi (6. März 2009)

Dennis Wronka hat gesagt.:


> Soweit ich weiss ist es so, dass Du eine Session mitnehmen kannst solang Du eine gueltige SessionID vorweisen kannst. Dass ist ja gerade was das Session-Hijacking relativ einfach macht.


Oh, warum regelt PHP, dann die Session nicht zusätzlich noch über die IP? 
Ok, wo ich die Frage stelle merke ich es selbst für Proxy wäre keine eindeutige Identifikation möglich, und auch nur als zusätzliche Überprüfung ginge auch nicht, da ich früher auch mal AOL-Kunde war 



Dennis Wronka hat gesagt.:


> Es geht darum dass Du verhinderst dass der User unerwuenschten SQL-Code in Deine Abfrage einbauen kann.


hm, aber beim Benutzernamen kann er wenig Schaden anstellen?
und aus dem eingegebene PW wird ja auch gleich ein Hash erzeugt?
Aber man könnte es ja auch einfach so schreiben. oder irre ich:

```
$sql = "SELECT ".  
    "Id, Nickname, Kennwort, Rechte, login ".  
  "FROM ".  
    "benutzerdaten ".  
  "WHERE ".  
    "(Nickname like '".mysql_escape_string($_POST["Nickname"])."') AND ".  
    "(Kennwort = '".md5 (mysql_escape_string($_POST["Kennwort"]))."')";
```
Auch wenn es sehr schlechtes coding in meinen Augen ist.


----------



## Dennis Wronka (6. März 2009)

Steusi hat gesagt.:


> Ok, wo ich die Frage stelle merke ich es selbst für Proxy wäre keine eindeutige Identifikation möglich, und auch nur als zusätzliche Überprüfung ginge auch nicht, da ich früher auch mal AOL-Kunde war


Auch vom Proxy kommt ja eine IP. Man koennte aber auch checken ob vom Proxy die Client-IP durchgereicht wurde, ein ordentlich eingerichteter Proxy sollte dies tun, nur Proxies die den Client anonymisieren sollen tun dies nicht, und dann eben diese verwenden.



Steusi hat gesagt.:


> hm, aber beim Benutzernamen kann er wenig Schaden anstellen?
> und aus dem eingegebene PW wird ja auch gleich ein Hash erzeugt?


Also der Hash ist, wie Du schon sagst, ungefaehrlich, da es sich bei einem solchen Hash ja um einen Wert mit begrenztem Zeichensatz handelt.
Aber wer sagt denn dass der User im Feld fuer den Usernamen wirklich nur Buchstaben verwendet?
Da gibt es durchaus Moeglichkeiten Code in die SQL-Abfrage einzuschleusen die dann z.B. Deine Passwort-Abfrage schlichtweg aushebelt.


----------

