Verständnisfrage zu HTTP Session/Cookies



Kaioshin

New Member
Hallo Leute

Ich habe eine Allgemein Frage zu Webservern in Bezug auf HTTP Sessions und Cookies. Ich hoffe ich poste hierfür in der richtigen Forumkategorie.

Folgendes: Für die Wiedererkennung eines Nutzers bzw. für die Erschaffung einer Beziehung bei der Navigierung einer Webseite zwischen den einzelnen Seiten ist es üblich Cookies einzusetzen und somit eine Session zu kreieren. Ich stelle aber bei manchen Seiten fest, dass ich gar kein Cookie habe. Trotzdem erkennt mich die Webseite - solange ich den Browser nicht ganz schliesse - wieder. Wenn ich den Verlauf mitschneide - beispielsweise mit dem Firefox Addon, LiveHTTPHeaders, stelle ich fest dass ein Cookie (PHPSSEID) mitgesendet wird. Dieses "Cookie" ist aber auf dem System nirgends gespeichert - zumindest nicht im Filesystem. Kann mir jemand erklären wie das Ganze zusammenhängt? Einerseits ist es ein Cookie mit dem die Session fortgesetzt werden kann, andererseits jedoch habe ich nirgendwo ein Cookie gespeichert.

Bin für jede Antwort sehr dankbar :)

Gruss, Kaioshin
 
Kann mir jemand erklären wie das Ganze zusammenhängt? Einerseits ist es ein Cookie mit dem die Session fortgesetzt werden kann, andererseits jedoch habe ich nirgendwo ein Cookie gespeichert.

Das ist kein echter Cookie. Da wird einfach beim Ausliefern der Seite eine generierte ID an jeden verfügbaren Link als Parameter angehangen. Wenn du auf den Link klickst, wird der Parameter erneut an die Seite übertragen und der Zusammenhang zwischen zwei Requests ist hergestellt. So kannst du auch ohne Cookies Klick für Klick einen User verfolgen.

So weit ich mich erinnere, kann PHP sowas out of the box.
 
Aber wenn ich beispielsweise die Seite in einem neuen Tab/Fenster öffne, reicht es den Link anzugeben ohne weitere Parameter mitzuliefern.

Hier eine betroffene Beispielseite: http://demos.9lessons.info/welcome.php

\\EDIT

Stelle gerade fest dass in Firefox tatsächlich für die obige Seite ein Cookie angelegt wird. Mir geht es nähmlich darum dieses Cookie zu kopieren um es in einem Tool weiterverwenden zu können, welches per HTTP Daten abholen muss. Möchte durch das bereits bestehende Cookie dann die nochmalige Authentifizierung ersparen. Der Grund hierfür ist, dass die betroffene Webapplikation eine bereits bestehende Session bei Eröffnung einer neuen beendet.

Gruss, Kaioshin
 
Last edited by a moderator:
Wenn ich bei deiner Beispiel-Seite Cookies abschalte, geht auch der Login nicht mehr. Du hast den Verkehr ja selbst mitgeschnitten und weißt daher, dass dein Browser ein Cookie mitsendet. Der liegt natürlich nicht als File irgendwo rum, sondern z.B. bei Firefox in einer SQLite-Datenbank.

Am Rande erwähnt: Das von dir verlinkte Script setzt du bitte nicht ein. Da sind diverse SQL-Injection Sicherheitslücken drin.
 
Siehe bitte vorherigen Beitrag, habe einen entprechenden Edit durchgeführt.

Am Rande erwähnt: Das von dir verlinkte Script setzt du bitte nicht ein. Da sind diverse SQL-Injection Sicherheitslücken drin

Welchen Script? Meinst du die Seite? Und wieso diverse SQL Injection, die einzigen Paramter die die login.php erwartet, sind username und password.
 
wget/curl müsste post und auch cookies unterstützen. D.h. du kannst dich mit einen der beiden tools per Kommandozeile autentifizieren und ein cookie abspeichern.


