den Onlinestatus eines Users allein mit HTML-Mitteln zu
ermitteln ist, wie bekannt, nicht möglich.
Da ich auch in den Tiefen des www hierzu nichts finden konnte,
habe ich eine Möglichkeit herausgefunden, wie es doch
zumindest mit PHP funktioniert.
Man braucht einen Frame mit Höhe und Breite auf 0 gesetzt:
<iframe width=0 height=0>
Dem muss natürlich mit src=online.php der Name des zu
ladenden Scripts übergeben werden. Hier online.php.
Mittels meta-Tag ruft sich das Script in regelmäßigen
Abständen (z. B. alle 10 Sekunden) selbst auf.
Das Script erledigt folgende Arbeiten:
1. Ermittlung deiner IP-Adresse
2. Nach dem Login mit Usernamen und Kennwort folgt noch die
Ermittlung deiner User-ID. Diese beiden Daten werden zur
Identifizierung herangezogen.
3. Das Script schaut in der Datenbanktabelle nach, ob die
Konstellation IP-Adresse und User-ID bereits vorhanden ist.
Falls ja, wird der Timestamp der aktuellen Zeit in die
Datenbank geschrieben. Der alte Timestamp wird überschrieben.
Falls es noch keinen IP-Eintrag mit der User-ID gibt, wird
ein entsprechender Datenbankeintrag eingefügt.
5. Damit ist ersteinmal sichergestellt, dass die Daten
regelmäßig aktualisiert werden.
6. Danach schaut sich das Script alle Tabelleneinträge an
und holt sich den eingetragenen Timestamp und vergleicht ihn
mit dem aktuellen Timestamp.
Liegen hier in meinem Fall 5 Minuten (300 Sekunden)
Differenz vor, wird der User automatisch ausgeloggt, da er
seit 5 Minuten seinen Datenbankeintrag nicht geändert hat.
Das Script funktioniert
a) Wenn sich ein User ganz normal ausloggt und
b) wenn ein User einfach den Browser bzw. den Browsertab
schließt.
In beiden Fällen wird die Datenbanktabelle nicht mehr
aktualisiert und nach 5 Minuten gelöscht.
Das Script ist zwar (noch) nicht in Perfektion
fertiggestellt, aber es versieht seinen Dienst, wie es soll.
Hier ist das Script...
Gruß
Heiko
---[ Scriptanfang ]---
<?PHP
// error_reporting(0);
?>
<html>
<head>
<meta http-equiv="refresh" content=10; URL=online.php/">
</head>
<body bgcolor=yellow>
<?php session_start();
include("global.php"); // verschiedene Funktionen für
Datenbankzugriffe
$ip = $_SESSION['ip']; // $_SESSION['ip'] wird nach
erfolgreichem Login gesetzt
$zeit = time();
$userid = $_SESSION['userid']; // $_SESSION['userid'] wird
nach erfolgreichem Login gesetzt
$offline = 300; // Zeit in Sekunden, nach der ein User als
offline markiert wird
$sql = "SELECT * FROM onlinestatus WHERE ip = '$ip' AND
userid = '$userid'";
verbinden();
$erg=mysql_query($sql);
if (!$erg)
{
echo "Fehler beim Datenbankzugriff<br>";
exit;
}
$found = mysql_num_rows($erg);
if ($found == 0)
{ // User muss neu in die Datenbanktabelle eingetragen werden
$sql = "INSERT INTO onlinestatus VALUES('$ip', '$userid',
'$zeit')";
verbinden();
$erg=mysql_query($sql);
} // ENDE: User muss neu in die Datenbanktabelle eingetragen
werden
else
{ // Datenbankeintrag des Users aktualisieren
$sql = "UPDATE onlinestatus SET ip = '$ip', userid =
'$userid', zeit = '$zeit' WHERE ip = '$ip' AND userid =
'$userid'";
verbinden();
$erg = mysql_query($sql);
} // ENDE: Datenbankeintrag des Users aktualisieren
// Gesamte Tabelle durchsehen, ob onlinezeit überschritten wurde
$sql = "SELECT * FROM onlinestatus";
verbinden();
$erg=mysql_query($sql);
$found=mysql_num_rows($erg);
while ($z = mysql_fetch_row($erg))
{
if (($zeit - $z[2]) > $offline)
{
$sql1 = "DELETE FROM onlinestatus WHERE ip = '$z[0]' AND
userid='$z[1]'";
verbinden();
$erg1=mysql_query($sql1);
}
}
// Useranzeige aktualisieren
verbinden();
$erg=mysql_query($sql);
echo "$found User online<br>";
while ($z = mysql_fetch_row($erg))
{
$sql1 = "SELECT nachname,vorname FROM benutzer WHERE id =
'$z[1]'";
verbinden();
$erg1=mysql_query($sql1);
$feld = mysql_fetch_object($erg1);
echo $feld->vorname . " " . $feld->nachname . "<br>";
}
?>
</body>
</html>
Hi Heiko
Danke für den Skript.
Ich werte das als freie Einladung zu einer offenen Diskussion :-)
Ich finde es den falschen Weg, die IP Adresse zu prüfen und mit dem
TimeStamp zu verknüpfen.
Das Funktioniert nicht, wenn mehrere Personen aus dem selben Netz
kommen. In Deinem Skript werden sie sich gegenseitig den "Status
Online" überschreiben.
Besser finde ich die Benutzung der Session[1], insbesondere der ID.
Ich würde da eher nur die Session prüfen. Die kennt der Server
eindeutig und sie wird auch geschlossen, wenn der Browser geschlossen
wird.
(Zudem ist es gängige Praxis.)
Also:
1. Login
2. SessionID und LoginID in DB schreiben, aktiv setzen (Status)
3. Den OnlineStatus würde ich wohl nur bei einem normalen (manuellen)
Page-refresh prüfen
Ansonsten finde ich Deine Idee gut wobei ich persönlich eher DHTML
und AJAX verwendet hätte.
4. Wenn die SessionID nicht mehr existiert = UserOffline, DB Status
auf inaktiv setzen ..(oder grad löschen)
Prüfen der SessionIDs entweder bei jedem PageRefresh oder per
CronJob.
Natürlich zerstören der Session und Löschen des DB Eintrages, beim
korrekten Logout
Grüsse
Oliver
[1] Sessions
http://www.usegroup.de/software/phptutorial/sessions.html
> habe ich eine Möglichkeit herausgefunden, wie es doch zumindest mit PHP
> funktioniert.
Das ist reichlich unzuverlässig, da es darauf baut, dass der Browser
mitspielt. Ein Verbindungsabbruch, bei dem das "meta" nicht mitkommt und
offline ist der User.
Grüße, Matthias
Funktioniert vielleicht im Intranet. Nicht in der realen Welt.
Die IP eines Besuchers kann sich von Request zu Request �ndern.
--
Web (en): http://www.no-spoon.de/ -*- Web (de): http://www.frell.de/
Stimmt. Aber...
Wenn sich die IP ändert, wird sie aus der Datenbank gelöscht
und die neue IP mitsamt User-ID und Timestamp wieder
eingetragen.
Gruß
Heiko
Nur zu. :-)
>
> Ich finde es den falschen Weg, die IP Adresse zu prüfen und mit dem
> TimeStamp zu verknüpfen.
> Das Funktioniert nicht, wenn mehrere Personen aus dem selben Netz
> kommen. In Deinem Skript werden sie sich gegenseitig den "Status
> Online" überschreiben.
Stimmt nicht so ganz, denn nicht nur die IP-Adresse, sondern
auch die entsprechende User-ID (gemeinsam) wird mit dem
Timestamp verknüpft.
>
> Besser finde ich die Benutzung der Session[1], insbesondere der ID.
Klingt logisch, denn die session-ID ist absolut einmalig. :-)
>
> Ich würde da eher nur die Session prüfen. Die kennt der Server
> eindeutig und sie wird auch geschlossen, wenn der Browser geschlossen
> wird.
> (Zudem ist es gängige Praxis.)
Stimmt auffallend.
>
> Also:
> 1. Login
> 2. SessionID und LoginID in DB schreiben, aktiv setzen (Status)
> 3. Den OnlineStatus würde ich wohl nur bei einem normalen (manuellen)
> Page-refresh prüfen
Und was würde passieren, wenn ich mehr als 5 Minuten ohne
Refresh auf der Seite bin? Genau. Logout. :-)
> Ansonsten finde ich Deine Idee gut wobei ich persönlich eher DHTML
> und AJAX verwendet hätte.
Danke für die Blumen. Mit DHTML und Ajax habe ich noch nicht
die notwendigen Erfahrungen. Möchte mich aber bei
Gelegenheit darin schlau machen.
> 4. Wenn die SessionID nicht mehr existiert = UserOffline, DB Status
> auf inaktiv setzen ..(oder grad löschen)
Und statt der Session-ID allein prüfe ich die IP-Adresse
_UND_ die Login-ID.
>
> Prüfen der SessionIDs entweder bei jedem PageRefresh oder per
> CronJob.
Cronjob ist ein guter Ansatz, an den ich bei der Erstellung
des Scriptes gar nicht gedacht hatte.
> Natürlich zerstören der Session und Löschen des DB Eintrages, beim
> korrekten Logout
Nicht der Rede wert. :-)
>
> Grüsse
> Oliver
Grüße aus Berlin
Heiko
--
Die Signatur fällt heute mal aus.
>> Besser finde ich die Benutzung der Session[1], insbesondere der ID.
>
> Klingt logisch, denn die session-ID ist absolut einmalig. :-)
Nein. Zum einen gibt es Angriffe, die schwache Session-Systeme wie das
von PHP ausnutzen wie z.b. Session Fixation.
Zum anderen ist die Session-Id endlich in Länge und verwendeten
Buchstaben. Korrekt wäre daher: In der Regel ist sie ziemlich selten ;)
Gruß,
Torsten
--
http://www.dddbl.de - ein Datenbank-Layer, der die Arbeit mit 8
verschiedenen Datenbanksystemen abstrahiert,
Queries von Applikationen trennt und automatisch die Query-Ergebnisse
auswerten kann.
Gut zu Wissen! Was ist wenn man einen Random-Hash in den Session-Name
schreiben würde und die Abfrage danach richten täte?
Kennst Du ein Beispiel für Session Fixation? Ist das Problem nicht
eher bei einer lockeren Rechtehaltung im Dateisystem?
>
> Zum anderen ist die Session-Id endlich in Länge und verwendeten
> Buchstaben. Korrekt wäre daher: In der Regel ist sie ziemlich selten ;)
>
> Gruß,
> Torsten
...
:-)
Oliver
Was ist mit verschiedenen Usern, die mit der selben IP kommen?
Gruss
Oliver
dafür gibt's ja noch die User-ID, die vom jeweiligen
Login-System vergeben wird und einmalig sein sollte.
Beispiel:
2 User loggen sich von der gleichen IP-Adresse 217.159.80.57
ein.
Die User erhalten von der HP, auf der sie sich eingeloggt
haben, unterschiedliche User-IDs. Z. B. ID 1 und 2.
Ermittelt das Script, dass User 2 von obiger IP inaktiv ist,
wird User 2 abgemeldet, während User 1 aber noch online bleibt.
Mein Script wurde dahingehend sowohl im Intranet als auch im
Internet getestet. Es funktioniert.
> Gruss
> Oliver
Gruß
in. Zum einen gibt es Angriffe, die schwache Session-Systeme wie das
> von PHP ausnutzen wie z.b. Session Fixation.
Also wenn DU sowas erzählst kannst Du eigentlich nicht wissen was
wirklich Session-Fixation ist. Die setzt laut definition eine
entsprechend manipulierte Anwendung auf dem Server voraus. Doch wenns
wirklich dazu kommt ist die Session das letzte worüber ich mir Sorgen
machen würde.
MfG, Ulf
--
Es würde gegen meine Programmierung verstoßen, eine Gottheit
zu personifizieren. [C-3PO]
>>>> Besser finde ich die Benutzung der Session[1], insbesondere der ID.
>>> Klingt logisch, denn die session-ID ist absolut einmalig. :-)
>> Nein. Zum einen gibt es Angriffe, die schwache Session-Systeme wie das
>> von PHP ausnutzen wie z.b. Session Fixation.
>
> Gut zu Wissen! Was ist wenn man einen Random-Hash in den Session-Name
> schreiben w�rde und die Abfrage danach richten t�te?
> Kennst Du ein Beispiel f�r Session Fixation?
Beispiel:
=== datei session.php ===
<?php
session_start();
// authentifikation und ganz viel Anderes
?>
=== Angriffsstart: Erzeugen einer Session ===
http://domain/session.php?PHPSESSID=4d6ffb6381dc7c41d6070d4e201610d5
=== Auszug aus dem Session-Save Path ===
drwx-wx-wt 2 apache apache 12K 2009-12-09 09:44 ./
drwxr-xr-x 36 root root 4,0K 2009-12-07 15:12 ../
-rw------- 1 apache apache 0 2009-12-09 09:44
sess_4d6ffb6381dc7c41d6070d4e201610d5
(Die Session wurde also wie vorgegeben angelegt und existiert jetzt bis
sie als Garbage betrachtet wird. Die Lebenszeit l��t sich mit
regelm��igen Requests erh�hen)
=== Angriff ===
Kurze Mail an $Admin mit dem Hinweis, dass $Funktion scheinbar nicht
geht. Da der $Admin viel zu tun hat und nicht alles sofort wei�, hier
der Pfad zum Modul: http://bit.ly/4Vn8eT (Kurzurl zum verschleiern des
Angriffes genutzt)
> Ist das Problem nicht
> eher bei einer lockeren Rechtehaltung im Dateisystem?
Nein - es ist ein systembedingtes Problem von PHP. Dagegen hilft der
Einsatz von session_regenerate_id() (Parameter nicht vergessen, sonst
ist ein Angriff auf alte Sessions m�glich) oder ein eigenes Session-System.
Gru�,
> in. Zum einen gibt es Angriffe, die schwache Session-Systeme wie das
>> von PHP ausnutzen wie z.b. Session Fixation.
>
> Also wenn DU sowas erzählst kannst Du eigentlich nicht wissen was
> wirklich Session-Fixation ist.
Eine Session-Fixation ist ein Angriff auf eine verbindungsbehaftete
Datenkommunikation bei der der Angreifer die Session des Angegriffenen
fixiert (= setzt).
Oder vereinfacht ausgedrückt: Ich lege deine Session-Id fest.
Da PHP ein schwaches Session-System verwendet und gültige Sessions
erzeugt werden, obgleich diese nicht existiert haben und ohne, dass eine
Authentifizierung notwendig ist, ist der Angriff simpel.
Wenn du glaubst, dass ich etwas nicht wisse, mich im Lexem vergriffen
oder mich schlichtweg irre, dann schreibe bitte deine Überzeugung aus,
damit ich darauf eingehen kann. In der Regel sehe ich Fehler schnell ein
und entschuldige mich sogar dafür. Auch wenn mir der Umgangston im
Internet wohlbekannt ist und ich über Jahre meinen Beitrag dazu
geleistet habe, schmälert er in letzter Zeit mein Bedürfnis mich
überhaupt zu beteiligen. Ob das ein Verlust oder ein Gewinn ist, darf
jeder selbst beurteilen.
> Die setzt laut definition eine
> entsprechend manipulierte Anwendung auf dem Server voraus.
Mir ist keine Definition bekannt, die "setzt entsprechend manipulierte
Anwendung auf dem Server voraus" enthält. Bitte zeige mir eine.
> Oder vereinfacht ausgedrückt: Ich lege deine Session-Id fest.
Du brauchst mir das nicht erklären! Mir ist durchaus klar von was wir
reden.
> Da PHP ein schwaches Session-System verwendet und gültige Sessions
> erzeugt werden, obgleich diese nicht existiert haben und ohne, dass eine
> Authentifizierung notwendig ist, ist der Angriff simpel.
Der Angriff ist simpel aber der erfolgreiche Angriff nicht.
Es wird immer von einer der folgenden Möglichkeiten ausgegangen um eine
Anwendung zu komprimitieren:
- URL-Manipulationen
Setzt aber voraus das session_use_cookies_only deaktiviert ist.
Ist in der heutigen Zeit bei fast keinem Hoster mehr deaktiviert
- Cross-Site-Scripting
OK wer Seine Anwendungen nicht gegen bekannte Probleme absichert
Hat hier ein Problem. Aber das ist dann sicher nicht das Einzige
über was man sich sorgen machen sollte
- Cross-Site-Cooking
OK das ist jetzt ne Clientsache. Wer seinen Browser nicht wenigstens
grundlegend im Griff hat stellt ein Problem dar
- Zugriff auf den PC des Opfers
da braucht ich nix dazu sagen oder?
>> Die setzt laut definition eine
>> entsprechend manipulierte Anwendung auf dem Server voraus.
>
> Mir ist keine Definition bekannt, die "setzt entsprechend manipulierte
> Anwendung auf dem Server voraus" enthält. Bitte zeige mir eine.
<http://www.acros.si/papers/session_fixation.pdf>
<http://www.erich-kachel.de/?p=368>
MfG, Ulf
--
In der Tiefe meiner Seele ist eine wärmende Dunkelheit, deren
Vollständigkeit einer undurchdringlichen Unbegreiflichkeit der
Unendlichkeit gleicht! [Andreas J. Voigt]
Ok, jetzt versteh ichs. Danke.
Mit dem Konzept bin ich noch immer nicht so einverstanden und
favorisiere die Serverseitige Session als das "richtigere" Konzept.
Um die von Torsten genannten Sicherheitsaspekte zu respektieren hatte
ich solche Dinge noch berücksichtigt:
- Session Name setzen und geprüft
- Session ID bei jedem Seitenaufruf geprüft mit lokaler Variable
- Eigene Session ID erstellen mit zufälligem Inhalt
- Seitenaufruf über
- Session Timeout "relativ tief"
Hinsichtlich Torstens Einwände würde ich wohl zusätzlich die Session
ID in ein File oder in die DB schreiben und von dort mit der aktuellen
ID gegenprüfen sowie die externe Seitenaufrufe und/ oder Cookies nicht
einschalten...
Die übrigen Argumente von Torsten sind zwar richtig, ich sehe das
Problem aber eher bei der Konfiguration (Apache, PHP, Sicherheit, ...)
als beim Programmierkonzept.
(Wenn ich Zeit und Laune habe, werde ich noch im Thread weiter oben
bei Torsten/ Ulf darauf eingehen und seine Argumente untersuchen)
Oliver
[1] Session Hijack
http://www.php-kurs.com/session-hijacking.htm
>> Oder vereinfacht ausgedrückt: Ich lege deine Session-Id fest.
>
> Du brauchst mir das nicht erklären! Mir ist durchaus klar von was wir
> reden.
Ich wollte nur aufzeigen, dass ich entgegen deiner Äußerung durchaus
Kenntnis von Session-Fixation habe. Offensichtlich herrschen darüber
unterschiedliche Auffassungen.
>> Da PHP ein schwaches Session-System verwendet und gültige Sessions
>> erzeugt werden, obgleich diese nicht existiert haben und ohne, dass eine
>> Authentifizierung notwendig ist, ist der Angriff simpel.
>
> Der Angriff ist simpel aber der erfolgreiche Angriff nicht.
Ach bitte... Es geht um ein - mittlerweile erprobtes - Angriffskonzept.
Für die konzeptionelle Betrachtung ist es völlig unerheblich, wie häufig
es real erfolgreich ist. Es geht um die grundsätzliche Betrachtung.
Eigentlich wollte ich auch noch einiges zum Rest schreiben. Aber das ist
Zeitverschwendung. Du zählst die gängigen Angriffsmethoden zu diesem
Muster auf und beweist damit, dass solche Angriffe *möglich* sind. Und
nichts anderes habe ich behauptet. Es freut mich, dass du meine Ansicht
teilst.
>>> Die setzt laut definition eine
>>> entsprechend manipulierte Anwendung auf dem Server voraus.
>> Mir ist keine Definition bekannt, die "setzt entsprechend manipulierte
>> Anwendung auf dem Server voraus" enthält. Bitte zeige mir eine.
>
> <http://www.acros.si/papers/session_fixation.pdf>
> <http://www.erich-kachel.de/?p=368>
Ich habe den zweiten link nach "manipuliert" durchsucht. Ich fand das
Wort im Abschnitt über CSRF. Von einer Fixation-Definition, die diese
Worte oder die inhaltliche Bedeutung deiner Behauptung innehatte, war
nichts zu finden, vllt. habe ich es auch übersehen. Tut mir leid. Ab
hier mußt du dich ohne mich weiterstreiten.