HeikoH: $_GET und $_SESSION liefern keine Werte

Hallo @,
ich nutze ein CMS Script, osdate, und möchte dieses mit einem weiteren Baustein, Kalender, erweitern.
Das Verzeichnis Kalender habe ich ins Hauptverzeichnis vom CMS gelegt und passe es derzeit an, versuche es zumindest.
Ich möchte in einer Datei vom Kalender Werte vom CMS abfragen aber es wird kein Wert der Variable $id zugeführt.
Hier ein Auszug:

if (isset($_GET['id']) && ($_GET['id'] != ''))
 $id = $_GET['id'];
elseif (isset($_SESSION['UserId']) && ($_SESSION['UserId'] != ''))
 $id = $_SESSION['UserId'];
else
 $id = '';

$_SESSION['test'] = $id; // sehen was gespeichert wird

$db_user ="xxx";
$db_name = "xxx";
$db_host = "xxx";
$db_pw = "xxx";

mysql_connect($db_host, $db_user, $db_pw);
mysql_select_db($db_name);

$abfrage = "SELECT * FROM travelplan WHERE UserId = $id";

Füge ich nach if/else $id = 105; //als Beispiel ein, funktioniert mein Plan.
Auf der Ausgabeseite lasse ich mir ausserdem auch die UserId aus der Session anzeigen - sie ist da. Und wenn ich im Browser ?id=105 anhänge, funktioniert der Plan nicht.
Bei php.net hab ich nichts gefunden ob man $_GET für bestimmte Seiten beschränken kann, genauso $_SESSION - kann man das machen(?), denn im CMS funktionieren diese vorgefertigten Variablen.
Auch die include() Funktion für die Einbindung der DB Varianblen habe ich nicht hinbekommen, was ich auch gesetzt habe ('../start.php' oder './start.php' oder viele andere Möglichkeiten noch).

CMS
|
start.php
|
|--[Kalender]
|       |
|       ziel.php // Datei, wo start.php includiert werden soll
...

Aber das nur nebenbei - ist nicht so wichtig. Wichtig ist, dass ich $id mit "Leben" füllen kann.