Und wieso diverse SQL Injection, die einzigen Paramter die die login.php erwartet, sind username und password.

Sobald du Parameter ungeprüft an die DB übergibst, kann der Hacker alles machen.

Im Tutorial steht folgendes:
Code:
$myusername=addslashes($_POST['username']);
$mypassword=addslashes($_POST['password']);

Zur Funktion addslashes ( http://de3.php.net/addslashes ):
Möchte man zum Beispiel einen Namen wie O'reilly in ein Datenbankfeld schreiben, muss er maskiert sein. Es wird dringend empfohlen, die datenbankspezifische Escapefunktion zu verwenden (z.B. mysqli_real_escape_string() für MySQL oder pg_escape_string() für PostgreSQL).

Diese Funktion des Escapens der Zeichen wird von faulen Programmierer ausgenutzt um eine mysql-injection zu verhindern, was aber nicht immer klappt:

Die PHP-Direktive magic_quotes_gpc war vor PHP 5.4 standardmäßig aktiviert, sodass die Funktion addslashes() auf alle GET-, POST- und COOKIE-Daten angewendet wurde. Verwenden Sie daher die Funktion addslashes() nicht, wenn Strings bereits durch magic_quotes_gpc escaped wurden, ansonsten erhalten Sie doppelte Maskierungen.

Zitat aus Wikipedia ( http://de.wikipedia.org/wiki/SQL-Injection#PHP ):
Häufig wird aus Bequemlichkeit einfach die Konfigurationsoption „magic_quotes_gpc“ auf „on“ gestellt, mit der von außen kommende Benutzereingaben automatisch maskiert werden. Doch dies ist nicht empfehlenswert. Denn manche nicht selber programmierte Skripte setzen eigenständig Funktionen wie etwa addslashes()[3] oder das bereits weiter oben genannte mysql_real_escape_string()[4] ein. Das heißt, dass bereits allen relevanten Zeichen in den Benutzereingaben durch so genannte Magic Quotes[5] ein Backslash vorangestellt wurde und nun durch die Escape-Funktion erneut ein Backslash vorangestellt wird. Somit werden die Benutzereingaben verfälscht und man erhält beispielsweise anstatt eines einfachen Anführungszeichens ein Anführungszeichen mit vorangestelltem Backslash (\"). Auch aus Gründen der Portabilität sollte bei der Entwicklung von Anwendungen auf diese Einstellung verzichtet und stattdessen alle Eingaben manuell validiert und maskiert werden, da nicht davon ausgegangen werden kann, dass auf allen Systemen dieselben Einstellungen vorherrschen oder möglich sind. Darüber hinaus sollte addSlashes() nicht zum Maskieren von Datenbank-Eingaben benutzt werden, da es keine ausreichende Sicherheit gegenüber mysql_real_escape_string() gewährleistet.[6]

Schon erschreckend, dass es überhaupt möglich ist mit PHP so scheiße programmieren zu können.

Ich finde es immer wieder erstaunlich, wie schlecht die Tutorials doch sind. Gibt es sowas für php?: http://bobby-tables.com/python.html

Ich meine eine Abstaktionsschicht zwischen DB und Programm.

Generell musst du alle Eingaben validieren, sofern nichts dazwischen ist, was bösen Code herausfiltert.

Um nochmal auf wget zurück zu kommen:
Code:
wget --post-data "username=test&password=test" demos.9lessons.info/login.php -O-
Das funktioniert. Jetzt noch mit cookies: http://www.gnu.org/software/wget/manual/html_node/HTTP-Options.html

Folgendes solltest du dir ansehen:
  • ‘--save-cookies file’
  • ‘--keep-session-cookies’
  • ‘--load-cookies file’

Beim kurzen Test hat er keine Cokkies geschrieben. Ist schon zu spät um darüber weiter nachzudenken.
 
Last edited by a moderator:
Hallo

Zum Thema SQL Injection, danke für die Erklärung. Diesen Script habe ich sowieso nicht vor zu nutzen, der Login der Seite sollte einzig und allein nur als Beispiel zu meiner Frage dienen.

Beim kurzen Test hat er keine Cokkies geschrieben. Ist schon zu spät um darüber weiter nachzudenken.

Also ich habe folgendes festgestellt. Bei der Beispielseite handelt es sich bei dem angelegten Cookie um ein Session cookie und nicht um ein Persistent Cookie. Dass soll heissen, dass ein Session cookie nur für diese Sitzung gültig ist und im Regelfall nur im Arbeitsspeicher liegt. Nach Schliessung des Browsers, hat dieses Cookie keine Gültigkeit mehr bzw. geht ganz verloren. Was in meinem Fall genau gleich ist (im Bezug auf die Webapplikation bei der es mir geht). Hierzu ein Beitrag aus Wikipedia:

Session cookie

A user's session cookie[15] (also known as an in-memory cookie or transient cookie) for a website exists in temporary memory only while the user is reading and navigating the website. When an expiry date or validity interval is not set at cookie creation time, a session cookie is created. Web browsers normally delete session cookies when the user closes the browser.[16][17]

Quelle: http://en.wikipedia.org/wiki/HTTP_cookie#Session_cookie

Nun in meinem Fall ist es so, dass ich ein Tool entwickeln möchte (um gewisse Tätigkeiten zu vereinfachen) welches sich aber letztendlich im Kern, auf eine Webapplikation stützt (Datenbestände etc.). Leider habe ich zu dieser Webapplikation bzw. zum Webserver keine Schnittstelle welche mir zur Verfügung gestellt werden würde. Ich muss mit meinem Tool - wie der normale User - über HTTPS mit der Webapplikation kommunizieren. Im Endeffekt geht es nur darum einige Daten - mit Hilfe einer vereinfachten Oberfläche welche entworfen werden soll - auszulesen.

Zum Part "Kommunikation mit der Webapplikation" sehe ich für mich nun folgende Hürden:

  • Das vorangegangen Session cookie wird bei Eröffnung einer neuen Session für ungültig erklärt. Hier gilt also das bereits bestehende Session cookie zu verwenden (was durch einen manuellen Login mit dem Browser angelegt wurde).
  • Ich habe bisher keine Möglichkeit gefunden, Session cookies vom Internet Explorer oder Firefox abzulesen.

Im Übrigen ist das für mich nur ein Hobbyprojekt, daher habe ich natürlich keine dedizierte Schnittstelle oder ähnliches. Dazu kommt dass ich noch die Anfragen, welche der Webapplikation gestellt werden müssten, noch vorher analysieren muss - da ich keine Dokumentation darüber habe was für Parameter etc. erwartet werden und wie der Kommunikationsablauf aussieht. Es war nur eine Idee mit der ich mich nun genauer beschäftigen wollte.

Ich bedanke mich für eure bisherige Hilfe!

Gruss, Kaioshin
 
Last edited by a moderator:
Last edited by a moderator:
Requests ist ganz gut. Hab ich schon verwendet um z.B. von einer Seite populäre Babynamen zu bekommen. Aus purer Langeweile hab ich dann daraus einen Graphen mit matplotlib erstellt. Mit gerade mal 38 Zeilen Code ist das recht einfach. Jedes mal das Rad neu zu erfinden ist nicht zweckmäßig. Du kannst aus dem Vollen schöpfen.

Eigentlich ist jede Website eine API, man muss sie nur nutzen.

PS: Django finde ich etwas überladen. Sicherlich kann man dimit echt tolle Projekte auf die Beine stellen. Meine ersten Versuche habe ich mit Flask gemacht. Mit den Dekoratoren wird es einem wirklich sehr einfach gemacht.
 
Ein Problem besteht aber weiterhin. Ich darf leider keine neue Sitzung starten, ich muss die bestehende verwenden. Ich stelle mir das so vor, dass ich die Cookies irgendwie ablesen müsste um diese dann für meine Anfragen zu verwenden.

Mit dem Tool von "IECookiesView" von Nirsoft, werden die session Cookies nicht angezeigt nur die persistenten Cookies. Das gleiche gilt für Firefox (wobei man bei Firefox diese session Cookies zumindest im entsprechenden Menü dafür sehen kann). Für mich relevant wäre es aber im Internet Explorer. Ich möchte das Ganze zwar nicht aufgeben, aber hinsichtlich zig anderer Probleme die hier noch warten, ist das ohne eine eigene Schnittstelle die entsprechend in einer Dokumentation festgehalten ist sehr aufwendig.
 
Last edited by a moderator:
Es wäre wichtig zu wissen wie, wo und wann diese Software welche du entwicklen willst zum Einsatz kommen soll.
Falls deine Client-Applikation im Browser selbst laufen kann/soll/darf, so wäre es ggf möglich dass entweder automatisch (Greasemonkey) oder manuell (Javascript Bookmarklet) die Cookies ausgelesen werden. Das Resultat kann dann entweder im gleichen Browser-Fenster die Original-Webseite ersetzen oder via Cross-Window Kommunikation an deine App überreicht werden.

Da keine Details zu deiner Realisierung bekannt sind, eine kleine Warnung: viele Anbieter sehen eine Änderung des Clients mit teilweise mehr Features oder Automatisierungen als verboten an und können je nach Belastung des Systems dadurch sogar rechtliche Schritte geltend machen.
 
Ein Problem besteht aber weiterhin. Ich darf leider keine neue Sitzung starten, ich muss die bestehende verwenden. Ich stelle mir das so vor, dass ich die Cookies irgendwie ablesen müsste um diese dann für meine Anfragen zu verwenden.
Hast du dir auch mal die Zeit genommen, auf einen der Links zu klicken und z.B. zu Python-Requests die Doku zu lesen? Da steht drin, wie das geht.

Mit dem Tool von "IECookiesView" von Nirsoft, werden die session Cookies nicht angezeigt nur die persistenten Cookies. Das gleiche gilt für Firefox (wobei man bei Firefox diese session Cookies zumindest im entsprechenden Menü dafür sehen kann). Für mich relevant wäre es aber im Internet Explorer.
Für dein "Tool" wie auch immer es aussehen soll, brauchst du weder Firefox noch den Explorer. Der Ansatz die Cookies da raus zu nuckeln ist vollkommen falsch. Du brauchst keinen Browser, der das implementiert, sondern eine Bibliothek für deine Programmiersprache, die dir die Cookies liefert. Beispiele siehe oben.
 
Vielleicht kann er nicht programmieren. Anders kann ich mir das nicht erklären, wieso er den umständlicheren Weg gehen will. Er soll ja auch das Rad nicht neu erfinden sondern einfach die Mittel nutzen, die bereits zur Verfügung stehen. Requests bietet alles was du brauchst, abstrahiert das schön und ist leicht zu bedienen.
 
Ich programmiere zwar nicht in Python aber das ist hier nicht das Problem. Mir fehlt es hier über das Verständnis bei der HTTP Kommunikation - daher auch die Frage. Ich schaue mir gerade diese Requests Bibliothek an.
 
Wie genau jetzt HTTP funkioniert musst du noch nicht einmal wissen. Paar Sachen wie GET, POST, regex und eine Klasse/Modul/Bibliothek in der Sprache deiner Wahl helfen dir da schon weiter.
 
Grundsätzlich eine HTTP Request erstellen und das erhaltene Cookie einsetzten ist ja kein Problem. Die Sitzung im Browser ist danach aber ungültig. Ich habe das zwar noch nicht mit der betroffenen Applikation probiert, stelle es aber fest wenn ich mich mit zwei unterschiedlichen Browsern anmelde. Ich verstehe leider nicht was für einen anderen Ansatz ich mit diesen Bibliotheken verfolgen könnte. Bitte hierzu um ein Stichwort.
 
Die Sitzung im Browser ist danach aber ungültig. Ich habe das zwar noch nicht mit der betroffenen Applikation probiert, stelle es aber fest wenn ich mich mit zwei unterschiedlichen Browsern anmelde
Das hängt alles von der Webapplikation ab. Generell ist dies nämlich nicht der Fall und es besteht eine 1-zu-n Beziehung zwischen Benutzerkonto und Sessions. Manchmal (bspw Onlinebanking) kann es aber sinnvoll sein nur eine 1:1 Session zu zu lassen, evtl ist der Programmierer der getesteten Applikation aber auch schlicht unbegabt und speichert den Session-Identifizierer in der Benutzertabelle.
Ob die gewünschte Applikation also mehrere Sessions zulässt muss also getestet werden, nicht geraten.

ch verstehe leider nicht was für einen anderen Ansatz ich mit diesen Bibliotheken verfolgen könnte.
Einen Browser simulieren.
 
Kleines Beispiel wie man von http://www.ssa.gov/cgi-bin/popularnames.cgi die populären Babynamen bekommt:

Code:
from collections import namedtuple
import re
import requests
import os

#hier koennte man einen dekorator zum cachen einfuehren
def getdata(year):
    cachefilename = 'cache_%s.htm' % year
    if not os.path.isfile(cachefilename): # Cachefile zum lesen oeffnen
        with open(cachefilename,'wb') as fd:
            payload = {'top': '1000', 'year': year} # Daten fuer das Fromular uebergeben
            r = requests.post('http://www.ssa.gov/cgi-bin/popularnames.cgi', data=payload) #Request machen
            fd.write(r.content) # Request cachen
            r = r.content
    else: # Wenn cache vorhanden inhalt aus dem cache lesen
        with open(cachefilename,'rb') as fd:
            r = fd.read()
    return parse(r) # Inhalt zurueckgeben

def parse(content):
    parsed = re.findall(r'<td>(\d+)</td>\s<td>(\w+)</td>\s<td>(\w+)</td>', content)
    out = namedtuple('Babynames',['Rank','Male','Female'])
    #print re.findall(r'Popularity\sin\s\d+', content)
#   for line in parsed: # so nicht
    for rank, male, female in parsed:
        #yield out(*line) #schlechter stil..
        yielt out(rank, male, female)


def get_male_by_name(name):
    for year in range(1987,2013):
        for rank, male, female in getdata(year):
            if male == name:
                print "Year %s: %s %s" % (year, male, rank)
                break

def get_by_name(name, sex='male'):
    stucture = { 'rank': 0, 'male': 1, 'female': 2}
    for year in range(1990,2013):
        for data in getdata(year):
            if data[stucture[sex]] == name:
                print "Year %s: %s %s" % (year, name, data[stucture['rank']])
                break
        else:
            print "Year %s: %s %s" % (year, name, None)

def get_by_name_xy(name, sex='male'):
    outx = []
    outy = []
    stucture = { 'rank': 0, 'male': 1, 'female': 2}
    for year in range(1987,2013):
        outx.append(year)
        for data in getdata(year):
            if data[stucture[sex]] == name:
                outy.append(int(data[stucture['rank']]))
                break
        else:
            outy.append(float('nan'))
    return (outx, outy)

Um das mal abzukürzen:

Code:
import requests
url = 'http://www.ssa.gov/cgi-bin/popularnames.cgi'
payload = {'top': '1000', 'year': year}
req = requests.post(url, data=payload)
komplette_seite_als_string = req.content
 
Last edited by a moderator:
Back
Top