HeikoH

  1. if (isset($_GET['id']) && ($_GET['id'] != ''))
    $id = $_GET['id'];
    elseif (isset($_SESSION['UserId']) && ($_SESSION['UserId'] != ''))
    $id = $_SESSION['UserId'];
    else
    $id = '';

    $abfrage = "SELECT * FROM travelplan WHERE UserId = $id";

    Nur nebenbei: Wenn ich ein ganz böser Mensch wäre, würde ich in der Adressleiste meines Browsers '…?id=0 or true' eintippen und darauf spekulieren, dass du (wie ja tatsächlich oben zu sehen) den Parameter id ungefiltert und ungesichert in deinen SQL-Befehl einfügst: 'SELECT * FROM travelplan WHERE UserId = 0 or true'. Und nun lasse dir mal durch den Kopf gehen, was da passiert …

    Füge ich nach if/else $id = 105; //als Beispiel ein, funktioniert mein Plan.
    Auf der Ausgabeseite lasse ich mir ausserdem auch die UserId aus der Session anzeigen - sie ist da. Und wenn ich im Browser ?id=105 anhänge, funktioniert der Plan nicht.

    Die doch eigentlich naheliegendste Frage hast du dir anscheined noch nicht gestellt: Wie sehen denn die an der if-Abfrage beteiligten Variablen aus, konkret: was steht denn in $_GET? Füge vor der if-Zeile 'var_dump($_GET); var_dump($_SESSION);' ein (überprüfe solche Ausgaben immer in der Quellcodeansicht des Browsers, nicht in der normalen Webseitendarstellung!), oder benutze 'phpinfo(INFO_VARIABLES);'. Erst dann hast du einen Überblick darüber, welche Bedinungen gegeben sind.

    Bei php.net hab ich nichts gefunden ob man $_GET für bestimmte Seiten beschränken kann, genauso $_SESSION - kann man das machen(?)

    Nein. Sie sind lediglich bei uralten PHP-Versionen nicht vorhanden, aber da sie bei dir ja an anderer Stelle funktionieren, wird das nicht die Ursache sein.

    Auch die include()-Funktion für die Einbindung der DB-Varianblen habe ich nicht hinbekommen, was ich auch gesetzt habe ('../start.php'

    include('../start.php'); sollte eine Datei aus dem darüber gelegenen Verzeichnis einbinden.

    oder './start.php'

    ./ ist das aktuelle Verzeichnis.

    Wenn include() die besagte Datei nicht findet, sollte sich im Fehlerprotokoll des Servers eine entsprechende Meldung finden.

    1. if (isset($_GET['id']) && ($_GET['id'] != ''))
      $id = $_GET['id'];

      hab noch ein wenig probiert - hier muss ein Problem sein - es wird 'RCalendar1' ausgegeben

      Nur nebenbei: Wenn ich ein ganz böser Mensch wäre, würde ich in der Adressleiste meines Browsers '…?id=0 or true' eintippen und darauf spekulieren, dass du (wie ja tatsächlich oben zu sehen) den Parameter id ungefiltert und ungesichert in deinen SQL-Befehl einfügst: 'SELECT * FROM travelplan WHERE UserId = 0 or true'. Und nun lasse dir mal durch den Kopf gehen, was da passiert …

      ...noch nichts, da es ja nicht funktioniert, sondern wie oben beschrieben die Ausgaben ist - aber ich werde es ausprobieren denn ich hab keine Idee was passiert - bin aber auch kein Profi

      Füge vor der if-Zeile 'var_dump($_GET); var_dump($_SESSION);' ein (überprüfe solche Ausgaben immer in der Quellcodeansicht des Browsers, nicht in der normalen Webseitendarstellung!), oder benutze 'phpinfo(INFO_VARIABLES);'. Erst dann hast du einen Überblick darüber, welche Bedinungen gegeben sind.

      Gute Idee - mache ich gerade

      Wenn include() die besagte Datei nicht findet, sollte sich im Fehlerprotokoll des Servers eine entsprechende Meldung finden.

      Mal schauen, wusste nicht, dass man dort was findet

      Danke erstmal, hab wieder was zu tum

      HeikoH

      1. Hello,

        if (isset($_GET['id']) && ($_GET['id'] != ''))
        $id = $_GET['id'];
        hab noch ein wenig probiert - hier muss ein Problem sein - es wird 'RCalendar1' ausgegeben

        Wie kommt denn der Request zustande?

        Per Link?
          Dann schau Dir im Quelltext an, wie der Link aussieht.
          Was in den Parametern des Links nicht drinsteht, kann in $_GET
          (ohne weitere Manipulation [1]) nicth auftauchen

        Per Formular
          - per Post
          -- mit zusätzlichen Get-Paramertern?
          ...

        schau Dir das <form-Element an und was dort vereinbart wird

        Per JavaScript
          - per Formular und submit
          -- per Post
          --- mit zusätzlichen Get-Parametern?
          -- per Get

        - per URL-Umschaltung

        - per AJAX

        Erst, wenn Du diese Randbedingungen geprüft hast, kannst Du überhaupt gezielt weitersuchen.

        Liebe Grüße

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        1. Wie kommt denn der Request zustande?

          es gibt eine <div id="containerRCalendar1"></div>
          Kann das diese Ausgabe erzeugen?

          HeikoH

          1. Hello Heiko,

            Wie kommt denn der Request zustande?

            es gibt eine <div id="containerRCalendar1"></div>
            Kann das diese Ausgabe erzeugen?

            *ups*

            Sollte der Eindruck trügen, dann entschuldig bitte.
            Aber Du scheinst bisher mit Client-Server Szenarien und hier speziell mit HTTP noch nicht so sehr vertraut zu sein. Es sollte daher besser sein, wenn Du vorher einige grundlegende Übungen machst mit dem Browser, PHP und dem Webserver.

            Dazu gehören auch die unterschiedlichen von den üblichen Browsern untersützten Request-Methoden.
            Request ist hier das "Aufrufen" einer "Seite" auf dem Webserver. Woraus die besteht, ist egal. Es kann  sich eine Datei (z.B. *.html) dahinter verbergen, eine Software, die Daten aus einer Datenbank holt und dann zum Client (Browser) zurückschickt oder auch eine ganze Gruppe von Servern, die mit ihrer Software und ihren Datenbanken etwas für Dich zusammenbauen, was dann auf dem Client (im Browser-Quelltext) aussieht, als käme es aus einer HTML-Datei.

            Sag uns bitte, wo wir Dich abholen dürfen, damit wir nicht nutzlos Energie verpulvern, Du aber auch nicht zu weit laufen musst... :-)

            Liebe Grüße

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            1. Request ist hier das "Aufrufen" einer "Seite" auf dem Webserver. Woraus die besteht, ist egal. Es kann  sich eine Datei (z.B. *.html) dahinter verbergen, eine Software, die Daten aus einer Datenbank holt und dann zum Client (Browser) zurückschickt oder auch eine ganze Gruppe von Servern, die mit ihrer Software und ihren Datenbanken etwas für Dich zusammenbauen, was dann auf dem Client (im Browser-Quelltext) aussieht, als käme es aus einer HTML-Datei.

              so ein programm ist, meinem Verständnis nach, PHP

              Sag uns bitte, wo wir Dich abholen dürfen, damit wir nicht nutzlos Energie verpulvern, Du aber auch nicht zu weit laufen musst... :-)

              bin relativ zentral gelegen - Berlin ;)

              Ich kann auch verstehen, dass es für euch schwer ist mir zu helfen, da Ihr das Script nicht kennt und für mich ist es auch schwer, da ich ein fremdes Script (Kalender) in ein fremdes Script (osDate) einbauen möchte.
              Dazu kommt osDate verwendet dazu noch Smarty, und ich hab überhaupt keine Ahnung davon, und ich versuche dann immer über kleine Testdateien überhaubt eine Ausgabe am Browser zu bekommen. Wenn ich, wie vorhin, den Quelltext mir anschaue - der sieht so zerpflückt aus - fürchterlich. Ist also alles nicht einfach.

              Aber nochmal zurück zum Thema.

              Ich dachte immer,  $_GET holt sich seine Informationen aus der Adresszeile.
              Aber da muss es nochmehr geben. In der Zeile steht nur travelplan.php ohne angehängte Werte. Auch das Form woher diese Seite aufgerufen wird, ist übrigens die gleiche Datei, ist ohne Anhang (<form name="frmPlan" id="frmPlan" method="post" action="travelplan.php" onsubmit="javascript: return validateme(this);">).

              Aber in diesem Form befindet sich
              <div>
               <div id="containerRCalendar1"></div>
              </div>

              Daher dachte ich es kommt daher...
              ...sehe aber gerade vor meinem geistigen Auge das hier steht "containerRCalendar1" und nicht "RCalendar1". Also muss es im Javascript stecken... Dies sieht allerdings so aus:
              document.write('<scr'+'ipt language="JavaScript" type="text/javascript" src="TDE_RCalendar/yahoo.js"></scr'+'ipt>');
              document.write('<scr'+'ipt language="JavaScript" type="text/javascript" src="TDE_RCalendar/event.js"></scr'+'ipt>');
              document.write('<scr'+'ipt language="JavaScript" type="text/javascript" src="TDE_RCalendar/dom.js"></scr'+'ipt>');

              document.write('<scr'+'ipt language="JavaScript" type="text/javascript" src="TDE_RCalendar/calendar.js"></scr'+'ipt>');
              document.write('<scr'+'ipt language="JavaScript" type="text/javascript" src="TDE_RCalendar/TDERCalendar.js"></scr'+'ipt>');
              document.write('<link rel="stylesheet" type="text/css" href="TDE_RCalendar/R_public.css" />');

              Das heisst, es ist etwas mehr Arbeit.

              Kurz und gut, ich möchte nur den Wert von "id" aus der Browserzeile bei Bedarf haben - ist es daher nicht ehr klug diese zu zerlegen und wenn ein ?id=wert angehängt ist, ihn von dort zu holen? z.B. 'REQUEST_URI'?

              HeikoH

              1. Hello Heiko,

                da wirst Du dann wohl nicht drum herum kommen, und erstmal alle Scripte zusammensammeln müssen.

                Letztlich kannst Du an die URL im action-Attribut des <form>-Elementes auch noch Get-Parameter anhängen. Wenn die in den JavaScript-Scripts nicht wieder überschrieben werden (vermutlich dann in der Funktion validateme(this) ), dann solltest Du sie nachher auch in $_GET wiederfinden.

                Das wäre doch mal einen Versuch wert.

                Liebe Grüße

                Tom vom Berg

                --
                Nur selber lernen macht schlau
      2. Nur nebenbei: Wenn ich ein ganz böser Mensch wäre, würde ich in der Adressleiste meines Browsers '…?id=0 or true' eintippen und darauf spekulieren, dass du (wie ja tatsächlich oben zu sehen) den Parameter id ungefiltert und ungesichert in deinen SQL-Befehl einfügst: 'SELECT * FROM travelplan WHERE UserId = 0 or true'. Und nun lasse dir mal durch den Kopf gehen, was da passiert …
        ...noch nichts, da es ja nicht funktioniert, sondern wie oben beschrieben die Ausgaben ist - aber ich werde es ausprobieren denn ich hab keine Idee was passiert - bin aber auch kein Profi

        Was Gonzo versuchte dir klarzumachen:
        Du darfst den Inhalt von Variablen nicht einfach ungeprüft übernehmen, ohne allerwenigstens strip_tags() drauf anzuwenden und den Inhalt der Variablen auf erlaubte Werte zu Prüfen. Tust du das nicht, kann man deinem Programm Funktionen einbauen, von denen du noch nicht mal Ahnung hattest daß es sie gibt.

        1. Hello,

          Was Gonzo versuchte dir klarzumachen:
          Du darfst den Inhalt von Variablen nicht einfach ungeprüft übernehmen, ohne allerwenigstens strip_tags() drauf anzuwenden

          Gerade diese Funktion ist bei der Übernahme von Werten aus dem Request nicht hilfreich.
          In diesem oben beschreibenen Falle wäre es besser,

          a) $id = 0;
               if (iiset($_GET['id'])
               {
                   $id = intval($_GET['id'])
               }

          zu benutzen und dafür zu sorgen, dass die ID 0 ein neutrales Element ist, also eine, die als gültiger Wert nicht vorkommt.

          und den Inhalt der Variablen auf erlaubte Werte zu Prüfen.

          Das ist natürlich richtig, aber nur ein Allgemeinplatz, mit dem jemand, der sich noch nicht mit Intrusion und Injection beschäftigt hat, daher überhaupt nichts anfangen kann.

          Die Funktion strip_tags() oder besser die Funktion htmlspecialchars() benutzt man dann, wenn man allgemeine Eingaben des Client (in denen eigentlich jeder Wert erlaubt ist) in den HTML-Kontext zurück sendet, also i.d.R. an den Browser. Dadurch verhindert man das "Zerschießen" der Response-Seite und auch unerwünschte Script-Übungen des Clients.

          Liebe Grüße

          Tom vom Berg

          --
          Nur selber lernen macht schlau
          1. Gerade diese Funktion ist bei der Übernahme von Werten aus dem Request nicht hilfreich.
            In diesem oben beschreibenen Falle wäre es besser,

            a) $id = 0;
                 if (iiset($_GET['id'])
                 {
                     $id = intval($_GET['id'])
                 }

            Da hast du natürlich recht. Ich nutze auf meinen Seiten eine extra Funktion, die aus den übergebenen Werten alles ausbaut was da nicht reingehört, und da ist strip_tags() nur ein kleiner Teil davon. Die optimale Methode, übergebene Werte von allem "feindlichen" zu befreien suche ich selbst noch, immer wieder gibt es denkbare Szenarien was falsch laufen könnte.

            Entscheidend ist, sich darüber überhaupt mal Gedanken zu machen. Wenn es ganz einfach ist, mal eben was in der Adresszeile zu fummeln, wird das sicher irgendwann gemacht. Je weniger Erfolg der "Angreifer" damit hat, desto eher wird er die Lust verlieren. Professionelle Internetauftritte wie Amazon oder dergleichen sind da noch ganz anderen Gefahren ausgesetzt, weil man da nicht nur den Betreiber ärgern kann in dem man seine kleine Datenbank löscht, sondern weil da unter Umständen richtig Kohle zu machen ist.

          2. Die Funktion strip_tags() oder besser die Funktion htmlspecialchars() benutzt man dann, wenn man allgemeine Eingaben des Client (in denen eigentlich jeder Wert erlaubt ist) in den HTML-Kontext zurück sendet, also i.d.R. an den Browser. Dadurch verhindert man das "Zerschießen" der Response-Seite und auch unerwünschte Script-Übungen des Clients.

            Ich verstehe überhaupt nix davon...
            Sorry
            Ich werde anscheinend $_GET[id] nicht einsetzen können, da diese Variable schon besetzt ist durch das Javascript vom Kalenderhersteller.
            Ich dachte mit $_GET kann ich auslesen was in der Browserzeile hinter ? angehangen wird - da muss es aber nochmehr geben, wie schon beschrieben von Euch, vielleicht werde ich es mit einer Funktion versuchen, die die Browserzeile ausliesst um sie dann zu zerlegen um an den Wert $id von dort zu kommen. Bevor ich das vorgefertige Kalenderscript zerlegen um ungewissen Ausgang...

            HeikoH

        2. Was Gonzo versuchte dir klarzumachen:
          Du darfst den Inhalt von Variablen nicht einfach ungeprüft übernehmen, ohne allerwenigstens strip_tags() drauf anzuwenden und den Inhalt der Variablen auf erlaubte Werte zu Prüfen. Tust du das nicht, kann man deinem Programm Funktionen einbauen, von denen du noch nicht mal Ahnung hattest daß es sie gibt.

          Ein guter Rat - ich werde ihn auch befolgen. Jetzt möchte ich es erstmal so einfach wie möglich, da ich es nur auf meinen localhost probiere. Das Schützen kommt später, wenn alles funktioniert.

          HeikoH

      3. if (isset($_GET['id']) && ($_GET['id'] != ''))
        $id = $_GET['id'];
        hab noch ein wenig probiert - hier muss ein Problem sein - es wird 'RCalendar1' ausgegeben

        Wo genau, welche Variable, mit welchem Code?

        • Wenn in $_GET["id"] 'RCalendar1' steht, dann würdest du jetzt schon mal wissen, dass das Problem nicht $_GET selber ist, sondern noch weiter vorne liegen muss. Dort, wo die URL bzw. die URL-Parameter zusammengebastelt werden, wird eine URL à la "bla.php?id=RCalendar1" erzeugt.

        • Falls du hingegen $id nach dem if-Block ausgegeben hast, dann besteht immer noch die Möglichkeit, dass der falsche Wert aus $_SESSION komt.

        Nur nebenbei: Wenn ich ein ganz böser Mensch wäre, würde ich in der Adressleiste meines Browsers '…?id=0 or true' eintippen und darauf spekulieren, dass du (wie ja tatsächlich oben zu sehen) den Parameter id ungefiltert und ungesichert in deinen SQL-Befehl einfügst: 'SELECT * FROM travelplan WHERE UserId = 0 or true'. Und nun lasse dir mal durch den Kopf gehen, was da passiert …

        ich hab keine Idee was passiert - bin aber auch kein Profi

        Dein SQL-Befehl endet dann folgendermaßen: 'where id=0 or true'. Die Bedingung 'id=0 or true' ist wegen es 'or true' immer erfüllt, damit wird auch der vorangehende Befehl _sämtliche_ Daten betreffen, nicht nur die für id=0 zutreffenden.
        Ist id zum Beispiel die Nutzernummer, lassen sich mit '?id=0 or true' auch die Daten aller anderen Nutzer ausgeben.