Nelly: Sicherheit beim Upload

0 133

Sicherheit beim Upload

  1. 0
    1. 1
      1. 0
        1. 0
          1. 0

            $_FILES[<name>]['tmp_name']

            1. 0
              1. 0
                1. 0
                  1. 0

                    Dateiupload, was tut move_uploaded_file() wirklich?

                    1. 0
                      1. 0

                        Rumpaulerei

                        1. 0
                          1. 0

                            Gültigkeit von Funktionen für den Dateiupload

                            1. 0
                              1. 0
                                1. 0
                                  1. 0
                                    1. 0
                                      1. 0
                                        1. 0
                                          1. 0
                                            1. 0
                                              1. 0
                                                1. 0
                                                  1. 0
                                                    1. 0
                                                  2. 0
                                                    1. 0
                                    2. 0
                                      1. 0
                            2. 0
                              1. 0
                            3. 1
                              1. 0
                                1. 0
                                  1. 0
                                    1. 0
                                      1. 0
                                        1. 0
                    2. 0
                      1. 0
                        1. 0
                          1. 0
                2. 1
                3. 4
                  1. 0

                    Der Wert von alten PHP-Funktionen

            2. 0

              Das geht auch anständiger!

              1. 0
                1. 1
              2. 0
    2. 0
      1. 0
        1. 0
        2. 7
          1. 1
            1. 0
            2. 0
              1. 0
                1. 0
                  1. 0
                    1. 0
                  2. 0
          2. 0
            1. 0
              1. 0
                1. 0
                2. 2
                  1. 0
                    1. 2
                3. 0
                  1. 0
                    1. 0
            2. 3
            3. 3
              1. 2
                1. 0
                  1. 0
                    1. 0
                      1. 0
                        1. -1
                          1. 0
                            1. 0
                          2. 0
                            1. 0
                              1. 0
                                1. 0
                                  1. 0
                                    1. 0
                                      1. 0
                                      2. 2
                                        1. 0
                                        2. 0
                                          1. 0
                                            1. 0
                                              1. 0
                                                1. 0
                                                  1. 1
                                                    1. 0
                                                      1. 0
                                                      2. 3
                                                  2. 0
                                                    1. 0
                                                      1. 2
                                                      2. 3
                                                        1. 0
                                                          1. 0
                                                            1. 0
                                                          2. 0
                      2. 2
                      3. 3
    3. 0

      Alle OOP-Konzepte, die ich bisher kennengelernt habe...

    4. 0
      1. 0
        1. 0

          Sicherheit beim Upload, Ergänzung zu open_basedir

        2. 1
        3. 0
          1. 0
            1. 0
              1. 0
                1. 0
                  1. 0
                    1. 0
                      1. 0
                        1. 0
                          1. 0
                            1. 0
                              1. 0
                          2. 0
        4. 1
  2. 1
    1. 0
  3. 0

Ich lade ein Bild hoch, bevor ich es abspeichere überprüfe ich ob es sich um ein jpg handelt.
Muss ich sonst noch etwas beachten um WIRKLICH nur JPGs zu bekommen?

  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  
"http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<title>Bild abspeichern</title>  
</head>  
<body>  
  
<?php  
  
if((isset($_POST['submit']))&&(!empty($_FILES['bild']['tmp_name'])))  
	{	  
	$picture_info = getimagesize ($_FILES['bild']['tmp_name']);  
	if ($picture_info[2]==2) // nur JPG  
		{  
		if ( move_uploaded_file ( $_FILES['bild']['tmp_name'], 'abgespeichertes_bild.jpg' ) )  
			{  
			  echo '<b>Upload beendet!</b>';  
			}  
		else  
			{  
			echo'Fehler beim abspeichern';  
			}  
		}	  
	else  
		{  
		echo 'Dies ist kein zulässiges Bildformat!';  
		}  
	}  
  
?>  
  
<form method="POST" enctype="multipart/form-data" action="bild.php">  
<input class="form_eingabe" type="file" name="bild">  
<input class="button" type="submit" value="Abspeichern" name="submit">	  
</form>  
  
</body>  
</html>  
  

  1. Hello,

    Ich lade ein Bild hoch, bevor ich es abspeichere überprüfe ich ob es sich um ein jpg handelt.
    Muss ich sonst noch etwas beachten um WIRKLICH nur JPGs zu bekommen?

    siehe
    https://forum.selfhtml.org/?t=206724&m=1403946
    http://wiki.selfhtml.org/wiki/Artikel:PHP/File_Upload

      if ( move\_uploaded\_file ( $\_FILES['bild']['tmp\_name'], 'abgespeichertes\_bild.jpg' )  
    

    move_uploaded_file() ist obsolet, wenn man $_FILES benutzt

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hi,

      move_uploaded_file() ist obsolet, wenn man $_FILES benutzt

      Was erzählst du denn schon wieder für einen Unsinn?

      MfG ChrisB

      --
      RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
      1. Hello,

        move_uploaded_file() ist obsolet, wenn man $_FILES benutzt

        Was erzählst du denn schon wieder für einen Unsinn?

        Halt dich doch bitte raus, wenn Du nicht ein einziges Mal wirklich fundierte Fakten liefern kannst.
        Das geht mir jetzt wirklich langsam auf den Senkel!

        Zeig mir die Stellen im Quellcode, die "move_uploaded_file()" besser stellt gegenüber $_FILES[<name>]['error'] == UPLOAD_ER_OK und den abgesicherten Namen $_FILES[<name>]['tmp_name']

        Wo stellt bitte "is_uploaded_file()" und "move_uploaded_file()" sicher, dass das File im Temporärverzeichnis nicht manipuliert wurde?

        Das tut $_FILES[<name>]['tmp_name'] leider auch nicht. Aber solltest Du mir nachweisen können, das die "*_upoladed_file()"-Funktionen hier irgendeine Besserstellung besitzen, dann entschuldige ich mich ganz offiziell bei Dir.

        Das wird aber mMn nicht passieren!

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hi,

          move_uploaded_file() ist obsolet, wenn man $_FILES benutzt

          Was erzählst du denn schon wieder für einen Unsinn?

          Halt dich doch bitte raus, wenn Du nicht ein einziges Mal wirklich fundierte Fakten liefern kannst.
          Das geht mir jetzt wirklich langsam auf den Senkel!

          Und mir geht auf den Senkel, dass du hier immer wieder Quatsch erzählst.
          Wenn dich Hinweise darauf stören - dann versuche bitte, weniger Quatsch zu erzählen.

          Wo stellt bitte "is_uploaded_file()" und "move_uploaded_file()" sicher, dass das File im Temporärverzeichnis nicht manipuliert wurde?

          Wer hat denn überhaupt behauptet, dass es das täte?

          Das tut $_FILES[<name>]['tmp_name'] leider auch nicht. Aber solltest Du mir nachweisen können, das die "*_upoladed_file()"-Funktionen hier irgendeine Besserstellung besitzen, dann entschuldige ich mich ganz offiziell bei Dir.

          Ich brauche dir überhaupt nichts nachweisen, weil ich mich ganz konkret auf deine Aussage

          move_uploaded_file() ist obsolet, wenn man $_FILES benutzt

          bezogen habe - und die ist in der Form nun mal einfach Quatsch.

          move_uploaded_file ist *die* Funktion, die dafür *vorgesehen* ist, eine hochgeladene Datei aus dem Upload-Tempverzeichnis an ihren designierten Zielort zu verschieben - nicht mehr, nicht weniger.
          Zu behaupten, $_FILES mache sie in irgendeiner Weise obsolet, ist einfach nur Unfug und falsch.

          Das wird aber mMn nicht passieren!

          Dass du einsiehst, dass du wieder mal Blödsinn erzählst? Das hängt von dir ab.

          MfG ChrisB

          --
          RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
          1. Hello,

            move_uploaded_file() ist obsolet, wenn man $_FILES benutzt

            Was erzählst du denn schon wieder für einen Unsinn?

            Halt dich doch bitte raus, wenn Du nicht ein einziges Mal wirklich fundierte Fakten liefern kannst.
            Das geht mir jetzt wirklich langsam auf den Senkel!

            Und mir geht auf den Senkel, dass du hier immer wieder Quatsch erzählst.
            Wenn dich Hinweise darauf stören - dann versuche bitte, weniger Quatsch zu erzählen.

            Wo stellt bitte "is_uploaded_file()" und "move_uploaded_file()" sicher, dass das File im Temporärverzeichnis nicht manipuliert wurde?

            Wer hat denn überhaupt behauptet, dass es das täte?

            Das tut $_FILES[<name>]['tmp_name'] leider auch nicht. Aber solltest Du mir nachweisen können, das die "*_upoladed_file()"-Funktionen hier irgendeine Besserstellung besitzen, dann entschuldige ich mich ganz offiziell bei Dir.

            Ich brauche dir überhaupt nichts nachweisen, weil ich mich ganz konkret auf deine Aussage

            move_uploaded_file() ist obsolet, wenn man $_FILES benutzt
            bezogen habe - und die ist in der Form nun mal einfach Quatsch.

            move_uploaded_file ist *die* Funktion, die dafür *vorgesehen* ist, eine hochgeladene Datei aus dem Upload-Tempverzeichnis an ihren designierten Zielort zu verschieben - nicht mehr, nicht weniger.
            Zu behaupten, $_FILES mache sie in irgendeiner Weise obsolet, ist einfach nur Unfug und falsch.

            Das wird aber mMn nicht passieren!

            Dass du einsiehst, dass du wieder mal Blödsinn erzählst? Das hängt von dir ab.

            Ach so, die notwendigen Argumente sind Dir also ausgegangen, und dich mal wirklich einzubringen mund nachzuschauen, wie denn die wahren Zusammenhänge sind, ist Dir zu mühevoll. Diese Community kann Dir also (frei gesagt) am Arsch lecken?

            @all others:
            Entschulödigt bitte, aber ChrisB ist einfach nicht derjenige, der sich wirklich _für__uns__alle_ anstrengen mag. Er kann nur rumpaulen, dies auch unter weiteren Pseudonymen...

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Hi,

              Ach so, die notwendigen Argumente sind Dir also ausgegangen,

              Argumente für was?

              Belege du doch bitte deine Aussage, move_uploaded_file wäre obsolet, erst mal!

              und dich mal wirklich einzubringen mund nachzuschauen, wie denn die wahren Zusammenhänge sind, ist Dir zu mühevoll.

              Dann erkläre doch bitte die Zusammenhänge, die ich nicht sehe.

              Diese Community kann Dir also (frei gesagt) am Arsch lecken?

              Leg mir bitte keine Wort in den Mund.

              @all others:
              Entschulödigt bitte, aber ChrisB ist einfach nicht derjenige, der sich wirklich _für__uns__alle_ anstrengen mag.

              Abgesehen davon, dass du hier gerade eher derjenige zu sein scheinst, dem die sachlichen Argumente ausgehen:
              Dann nenne bitte die Anstrengung, die ich deiner Meinung nach jetzt zu unternehmen hätte.
              Behalte dabei bitte im Auge, dass ich einzig und allein deine Aussage

              move_uploaded_file() ist obsolet, wenn man $_FILES benutzt

              als fachlich falsch kritisiert habe.
              Versuche bitte nicht, wieder auf Nebenschauplätze auszuweichen, sondern erkläre ganz klipp und klar, in wie fern das der Fall sein soll. Benenne also bitte insbesondere die Funktion, die deiner Meinung nach die geeignete und vorgesehen ist, um eine hochgeladene Datei aus dem Tempverzeichnis an ihren Zielort zu verschieben.

              Er kann nur rumpaulen, dies auch unter weiteren Pseudonymen...

              Ich gebe dir jetzt genau eine Chance, das zurück zu nehmen (oder zu belegen), bevor ich dich als Lügner bezeichnen muss.

              (Auch meinen vor Jahren hier verwendeten Nick spielst du doch wohl jetzt nicht an?)

              MfG ChrisB

              --
              RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
              1. Hello,

                Belege du doch bitte deine Aussage, move_uploaded_file wäre obsolet, erst mal!

                Gerne:

                move_uploaded_file() wurde mit (PHP 4 >= 4.0.3, PHP 5) eingeführt.
                Das war der letzte Verusch, die korrumpierbarene Variablen für den Upload abzusichern

                $_FILES wurd dann mit (PHP 4 >= 4.1.0, PHP 5) eingeführt
                Das ist nicht mehr korrumpierbar. Daher sind die *_uploaded_file()-Funktionen obsolet geworden.

                Sie sind für die sensitive Speicherung von Dateien (Überschreiben von vorhandenen wird z.B. verhindert) sogar unbrauchbar.

                Und nun entschuldige Dich!

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
                1. Hi,

                  Belege du doch bitte deine Aussage, move_uploaded_file wäre obsolet, erst mal!

                  Gerne:

                  move_uploaded_file() wurde mit (PHP 4 >= 4.0.3, PHP 5) eingeführt.
                  Das war der letzte Verusch, die korrumpierbarene Variablen für den Upload abzusichern

                  $_FILES wurd dann mit (PHP 4 >= 4.1.0, PHP 5) eingeführt
                  Das ist nicht mehr korrumpierbar.

                  $_FILES stellt lediglich die Daten zur Verfügung, die man braucht, um eine hochgeladene Datei zu verarbeiten bzw. den Upload auszuwerten (hinsichtlich seines Erfolgs).

                  $_FILES sorgt aber *nicht* dafür, die Datei aus dem Upload-Tempverzeichnis heraus zu holen - aus dem sie bei Scriptende automatisch wieder gelöscht wird, wenn man sie nicht woanders hin verschoben hat. Und *genau* *dafür* ist move_uploaded_file da.

                  Daher sind die *_uploaded_file()-Funktionen obsolet geworden.

                  Das ist nach wie vor Unfug.

                  Und nun entschuldige Dich!

                  Dazu habe ich keinen Grund.
                  Du aufgrund deiner dreisten Lüge von gerade eben aber immer noch …

                  MfG ChrisB

                  --
                  RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                  1. Hello,

                    Belege du doch bitte deine Aussage, move_uploaded_file wäre obsolet, erst mal!

                    Gerne:

                    move_uploaded_file() wurde mit (PHP 4 >= 4.0.3, PHP 5) eingeführt.
                    Das war der letzte Verusch, die korrumpierbarene Variablen für den Upload abzusichern

                    $_FILES wurd dann mit (PHP 4 >= 4.1.0, PHP 5) eingeführt
                    Das ist nicht mehr korrumpierbar.

                    $_FILES stellt lediglich die Daten zur Verfügung, die man braucht, um eine hochgeladene Datei zu verarbeiten bzw. den Upload auszuwerten (hinsichtlich seines Erfolgs).

                    Wenn diese Daten abgesichert sind, kann der Programmierer daraus alles andere ableiten. Die zusätzlichen Funktionn sind also obsolet.

                    $_FILES sorgt aber *nicht* dafür, die Datei aus dem Upload-Tempverzeichnis heraus zu holen - aus dem sie bei Scriptende automatisch wieder gelöscht wird, wenn man sie nicht woanders hin verschoben hat. Und *genau* *dafür* ist move_uploaded_file da.

                    Und genau dafür ist es auch unbrauchbar. Denn es überschreibt einfach bereits vorhandene Dateien.

                    Außerdem gab es neulich schon einmal eine Diskussion zu diesem Thema, an der Du dich gerne konstruktiv bteiligen können hättest.

                    Da hätte dann dein "Biss" sogar wichtig sein können, um in den Quellcodes von PHP die Wahrheit zu ergründen. Leider warst Du da nicht anwensend (was ich durchaus noch genauer untersuchen könnte...)

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
                    1. Hi,

                      $_FILES stellt lediglich die Daten zur Verfügung, die man braucht, um eine hochgeladene Datei zu verarbeiten bzw. den Upload auszuwerten (hinsichtlich seines Erfolgs).

                      Wenn diese Daten abgesichert sind, kann der Programmierer daraus alles andere ableiten. Die zusätzlichen Funktionn sind also obsolet.

                      Nein, move_uploaded_file ist nicht obsolet. Unfug wird nicht wahrer dadurch, dass du ihn gebetsmühlenartig wiederholst.

                      $_FILES sorgt aber *nicht* dafür, die Datei aus dem Upload-Tempverzeichnis heraus zu holen - aus dem sie bei Scriptende automatisch wieder gelöscht wird, wenn man sie nicht woanders hin verschoben hat. Und *genau* *dafür* ist move_uploaded_file da.

                      Und genau dafür ist es auch unbrauchbar. Denn es überschreibt einfach bereits vorhandene Dateien.

                      Works as designed.
                      Wenn dieser Effekt nicht gewünscht ist, muss man das halt vorher zusätzlich prüfen. (Ja, dass das ggf. ein TOCTTOU-Problem in sich birgt, ist mir bewusst.)

                      Welche Funktion deiner Meinung nach die geeignetere wäre, um Dateien aus dem Tempverzeichnis an ihren Zielort zu verschieben, hast du übrigens immer noch nicht verlauten lassen.

                      Leider warst Du da nicht anwensend (was ich durchaus noch genauer untersuchen könnte...)

                      Magst du noch elaborieren, in welche Richtung diese amüsante „Drohung“ zu deuten sein soll? :-)

                      MfG ChrisB

                      --
                      RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                      1. Hello,

                        [...]

                        wo steckte denn jetzt der Sachbeitrag?

                        Liebe Grüße aus dem schönen Oberharz

                        Tom vom Berg

                        --
                         ☻_
                        /▌
                        / \ Nur selber lernen macht schlau
                        http://bergpost.annerschbarrich.de
                        1. Hi,

                          wo steckte denn jetzt der Sachbeitrag?

                          Ich habe noch mal explizit deiner fachlich falschen Behauptung widersprochen, dass move_uploaded_file „obsolet“ wäre.

                          Welche Funktion deiner Meinung nach die geeignetere wäre, um Dateien aus dem Tempverzeichnis an ihren Zielort zu verschieben, hast du übrigens immer noch nicht verlauten lassen.

                          Das steht übrigens noch aus - also jetzt bitte mal Butter bei die Fische, Tom.

                          MfG ChrisB

                          --
                          RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                          1. Hello,

                            wo steckte denn jetzt der Sachbeitrag?

                            Ich habe noch mal explizit deiner fachlich falschen Behauptung widersprochen, dass move_uploaded_file „obsolet“ wäre.

                            Welche Funktion deiner Meinung nach die geeignetere wäre, um Dateien aus dem Tempverzeichnis an ihren Zielort zu verschieben, hast du übrigens immer noch nicht verlauten lassen.

                            Das steht übrigens noch aus - also jetzt bitte mal Butter bei die Fische, Tom.

                            Diese Antwort beweist wieder einmal, dass Du dich nicht anstrengen magst für die Gemeinschaft.

                            Denn sonst hättest Du ja wenignstens einmal versucht, einen Tiefenbeweis zu liefern, also zu zeigen, an welcher Stelle im Quelltext $_FILES und seine Elemente [tmp_name], [size] und [error] unsicher sind.

                            Denn meine Aussage lautet ja:
                            $_FILES und seine Elemente [tmp_name], [size] und [error] sind sicher, alle *_uploaded_files()-Funktionen sind daher obsolet(, oder sogar kontraproduktiv).

                            Von Dir habe ich bisher keine sachlichen Begründungen gehört.

                            @Dedlfix: Dass diese Funktionen noch noch nicht auf der Unerwünschtliste stehen, liegt vielleicht daran, dass man sie bisher übersehen hat?

                            Ich würde jedenfalls moderne PHP-Prgogramme nicht nehr darauf aufbauen, schon alleine wege des massiven TOCTTOU-Problemes...

                            Liebe Grüße aus dem schönen Oberharz

                            Tom vom Berg

                            --
                             ☻_
                            /▌
                            / \ Nur selber lernen macht schlau
                            http://bergpost.annerschbarrich.de
                            1. Hallo

                              wo steckte denn jetzt der Sachbeitrag?

                              Ich habe noch mal explizit deiner fachlich falschen Behauptung widersprochen, dass move_uploaded_file „obsolet“ wäre.

                              Welche Funktion deiner Meinung nach die geeignetere wäre, um Dateien aus dem Tempverzeichnis an ihren Zielort zu verschieben, hast du übrigens immer noch nicht verlauten lassen.

                              Das steht übrigens noch aus - also jetzt bitte mal Butter bei die Fische, Tom.

                              Diese Antwort beweist wieder einmal, dass Du dich nicht anstrengen magst für die Gemeinschaft.

                              Denn sonst hättest Du ja wenignstens einmal versucht, einen Tiefenbeweis zu liefern, also zu zeigen, an welcher Stelle im Quelltext $_FILES und seine Elemente [tmp_name], [size] und [error] unsicher sind.

                              Mit Verlaub, das hat er nirgendwo behauptet.

                              Denn meine Aussage lautet ja:
                              $_FILES und seine Elemente [tmp_name], [size] und [error] sind sicher, alle *_uploaded_files()-Funktionen sind daher obsolet(, oder sogar kontraproduktiv).

                              Wie speicherst *du* eine hochgeladene Datei ab, die sich – während der Skriptausführung – im Tempverzeichnis befindet und sich nach dessen Beendigung aus selbigem verflüchtigt. Einfach nur auf die FILES-Elemente zu verweisen wird's doch nicht sein, oder?

                              Tschö, Auge

                              --
                              Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
                              Terry Pratchett, "Wachen! Wachen!"
                              ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
                              Veranstaltungsdatenbank Vdb 0.3
                              1. Hello,

                                Wie speicherst *du* eine hochgeladene Datei ab, die sich – während der Skriptausführung – im Tempverzeichnis befindet und sich nach dessen Beendigung aus selbigem verflüchtigt. Einfach nur auf die FILES-Elemente zu verweisen wird's doch nicht sein, oder?

                                Das wirst Du im meinem Artiekel lesen können, wenn mir die diversen ausstehenden Antworten der PHP-Entwickler zu diesem Thema vorliegen.

                                Liebe Grüße aus dem schönen Oberharz

                                Tom vom Berg

                                --
                                 ☻_
                                /▌
                                / \ Nur selber lernen macht schlau
                                http://bergpost.annerschbarrich.de
                                1. Hi,

                                  Wie speicherst *du* eine hochgeladene Datei ab, die sich – während der Skriptausführung – im Tempverzeichnis befindet und sich nach dessen Beendigung aus selbigem verflüchtigt. Einfach nur auf die FILES-Elemente zu verweisen wird's doch nicht sein, oder?

                                  Das wirst Du im meinem Artiekel lesen können, wenn mir die diversen ausstehenden Antworten der PHP-Entwickler zu diesem Thema vorliegen.

                                  Aha.
                                  Und so lange diese Antworten noch nicht eingetroffen sind, behandelst du gar keine Dateiuploads mehr in PHP?
                                  Nun, das ist deine Entscheidung.
                                  Für den Rest der Welt gilt aber nach wie vor, move_uploaded_file ist *momentan* der dafür *vorgesehene* Weg. Und diesen Fakt wollen wir dem Threadersteller und anderen interessierten nicht vorenthalten (und insb. auch nicht irreführend behaupten, move_uploaded_file wäre ”obsolet“, was es zum jetzigen Zeitpunkt definitiv *nicht* *ist*), insb. so lange wir (konkret gemeint: *du*) keine Alternative anzubieten haben, sondern nur nebulös in die phantastische Zukunft, die da kommen wird, verweisen können …

                                  MfG ChrisB

                                  --
                                  RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                                  1. Hello,

                                    Wie speicherst *du* eine hochgeladene Datei ab, die sich – während der Skriptausführung – im Tempverzeichnis befindet und sich nach dessen Beendigung aus selbigem verflüchtigt. Einfach nur auf die FILES-Elemente zu verweisen wird's doch nicht sein, oder?

                                    Das wirst Du im meinem Artiekel lesen können, wenn mir die diversen ausstehenden Antworten der PHP-Entwickler zu diesem Thema vorliegen.

                                    Aha.
                                    Und so lange diese Antworten noch nicht eingetroffen sind, behandelst du gar keine Dateiuploads mehr in PHP?

                                    Das wäre jetzt zumindest der Trugschluss, bzw. eine mögliche Schlussfolgerung aus meiner Aussage. Aber sei versichert, ich bleibe trotzdem dran...

                                    Nun, das ist deine Entscheidung.

                                    Danke, dass Du mir diese Freiheit lässt.

                                    Für den Rest der Welt gilt aber nach wie vor, move_uploaded_file ist *momentan* der dafür *vorgesehene* Weg.

                                    Nö, denn dass das obsolet ist, ahbe ich schon früher verkündet. Und keiner konnte wirklich widersprechen.

                                    Und diesen Fakt wollen wir dem Threadersteller und anderen interessierten nicht vorenthalten

                                    genau. Die Welt dreht sich weiter.

                                    (und insb. auch nicht irreführend behaupten, move_uploaded_file wäre ”obsolet“, was es zum jetzigen Zeitpunkt definitiv *nicht* *ist*), insb. so lange wir (konkret gemeint: *du*) keine Alternative anzubieten haben, sondern nur nebulös in die phantastische Zukunft, die da kommen wird, verweisen können …

                                    Das kannst Du jetzt doch nicht wirklich meinen?

                                    Ich wiederhole es aber jetzt aber auch gerne auch nochmal für alle Diejenigen, die schwer von Begriff sind:

                                    die Funktionen *_uploaded_file() sind daher obsolet, weil durch die Einführung des abgesicherten Arrays $_FILES die Elemente [tmp_name], [size] und [error] sicher geworden sind.

                                    Um festzustellen, ob ein File fehlerfrei hochgeladen wurde, sollte also in Zukunft der absoute Vergleich (Identität) des Fehlerstatus [error] mit den vordefinierten Fehlerkonstanten reichen und ob ein File Inhalt hat, die anschließende Abfrage von $_FILES['size']

                                    Um das File zu verschieben, sollte man die generischen handlebsaierten Funktionen

                                    • fopen()
                                    • flock()
                                    • fread()
                                    • fwrite()

                                    benutzen.

                                    Alle anderen haben Mängel. (...)

                                    Liebe Grüße aus dem schönen Oberharz

                                    Tom vom Berg

                                    --
                                     ☻_
                                    /▌
                                    / \ Nur selber lernen macht schlau
                                    http://bergpost.annerschbarrich.de
                                    1. Hi,

                                      Für den Rest der Welt gilt aber nach wie vor, move_uploaded_file ist *momentan* der dafür *vorgesehene* Weg.

                                      Nö, denn dass das obsolet ist, ahbe ich schon früher verkündet. Und keiner konnte wirklich widersprechen.

                                      Dir wurde widersprochen, und inzwischen sogar schon von mehreren Seiten.

                                      Ich wiederhole es aber jetzt aber auch gerne auch nochmal für alle Diejenigen, die schwer von Begriff sind:

                                      Sorry, aber das bist hier einzig und allein nur du.

                                      Um festzustellen, ob ein File fehlerfrei hochgeladen wurde, sollte also in Zukunft der absoute Vergleich (Identität) des Fehlerstatus [error] mit den vordefinierten Fehlerkonstanten reichen und ob ein File Inhalt hat, die anschließende Abfrage von $_FILES['size']

                                      Um das File zu verschieben, sollte man die generischen handlebsaierten Funktionen

                                      • fopen()
                                      • flock()
                                      • fread()
                                      • fwrite()

                                      benutzen.

                                      Aha, deine so heiß geliebten „handlebasierten“ kleinen Freunde schon wieder.
                                      Ich vergaß, wie gern du eigentlich simple kleine Aufgaben unnötig verkomplizierst …

                                      MfG ChrisB

                                      --
                                      RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                                      1. Hello,

                                        Dir wurde widersprochen, und inzwischen sogar schon von mehreren Seiten.

                                        Klar, Gallileo musste auch widerrufen.
                                        Nur dessen "Widersacher" warn nicht so klar erkennbar und außerdem glaube ich, dass ich meine Meinung heutzutage trotzdem vertreten darf. Bitte beteilige dich konstruktiv am Thread, so wie z.B. Sven es tut https://forum.selfhtml.org/?t=206726&m=1403982, auch wenn er es nur einseitig tut. Wenn es ihm um die Sache ginge, könnte er ja auch schon mal den Quelltext zur Bildung von $_FILES heraussuchen. Dass er das nicht getan hat, ist sicherlich nur ein Versehen.

                                        Denn es geht hier ja nicht um um einen Wettkampf, sondern um die Ermittlung der "Wahrheit". Wozu sollte Open Source sonst gut sein?

                                        Solltet Ihr andere Ambitionen haben, müsst Ihr bitte auf mich verzichten...

                                        Liebe Grüße aus dem schönen Oberharz

                                        Tom vom Berg

                                        --
                                         ☻_
                                        /▌
                                        / \ Nur selber lernen macht schlau
                                        http://bergpost.annerschbarrich.de
                                        1. Hi,

                                          Dir wurde widersprochen, und inzwischen sogar schon von mehreren Seiten.

                                          Klar, Gallileo musste auch widerrufen.

                                          Amüsant, dein Größenwahn.

                                          Nur dessen "Widersacher" warn nicht so klar erkennbar und außerdem glaube ich, dass ich meine Meinung heutzutage trotzdem vertreten darf.

                                          Darfst du. Und ebenso dürfen wir dich wohl darauf hinweisen, dass du fachlich falsch liegst.

                                          Bitte beteilige dich konstruktiv am Thread, so wie z.B. Sven es tut https://forum.selfhtml.org/?t=206726&m=1403982, auch wenn er es nur einseitig tut. Wenn es ihm um die Sache ginge, könnte er ja auch schon mal den Quelltext zur Bildung von $_FILES heraussuchen. Dass er das nicht getan hat, ist sicherlich nur ein Versehen.

                                          Vielleicht will er sich auch nur nicht so viel Arbeit machen - sondern sieht die Bringschuld, deinen Unfug zu untermauern zu versuchen, eher bei dir?

                                          Solltet Ihr andere Ambitionen haben, müsst Ihr bitte auf mich verzichten...

                                          Bisschen spät für deinen Rückzug - inzwischen kann man da nur noch vom sprichwörtlichen „wegrennen mit eingezogenem Schwanz“ reden.

                                          MfG ChrisB

                                          --
                                          RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                                          1. Hello,

                                            Vielleicht will er sich auch nur nicht so viel Arbeit machen - sondern sieht die Bringschuld, deinen Unfug zu untermauern zu versuchen, eher bei dir?

                                            Du bist einfach zu faul, konstruktiv mitzuarbeiten. Sven tut das doch auch, obwohl er anderer Meinung ist. Wieso kannst Du das nicht?

                                            Liebe Grüße aus dem schönen Oberharz

                                            Tom vom Berg

                                            --
                                             ☻_
                                            /▌
                                            / \ Nur selber lernen macht schlau
                                            http://bergpost.annerschbarrich.de
                                            1. Hi,

                                              Vielleicht will er sich auch nur nicht so viel Arbeit machen - sondern sieht die Bringschuld, deinen Unfug zu untermauern zu versuchen, eher bei dir?

                                              Du bist einfach zu faul, konstruktiv mitzuarbeiten. Sven tut das doch auch, obwohl er anderer Meinung ist. Wieso kannst Du das nicht?

                                              Weil ich es leid bin, wiederholt mit dir ellenlange Diskussionen führen zu müssen einzig und allein deshalb, weil du nicht weißt, wo von du redest, und trotzdem stur auf deinem falschen Standpunkt beharrst.

                                              Wenn es dir so wichtig ist, deine fachliche Reputation hier zu wahren - dann verstehe ich echt nicht, warum du sie selber immer wieder auf diesem Wege untergräbst. Du erweist dir damit echt einen Bärendienst.

                                              MfG ChrisB

                                              --
                                              RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                                              1. Hello,

                                                Du bist einfach zu faul, konstruktiv mitzuarbeiten. Sven tut das doch auch, obwohl er anderer Meinung ist. Wieso kannst Du das nicht?

                                                Weil ich es leid bin, wiederholt mit dir ellenlange Diskussionen führen zu müssen einzig und allein deshalb, weil du nicht weißt, wo von du redest, und trotzdem stur auf deinem falschen Standpunkt beharrst.

                                                Im Gegensatz zu dir weiß ich schon, wovon ich rede.

                                                Liebe Grüße aus dem schönen Oberharz

                                                Tom vom Berg

                                                --
                                                 ☻_
                                                /▌
                                                / \ Nur selber lernen macht schlau
                                                http://bergpost.annerschbarrich.de
                                                1. Hi,

                                                  [...]

                                                  Sagt mal, geht das hier auch mal weiter?
                                                  Ich muss gleich einkaufen und will wissen, ob ich noch Popcorn kaufen soll. Meins ist heute mittag leider ausgegangen.

                                                  Bis die Tage,
                                                  Matti

                                                  1. [latex]Mae  govannen![/latex]

                                                    Sagt mal, geht das hier auch mal weiter?
                                                    Ich muss gleich einkaufen und will wissen, ob ich noch Popcorn kaufen soll. Meins ist heute mittag leider ausgegangen.

                                                    Popcorn kaufen? Das ist nur was für Luschen. Man kauft natürlich Aktien von Popcorn-Herstellern ;) (ok, die schmecken natürlich nicht ganz so gut; oder habe ich da was mißverstanden? ^^)

                                                    Stur lächeln und winken, Männer!
                                                    Kai

                                                    --
                                                    Dank Hixies Idiotenbande geschieht grade eben wieder ein Umdenken
                                                    in Richtung "Mess up the Web".(suit)
                                                    SelfHTML-Forum-Stylesheet
                                                    1. Moin Kai,

                                                      […] oder habe ich da was mißverstanden? ^^)

                                                      Bei den großen Flamewars im Usenet hat es sich damals eingebürgert, dass man nach Popcorn ruft, um zu signalisieren, dass man sich ob der Flamerei amüsiert.

                                                      Stur lächeln und winken, Männer!

                                                      Coole Signatur ;-) Die Pinguine rocken.

                                                      LG,
                                                       CK

                                                  2. Hello,

                                                    Hi,

                                                    [...]

                                                    Sagt mal, geht das hier auch mal weiter?
                                                    Ich muss gleich einkaufen und will wissen, ob ich noch Popcorn kaufen soll.

                                                    *ROTFL*

                                                    Naja, ich lege nicht unbedingt Wert auf Popcorn. Ich mag selber auch lieber Zwiebelringe.
                                                    Aber deshalb ist die Duskussion trotzdem noch nicht zu Ende und ich denek, dass es durchaus noch den Einen oder Anderen geben könnte, der am Ende nicht mehr auf mir rumhackt, sondern einsichtig wird ;-P

                                                    Daher hier nochmal kurz zusammengefasst meine Thesen:

                                                    • Uploads sind von Haus aus gefährlich
                                                    • Man muss diverse Maßnahmen ergreifen, um Uploads ungefährlich zu machen
                                                    • Die *_uploaded_file()-Funktionen sind zu einer Zeit entstanden, als $_FILES noch nicht
                                                        existiert hat
                                                    • Durch konsequente Verwendung der (neuen) Superglobalen Arrays (hier $_FILES) kann man auf die
                                                        *_uploaded_file()-Funktionen verzichten, ohne einen Sicherheitsverlust zu erleiden
                                                    • move_uploaded_file() hat gravierende Mängel für das kollaborative Arbeiten, also den
                                                        konkurrierenden Betrieb, der in Webapplikationen eigentlich vorherrschend ist.

                                                    Alle in diesem Thread bisher (von Anderen) vorgeschlagenen altenativen Vorgehensweisen zu move_uploaded_file() waren fehlerhaft. CK war aber schon dicht dran... :-)

                                                    Ich empfehle daher nochmals allen, den Artikel von Christian Seiler zu lesen
                                                    http://aktuell.de.selfhtml.org/artikel/programmiertechnik/dateisperren/

                                                    Ich gehe jetzt erstmal schlafen. Der Einsatz war mörderisch...

                                                    Bis morgen. :-)

                                                    Liebe Grüße aus dem schönen Oberharz

                                                    Tom vom Berg

                                                    --
                                                     ☻_
                                                    /▌
                                                    / \ Nur selber lernen macht schlau
                                                    http://bergpost.annerschbarrich.de
                                                      • Durch konsequente Verwendung der (neuen) Superglobalen Arrays (hier $_FILES) kann man auf die
                                                          *_uploaded_file()-Funktionen verzichten, ohne einen Sicherheitsverlust zu erleiden

                                                      Ohne Sicherheitsverlust? Du behauptest seit gefühlten 200 Posts, dass *_uploaded_file() grundsätzlich unsicher ist, wie passt das zusammen?

                                    2. Alle anderen haben Mängel. (...)

                                      Und diese Mängel sind so gravierend, dass man riskieren sollte durch eine fehlerhafte Implementierung eine Sicherheitslücke zu schaffen?

                                      In diesem Fall wüsste ich gerne, welche solch gravierenden Mängel vorhanden sind. Evtl. überleg ich mir dann, ob ich mein move_uploaded_file durch eine Funktion nach deiner Vorstellung ersetze.

                                      1. Hello,

                                        In diesem Fall wüsste ich gerne, welche solch gravierenden Mängel vorhanden sind. Evtl. überleg ich mir dann, ob ich mein move_uploaded_file durch eine Funktion nach deiner Vorstellung ersetze.

                                        Ach, weißt Du, wenn ich mich schon aufs Glatteis begebe, dann bitte vollständig.
                                        https://forum.selfhtml.org/?t=206726&m=1403982

                                        Und wenn Du auf dieser Ebene weiter diskutieren magst (mir Unterweisung geben magst, denn  ich habe da bestimmt noch Nachholbedarf), dann freue ich mich auf deine Beiträge.

                                        Liebe Grüße aus dem schönen Oberharz

                                        Tom vom Berg

                                        --
                                         ☻_
                                        /▌
                                        / \ Nur selber lernen macht schlau
                                        http://bergpost.annerschbarrich.de
                            2. Hi,

                              Diese Antwort beweist wieder einmal, dass Du dich nicht anstrengen magst für die Gemeinschaft.

                              So lange „die Gemeinschaft“ nur aus dem einzigen Mitglied „beleidigte Leberwurst Tom“ besteht, mag ich das in der Tat nicht.

                              Denn sonst hättest Du ja wenignstens einmal versucht, einen Tiefenbeweis zu liefern, also zu zeigen, an welcher Stelle im Quelltext $_FILES und seine Elemente [tmp_name], [size] und [error] unsicher sind.

                              Ich *habe* *nicht* *behauptet*, dass diese „unsicher“ wären.
                              Ernsthaft, welchen Sinn soll eine Diskussion mit dir haben, wenn du nicht mal richtig lesen kannst?

                              Ansonsten: *Zeige* mir bitte die Stelle, wo ich das angeblich getan habe.
                              (Aber nicht wieder lügen, gelle?)

                              Denn meine Aussage lautet ja:
                              $_FILES und seine Elemente [tmp_name], [size] und [error] sind sicher, alle *_uploaded_files()-Funktionen sind daher obsolet(, oder sogar kontraproduktiv).

                              Nach wie vor: Quatsch. (Explizit, damit du das nicht auch wieder falsch verstehst: Bezogen auf den zweiten Teil, move_uploaded_file wäre obsolet.)

                              Von Dir habe ich bisher keine sachlichen Begründungen gehört.

                              Das Manual besagt ganz klar und deutlich, dass move_uploaded_file die vorgesehene Funktion *ist*, um eine hochgeladene Datei aus dem Tempverzeichnis an ihren Zielort zu verschieben.
                              Ich sehe nicht, was ich dir daran noch „begründen“ müsste - es steht schlicht und einfach schwarz auf weiß da.

                              @Dedlfix: Dass diese Funktionen noch noch nicht auf der Unerwünschtliste stehen, liegt vielleicht daran, dass man sie bisher übersehen hat?

                              Oder daran, dass du mit deiner obskuren Einschätzung bezüglich der Funktion schlicht und einfach alleine auf weiter Flur stehst …?

                              Ich würde jedenfalls moderne PHP-Prgogramme nicht nehr darauf aufbauen, schon alleine wege des massiven TOCTTOU-Problemes...

                              Gut, dass ich dir das Stichwort im Verlauf des Threads geliefert habe, nicht wahr? :-)

                              MfG ChrisB

                              --
                              RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                              1. Hello,

                                Ich würde jedenfalls moderne PHP-Prgogramme nicht nehr darauf aufbauen, schon alleine wege des massiven TOCTTOU-Problemes...

                                Gut, dass ich dir das Stichwort im Verlauf des Threads geliefert habe, nicht wahr? :-)

                                Ja danke.

                                Ich musste es erst nachschlagen.

                                Was bedeutet das überhaupt?

                                Hat das überhaupt schon mal jemand behandelt in diesem Forum?

                                Liebe Grüße aus dem schönen Oberharz

                                Tom vom Berg

                                --
                                 ☻_
                                /▌
                                / \ Nur selber lernen macht schlau
                                http://bergpost.annerschbarrich.de
                            3. Hi,

                              ein Punkt, den du bisher garantiert übersehen hast, weil du ja so damit beschäftigt bist zu geifern und dich vergeblich bemühst, hinsichtlich deiner Unsinnsaussage “truth by repetition” zu erreichen:

                              Denn sonst hättest Du ja wenignstens einmal versucht, einen Tiefenbeweis zu liefern, also zu zeigen, an welcher Stelle im Quelltext $_FILES und seine Elemente [tmp_name], [size] und [error] unsicher sind.

                              Dazu braucht man gar nicht besonders in die Tiefe gehen, sondern nur mal hypothetisch den Fall betrachten, dass du nicht nur ein Script schreibst, welches vollkommen deiner Kontrolle unterliegt - sondern eines, das sich in eine andere Umgebung einfügt, sagen wir mal beispielsweise ein Plugin für eine verbreitetes System wie WordPress o.ä.

                              Da kannst du dir die „Sicherheit“ deiner Einträge in $_FILES nämlich schlicht und einfach in die Haare schmieren (sofern du sie dir im Verlaufe dieses Threads nicht schon alle ausgerupft hast) - weil du zu dem Zeitpunkt, wo dein Code letztendlich ausgeführt wird, gar nicht sagen kannst, welche anderen, nicht von dir stammenden Code-Teile den Inhalt von $_FILES nicht vielleicht schon *vorher* manipuliert haben:

                              $_FILES['foo']['tempname'] = 'Tom_erzaehlt_gerne_Quark.txt';  
                              $_FILES['foo']['size'] = 4711;  
                              $_FILES['foo']['error'] = UPLOAD_ERR_TOM_TALKS_NONSENSE;
                              

                              Wie Sven gerade auch noch mal bekräftigt hat, führt move_uploaded_file einige Prüfungen durch, um sicherzustellen, dass die Datei, die verschoben werden soll, auch tatsächlich aus einem gerade vor Scriptstart durchgeführten Upload stammt.

                              Und jetzt erkläre du, oh Weisheit mit Löffeln gefressen Habender, uns doch bitte mal, wie du das im geschilderten, in der Praxis wohl durchaus plausiblen Szenario allein unter Nutzung des gerade eben wie gezeigt manipulierten Arrays $_FILES machst, ohne das „obsolete“ move_uploaded_file zu benuzten …?

                              MfG ChrisB

                              --
                              RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                              1. Hello,

                                [code lang=php]$_FILES['foo']['tempname'] = 'Tom_erzaehlt_gerne_Quark.txt';

                                Da hat der Programmierer ChrisB ja auch geschlafen!

                                Hat er das jetzt absichtlich getan, um TOM ztu schaden?
                                Oder hat er das getan, weil einfach blöd ist?
                                Oder...

                                Liebe Grüße aus dem schönen Oberharz

                                Tom vom Berg

                                --
                                 ☻_
                                /▌
                                / \ Nur selber lernen macht schlau
                                http://bergpost.annerschbarrich.de
                                1. Hi,

                                  [code lang=php]$_FILES['foo']['tempname'] = 'Tom_erzaehlt_gerne_Quark.txt';

                                  Da hat der Programmierer ChrisB ja auch geschlafen!

                                  Hat er das jetzt absichtlich getan, um TOM ztu schaden?
                                  Oder hat er das getan, weil einfach blöd ist?

                                  Und du wagst es dich an anderer Stelle noch, anderen vorzuwerfen, sie hätten keine fachlichen Argumente?

                                  An jeder Stelle, wo dir hier fachliche Argumente entgegen gehalten werden, auf die du keine fachliche Erwiderung findest, flüchtest du dich in Ironie (oder was du dafür hältst), und jetzt reicht es bei dir sogar nicht mal mehr zu mehr als sowas …? Ist das armselig.

                                  Deine selbstherrliche Art, gepaart mit der absoluten Uneinsichtigkeit bzw Unfähigkeit, mal zuzugeben, wenn du fachlich schlicht und einfach falsch liegst, kotzt mich langsam an. Wie man so wenig Eier haben kann wie du, wenn es darum geht, mal einen fachlichen Irrtum schlicht und einfach einzugestehen, ist mir echt schleierhaft …

                                  MfG ChrisB

                                  --
                                  RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                                  1. Hello Chris,

                                    [code lang=php]$_FILES['foo']['tempname'] = 'Tom_erzaehlt_gerne_Quark.txt';

                                    Da hat der Programmierer ChrisB ja auch geschlafen!

                                    Hat er das jetzt absichtlich getan, um TOM ztu schaden?
                                    Oder hat er das getan, weil einfach blöd ist?

                                    Und du wagst es dich an anderer Stelle noch, anderen vorzuwerfen, sie hätten keine fachlichen Argumente?

                                    Habe ich dich da eben missverstanden? Dann tut es mir leid.
                                    Was wolltest Du denn mit dem Codeschnipsel sagen?

                                    Sollte das eventuell heißen:

                                    $_FILES['foo']['tmp_name'] = 'Chris ist auch nicht schlecht im Quarkerzählen.php';

                                    Wolltest Du damit also beweisen, dass der _Scriptautor_ den Dateinamen manipulieren kann? Der kann alles manipulieren. Er wird nur durch eine saubere Systemeinrichtung daran gehindert, mit seinen Scripten Schadcode wirksam werden zu lassen. Dass der sich selber schädigt, kann man nicht verhindern.

                                    Wichtig ist doch, dass der User des Systems (also der Client) keine Manipulationen mehr vornehmen kann. Das konnte er durch die alten Files-Variablen und register_globals vermutlich.

                                    Liebe Grüße aus dem schönen Oberharz

                                    Tom vom Berg

                                    --
                                     ☻_
                                    /▌
                                    / \ Nur selber lernen macht schlau
                                    http://bergpost.annerschbarrich.de
                                    1. Hi,

                                      Wolltest Du damit also beweisen, dass der _Scriptautor_ den Dateinamen manipulieren kann? Der kann alles manipulieren. Er wird nur durch eine saubere Systemeinrichtung daran gehindert, mit seinen Scripten Schadcode wirksam werden zu lassen. Dass der sich selber schädigt, kann man nicht verhindern.

                                      Ein Szenario, in dem $_FILES für dich als Ersteller eines Teil-Scriptes nicht verlässlich sein kann, hatte ich gerade genannt. Bitte stelle dich nicht begriffsstutziger an, als nötig.

                                      MfG ChrisB

                                      --
                                      RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                                      1. Hello,

                                        Wolltest Du damit also beweisen, dass der _Scriptautor_ den Dateinamen manipulieren kann? Der kann alles manipulieren. Er wird nur durch eine saubere Systemeinrichtung daran gehindert, mit seinen Scripten Schadcode wirksam werden zu lassen. Dass der sich selber schädigt, kann man nicht verhindern.

                                        Ein Szenario, in dem $_FILES für dich als Ersteller eines Teil-Scriptes nicht verlässlich sein kann, hatte ich gerade genannt. Bitte stelle dich nicht begriffsstutziger an, als nötig.

                                        Wozu soll ich mir das vorstellen?

                                        Wer Zugriff auf die Scripte hat, kann doch sowieso alles manipulieren.
                                        Was willst Du also damit sagen?

                                        Gib es doch einfach zu: Du hast dich da verrannt.

                                        Macht ja auch nix, ist ja Bestandteil von Diskussionen, dass man auch mal falsch liegt.

                                        Liebe Grüße aus dem schönen Oberharz

                                        Tom vom Berg

                                        --
                                         ☻_
                                        /▌
                                        / \ Nur selber lernen macht schlau
                                        http://bergpost.annerschbarrich.de
                                        1. Hi,

                                          Wozu soll ich mir das vorstellen?

                                          Wer Zugriff auf die Scripte hat, kann doch sowieso alles manipulieren.
                                          Was willst Du also damit sagen?

                                          Die Sicherheit, die $_FILES an der Stelle nicht mehr bieten kann, bietet move_uploaded_file immer noch. Also nix mit obsolet.

                                          MfG ChrisB

                                          --
                                          RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                    2. Moin Tom,

                      Wenn diese Daten abgesichert sind, kann der Programmierer daraus alles andere ableiten. Die zusätzlichen Funktionn sind also obsolet.

                      ASM bietet alles, was ein Software-Entwickler benötigt. Zusätzliche Funktionalität ist obsolet.

                      Tihi.

                      LG,
                       CK

                      1. Hello Christian,

                        Wenn diese Daten abgesichert sind, kann der Programmierer daraus alles andere ableiten. Die zusätzlichen Funktionn sind also obsolet.

                        ASM bietet alles, was ein Software-Entwickler benötigt. Zusätzliche Funktionalität ist obsolet.

                        Prinzipiell magst Du ja sogar Recht haben, aber wir sprachen eben gerade über eine höhere Programmiersprache, auch wenn Du PHP vielleicht nicht dazurechnen magst.

                        Außerdem ist ASM eine Compilersprache, mit der volle Gewalt über die Maschine erlangt werden kann, PHP ist ein Interpreter, der auf die Richtigkeit seines Unterbaus zählen können muss. Aber das weißt Du ja sleber ;-)

                        Vielen Dank jedenfalls für den kleinen Witz.

                        Liebe Grüße aus dem schönen Oberharz

                        Tom vom Berg

                        --
                         ☻_
                        /▌
                        / \ Nur selber lernen macht schlau
                        http://bergpost.annerschbarrich.de
                        1. Moin Tom,

                          Wenn diese Daten abgesichert sind, kann der Programmierer daraus alles andere ableiten. Die zusätzlichen Funktionn sind also obsolet.

                          ASM bietet alles, was ein Software-Entwickler benötigt. Zusätzliche Funktionalität ist obsolet.

                          Prinzipiell magst Du ja sogar Recht haben, aber […]

                          Merkste was?

                          LG,
                           CK

                          1. Hello,

                            Wenn diese Daten abgesichert sind, kann der Programmierer daraus alles andere ableiten. Die zusätzlichen Funktionn sind also obsolet.

                            ASM bietet alles, was ein Software-Entwickler benötigt. Zusätzliche Funktionalität ist obsolet.

                            Prinzipiell magst Du ja sogar Recht haben, aber […]

                            Merkste was?

                            Ich merk (mir) alles! ;-P

                            Liebe Grüße aus dem schönen Oberharz

                            Tom vom Berg

                            --
                             ☻_
                            /▌
                            / \ Nur selber lernen macht schlau
                            http://bergpost.annerschbarrich.de
                2. Hi!

                  move_uploaded_file() wurde mit (PHP 4 >= 4.0.3, PHP 5) eingeführt.
                  Das war der letzte Verusch, die korrumpierbarene Variablen für den Upload abzusichern
                  $_FILES wurd dann mit (PHP 4 >= 4.1.0, PHP 5) eingeführt
                  Das ist nicht mehr korrumpierbar. Daher sind die *_uploaded_file()-Funktionen obsolet geworden.

                  Es mag ja sein, dass deine Argumentation plausibel klingt. Doch das ist keine Aussage von offizieller Seite. Wenn nun jemand auf *_uploaded_file() verzichtet und irgendein Entwickler später die Funktion mit einem deiner Aussage widersprechenden Nutzen ausstattet, dann bist du beziehungsweise "das SELFHTML-Forum" für die durch die Nichtverwendungen entstehenden Nachteile verantwortlich. Solange sie immer noch die offiziellen Funktionen für das Verschieben und Prüfen hochgeladener Dateien sind, plädiere ich dafür, das so weiterzupropagieren oder an geeigneter Stelle eine Diskussion darüber anzustoßen, bei der auch mit den Interna PHPs vertraute Personen ihre Meinung dazu abgeben können. Und wenn du in diesen Funktionen eine schädliche Arbeitsweise siehst, dann ist es umso mehr deine moralische Pflicht, einen Bug-Report einzureichen.

                  Sie sind für die sensitive Speicherung von Dateien (Überschreiben von vorhandenen wird z.B. verhindert) sogar unbrauchbar.

                  Das garantiert auch ein copy()/rename() nicht.

                  Lo!

                3. Hi,

                  move_uploaded_file() wurde mit (PHP 4 >= 4.0.3, PHP 5) eingeführt.
                  Das war der letzte Verusch, die korrumpierbarene Variablen für den Upload abzusichern

                  $_FILES wurd dann mit (PHP 4 >= 4.1.0, PHP 5) eingeführt
                  Das ist nicht mehr korrumpierbar. Daher sind die *_uploaded_file()-Funktionen obsolet geworden.

                  move_uploaded_file ist dazu da, die hochgeladenen Dateien von dem temporären Ort, an dem sie sind, zu verschieben. Die Alternative dazu wäre rename.
                  Ein schneller Blick ins Manual zeigt, dass move_uploaded_file durchaus mehr macht als rename (siehe die Anmerkungen bzgl. Safe Mode). Ergo: move_uploaded_file ist nicht obsolet.

                  Sie sind für die sensitive Speicherung von Dateien (Überschreiben von vorhandenen wird z.B. verhindert) sogar unbrauchbar.

                  Wenn eine Funktion etwas nicht anbietet, was du haben willst, ist sie unbrauchbar? Sorg einfach dafür, dass der von dir gewünschte Dateiname nicht bereits vergeben ist (siehe Anmerkung von ChrisB dazu).

                  Bis die Tage,
                  Matti

                  1. Hello,

                    move_uploaded_file ist dazu da, die hochgeladenen Dateien von dem temporären Ort, an dem sie sind, zu verschieben. Die Alternative dazu wäre rename.

                    Nö. Die Alternative dazu wäre eine qualifizierte Dateierzeugung mit passender Fehlerauswerrtung. Aber dazu mehr demnächst ikn meinem Artikel :-)

                    Ein schneller Blick ins Manual zeigt, dass move_uploaded_file durchaus mehr macht als rename (siehe die Anmerkungen bzgl. Safe Mode). Ergo: move_uploaded_file ist nicht obsolet.

                    Die Begründung "mehr Shit ist besser" ist keinesfalls eine Existenzberechtigung für "move_uploaded_file()".

                    Sie sind für die sensitive Speicherung von Dateien (Überschreiben von vorhandenen wird z.B. verhindert) sogar unbrauchbar.

                    Wenn eine Funktion etwas nicht anbietet, was du haben willst, ist sie unbrauchbar? Sorg einfach dafür, dass der von dir gewünschte Dateiname nicht bereits vergeben ist (siehe Anmerkung von ChrisB dazu).

                    Zeig mir doch bitte mal, wie Du das machst!

                    Bitte fühle dich auch nicht angegriffen von mir, denn ich begrüße es sehr, dass Du Ideen einbringst, anders, als ChrisB es macht. Der pault nur rum!

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
            2. Hallo Tom,

              @all others:
              Entschulödigt bitte, aber ChrisB ist einfach nicht derjenige, der sich wirklich _für__uns__alle_ anstrengen mag.

              entschuldige bitte, aber diese Polemik ist frech und unverschämt.

              Er kann nur rumpaulen, dies auch unter weiteren Pseudonymen...

              Dafür, dass du diese Aussage nur auf dein Gefühl stützen kannst, lehnst du dich ganz schön weit aus dem Fenster.

              Ciao,
               Martin

              --
              Wenn man keine Ahnung hat - einfach mal Fresse halten.
                (Dieter Nuhr, deutscher Kabarettist)
              Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
              1. Hello Martin,

                @all others:
                Entschulödigt bitte, aber ChrisB ist einfach nicht derjenige, der sich wirklich _für__uns__alle_ anstrengen mag.

                entschuldige bitte, aber diese Polemik ist frech und unverschämt.

                Nö, sie ist nach meiner Rückschau die Wahrheit. Ich habe bisher keine Beiträge von ihm gefunden, die Streit geschlichtet hätten, durch Beibringung von Sachbeiträgen, sondern nur solche, die Streit hevorgebracht haben durch Angriff und Unterlassung des Sachbeitrages.

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
                1. Hi,

                  @all others:
                  Entschulödigt bitte, aber ChrisB ist einfach nicht derjenige, der sich wirklich _für__uns__alle_ anstrengen mag.

                  entschuldige bitte, aber diese Polemik ist frech und unverschämt.

                  Nö, sie ist nach meiner Rückschau die Wahrheit.

                  Deine Behauptung von gerade eben war schlicht und einfach gelogen.
                  Dass du sie jetzt einfach unter den Tisch fallen lässt, bestätigt mich in der Vermutung, dass dir das selber glasklar bewusst ist und war.

                  Ich habe bisher keine Beiträge von ihm gefunden, die Streit geschlichtet hätten, durch Beibringung von Sachbeiträgen, sondern nur solche, die Streit hevorgebracht haben durch Angriff und Unterlassung des Sachbeitrages.

                  Dass dir jedes Mal der Hut hoch geht, sobald darauf hingewiesen wird, dass eine Aussage deinerseits schlicht und einfach fachlich falsch ist, ist dein eigenes (Ego-)Problem.

                  MfG ChrisB

                  --
                  RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
              2. @@Der Martin:

                nuqneH

                Anständiger? Och, lass se doch,
                die fülln doch nur das Sommerloch.

                Aber mal im Ernst, Jungs, wollt Ihr nicht beide zum SELFHTML-Treffen kommen und die Sache wie Männer austragen? Dann hätten alle was davon und das Treffen ein Highlight.

                Ich würde auch das <I> auf mich nehmen und mich der Wetteinsätze annehmen.

                Qapla'

                --
                Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
                (Mark Twain)
    2. Moin!

      siehe
      http://forum.de.selfhtml.org/my/?t=206724&m=1403946&aaf=1
      http://wiki.selfhtml.org/wiki/Artikel:PHP/File_Upload

        if ( move\_uploaded\_file ( $\_FILES['bild']['tmp\_name'], 'abgespeichertes\_bild.jpg' )  
      

      move_uploaded_file() ist obsolet, wenn man $_FILES benutzt

      Dann erklärst du uns jetzt am besten mal, warum PHP bei move_uploaded_file() intern diese Dinge tut, die sich allesamt so lesen, als würden dort explizit Checks durchgeführt, die einen erfolgten Dateiupload prüfen:

      https://svn.php.net/viewvc/php/php-src/trunk/ext/standard/basic_functions.c?revision=314452&view=markup

        
      5739	/* {{{ proto bool move_uploaded_file(string path, string new_path)  
      5740	   Move a file if and only if it was created by an upload */  
      5741	PHP_FUNCTION(move_uploaded_file)  
      5742	{  
      5743	    char *path, *new_path;  
      5744	    int path_len, new_path_len;  
      5745	    zend_bool successful = 0;  
      5746	  
      5747	#ifndef PHP_WIN32  
      5748	    int oldmask; int ret;  
      5749	#endif  
      5750	  
      5751	    if (!SG(rfc1867_uploaded_files)) {  
      5752	        RETURN_FALSE;  
      5753	    }  
      5754	  
      5755	    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &path, &path_len, &new_path, &new_path_len) == FAILURE) {  
      5756	        return;  
      5757	    }  
      5758	  
      5759	    if (!zend_hash_exists(SG(rfc1867_uploaded_files), path, path_len + 1)) {  
      5760	        RETURN_FALSE;  
      5761	    }  
      5762	  
      5763	    if (php_check_open_basedir(new_path TSRMLS_CC)) {  
      5764	        RETURN_FALSE;  
      5765	    }  
      5766	  
      5767	    VCWD_UNLINK(new_path);  
      5768	    if (VCWD_RENAME(path, new_path) == 0) {  
      5769	        successful = 1;  
      5770	#ifndef PHP_WIN32  
      5771	        oldmask = umask(077);  
      5772	        umask(oldmask);  
      5773	  
      5774	        ret = VCWD_CHMOD(new_path, 0666 & ~oldmask);  
      5775	  
      5776	        if (ret == -1) {  
      5777	            php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));  
      5778	        }  
      5779	#endif  
      5780	    } else if (php_copy_file_ex(path, new_path, STREAM_DISABLE_OPEN_BASEDIR TSRMLS_CC) == SUCCESS) {  
      5781	        VCWD_UNLINK(path);  
      5782	        successful = 1;  
      5783	    }  
      5784	  
      5785	    if (successful) {  
      5786	        zend_hash_del(SG(rfc1867_uploaded_files), path, path_len + 1);  
      5787	    } else {  
      5788	        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to move '%s' to '%s'", path, new_path);  
      5789	    }  
      5790	  
      5791	    RETURN_BOOL(successful);  
      5792	}  
      5793	/* }}} */  
      
      

      - Sven Rautenberg

      1. Hello Sven,

        erstmal vielen Dank füe die erste qualifizierte Antwort zu diedem Thema seit Monaten.

        Dann erklärst du uns jetzt am besten mal, warum PHP bei move_uploaded_file() intern diese Dinge tut, die sich allesamt so lesen, als würden dort explizit Checks durchgeführt, die einen erfolgten Dateiupload prüfen:

        Du wirst jetzt hoffentlich auch Verständnis dafür haben, wenn ich mir jetzt auch ein paar Tage (Wochen?) Zeit nehmen werde, zumal Du ja nur die Frage aufwirfst, ob da eventuell Kontrollen vorgenommen werden, aber leider nicht mit der z.B. für Christian Seiler üblichen Klarheit beschreibst, welche Kontrollen da in welcher Form vorgenommen werden...

        Ich müsste jetzt also als Gegenbeweis die konsequente Kontrollverfolgung bis zum $_FILES-Array hin heraussuchen und auch für Leute, wie ChrisB verständlich, wiedergeben. Das ist nicht einfach!

        Ich will es aber trotzdem versuchen :-O

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hi,

          Du wirst jetzt hoffentlich auch Verständnis dafür haben, wenn ich mir jetzt auch ein paar Tage (Wochen?) Zeit nehmen werde, zumal Du ja nur die Frage aufwirfst, ob da eventuell Kontrollen vorgenommen werden, aber leider nicht mit der z.B. für Christian Seiler üblichen Klarheit beschreibst, welche Kontrollen da in welcher Form vorgenommen werden...

          Irre ich mich, oder jammerst du gerade herum, weil dir nicht alles in mundgerechte Häppchen zerteilt serviert wird?

          Den Anspruch, mal „etwas mehr für die Gemeinschaft zu tun“, stellst du wohl nur an andere?

          Ich müsste jetzt also als Gegenbeweis die konsequente Kontrollverfolgung bis zum $_FILES-Array hin heraussuchen und auch für Leute, wie ChrisB verständlich, wiedergeben. Das ist nicht einfach!

          Ich will es aber trotzdem versuchen :-O

          In gespannter Erwartung deines, weil du fachlich schlicht und einfach falsch liegst unvermeidlichen, Scheiterns –
          MfG ChrisB

          --
          RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
        2. Moin!

          Dann erklärst du uns jetzt am besten mal, warum PHP bei move_uploaded_file() intern diese Dinge tut, die sich allesamt so lesen, als würden dort explizit Checks durchgeführt, die einen erfolgten Dateiupload prüfen:

          Du wirst jetzt hoffentlich auch Verständnis dafür haben, wenn ich mir jetzt auch ein paar Tage (Wochen?) Zeit nehmen werde, zumal Du ja nur die Frage aufwirfst, ob da eventuell Kontrollen vorgenommen werden, aber leider nicht mit der z.B. für Christian Seiler üblichen Klarheit beschreibst, welche Kontrollen da in welcher Form vorgenommen werden...

          Das Problem ist:

          Du erklärst in gewisser Selbstherrlichkeit die Funktion move_uploaded_file() für obsolet, im Widerspruch zur geschriebenen Dokumentation und der herrschenden Meinung, aber du bietest keinerlei Alternative an, wie das, was die Funktion tut, nach deiner Meinung zu realisieren sei.

          Die übliche Vorgehensweise bei RFCs ist, dass ein altes RFC nur durch ein neues RFC für obsolet erklärt werden kann, indem die bisherige Vorgehensweise durch eine bessere Vorgehensweise ersetzt wird. Das fehlt hier. Und insbesondere dein Verweis auf den Wiki-Artikel, welcher ausgerechnet DIESEN Punkt derzeit nicht mit Inhalt füllt, klingt dann doch eher wie Ironie.

          Was die Kontrollen innerhalb der Funktion angeht (ich spekuliere mal etwas aufgrund des vorliegenden Codes, der mir ja trotz allem etwas sagen will):

          Offensichtlich pflegt PHP im Upload-Fall eine Datenstruktur "rfc1867_uploaded_files", in der alle hochgeladenen Dateien vermerkt werden.

          move_uploaded_file() bricht ab, wenn im Skriptrequest keine Dateien hochgeladen wurden (Zeile 5751).

          Es bricht ab, wenn nicht genau zwei Funktionsparameter verwendet werden (Zeile 5755).

          Es bricht ab, wenn der erste Funktionsparameter nicht in der Liste der hochgeladenen Dateien steht (Zeile 5759).

          Es bricht ab, wenn der Zielpfad durch open_basedir-Restriktionen nicht erlaubt ist (Zeile 5763).

          Erst jetzt wird das Bewegen der Datei durchgeführt. Dabei wird die eventuell schon existierende Zieldatei in jedem Fall gelöscht, und dann durch den Versuch des Umbenennens innerhalb des gleichen Dateisystems "schnell" bewegt. Wenn das funktioniert, werden in Nicht-Windows-Versionen von PHP noch die Rechte der Zieldatei nachgezogen. Wenn Rename nicht funktioniert, wird versucht, die Datei auf das Ziel zu kopieren. Ist die Kopie erfolgreich, wird die Quelldatei gelöscht.

          Wenn der vorgenannte Vorgang erfolgreich war, wird der Quellpfad der Datei aus der Liste hochgeladener Dateien gelöscht. Andernfalls gibts eine Warnung.

          Ich denke, die Behauptung der Funktionsdokumentation, dass move_uploaded_file() eine Datei nur dann verschiebt, wenn diese aus einem HTTP-Upload stammt, und dies auch nur ein einziges Mal pro Skriptausführung und Dateiname erlaubt, ergibt sich aus dem dargelegten Code recht deutlich.

          Ich müsste jetzt also als Gegenbeweis die konsequente Kontrollverfolgung bis zum $_FILES-Array hin heraussuchen und auch für Leute, wie ChrisB verständlich, wiedergeben. Das ist nicht einfach!

          Deine Argumentation klingt eher wie "Ich muss einen String, der nur Integer-Werte enthält, ja nicht mit htmlspecialchars() behandeln, wenn ich ihn in HTML reintun will, weil damit ja sowieso nix geändert wird. htmlspecialchars() ist zum Escapen von Integer-Strings obsolet."

          Ich denke, deine Suche im Code wird nicht sonderlich von Erfolg gekrönt sein, denn das Nadelöhr ist die Funktion zum Bewegen der Datei. PHP bietet nur zwei Funktionen an, die das überhaupt erledigen, einerseits move_uploaded_file(), andererseits rename(). Kennst du noch andere?

          Was den Sicherheitsaspekt angeht, kann rename() nicht mithalten. Denn selbst wenn der Quellpfad der zu verschiebenden Datei tatsächlich auf sichere Weise aus $_FILES ermittelt wurde, so muss rename() ja dennoch für den allgemeinen Fall geschrieben sein. Es kann also nicht geprüft werden, ob die zu verschiebende Datei hochgeladen wurde. Ebenso kann nicht geprüft werden, ob mehrfach versucht wird, die Datei zu verschieben.

          Abgesehen davon verrät die Doku, dass rename() erst seit PHP Version 5.3.1 in der Lage ist, auch unter Windows Dateien zwischen verschiedenen Dateisystemen zu verschieben.

          Unter diesen Gesichtspunkten sieht es für die Nutzung der Funktion rename() also ganz schlecht aus:
          1. Unter Windows muss man vor PHP 5.3.1 eine Kombination aus copy() und unlink() programmieren, wenn man die Datei z.B. zwischen zwei Laufwerken verschieben will. Anzumerken sei, dass auch NTFS das Mounten von Partitionen in Unterverzeichnissen erlaubt, d.h. man kann nicht anhand des Quell- und Zielpfads erkennen, ob rename() oder copy/unlink() erforderlich ist, sondern muss rename() probieren und im Fehlerfall copy/unlink() nachziehen.
          2. rename() hat keine zusätzliche Schutzschicht, die verhindert, dass Dateien verschoben werden, die nicht hochgeladen wurden.
          3. rename() verhindert auch nicht, dass versucht wird, eine hochgeladene Datei zweimal zu verschieben.
          4. rename() kann die verschobene Datei auch nicht aus der Liste der hochgeladenen Dateien entfernen - PHP wird also am Skriptende versuchen, die verschobene Datei an ihrem alten Ort zu löschen.

          Würdest du also immer noch argumentieren, move_uploaded_file() ist unter diesem Gesichtspunkten obsolet?

          - Sven Rautenberg

          1. Hi,

            Ich denke, deine Suche im Code wird nicht sonderlich von Erfolg gekrönt sein, denn das Nadelöhr ist die Funktion zum Bewegen der Datei. PHP bietet nur zwei Funktionen an, die das überhaupt erledigen, einerseits move_uploaded_file(), andererseits rename(). Kennst du noch andere?

            Er hat in https://forum.selfhtml.org/?t=206726&m=1403981 noch die "normalen" I/O-Operationen (fopen, fwrite, ...) erwähnt, welche man nutzen kann. Damit bekommt man mindestens ein copy auf dem Fußweg hin.

            Was den Sicherheitsaspekt angeht, kann rename() nicht mithalten. Denn selbst wenn der Quellpfad der zu verschiebenden Datei tatsächlich auf sichere Weise aus $_FILES ermittelt wurde, so muss rename() ja dennoch für den allgemeinen Fall geschrieben sein. Es kann also nicht geprüft werden, ob die zu verschiebende Datei hochgeladen wurde. Ebenso kann nicht geprüft werden, ob mehrfach versucht wird, die Datei zu verschieben.

            Was move_uploaded_file bietet und alle anderen Lösungen (weder rename noch Toms Fußweg) nicht bieten: das upload-Verzeichnis muß im Safe-Mode nicht in open_basedir enthalten sein. Mit rename/fopen kann ich aber nur auf Dateien zugreifen, auf die das gilt. move_uploaded_file erlaubt es aber explizit.
            Damit kann man also ein weiteres Verzeichnis aus open_basedir entlassen.

            Bis die Tage,
            Matti

            1. Hi!

              das upload-Verzeichnis muß im Safe-Mode nicht in open_basedir enthalten sein.

              Gilt das nur für den Safe-Mode? Denn das open_basedir arbeitet auch bei ausgeschaltetem Safe-Mode.

              Lo!

            2. Hello,

              Ich denke, deine Suche im Code wird nicht sonderlich von Erfolg gekrönt sein, denn das Nadelöhr ist die Funktion zum Bewegen der Datei. PHP bietet nur zwei Funktionen an, die das überhaupt erledigen, einerseits move_uploaded_file(), andererseits rename(). Kennst du noch andere?

              Er hat in https://forum.selfhtml.org/?t=206726&m=1403981 noch die "normalen" I/O-Operationen (fopen, fwrite, ...) erwähnt, welche man nutzen kann. Damit bekommt man mindestens ein copy auf dem Fußweg hin.

              Damit bekommt man sogar ein "Copy" hin, dass nicht einfach Zieldateien überschreibt, wenn man das nicht wünscht und das kollaborationsfähig ist, also die Aspekte einer Multiuserumgebung berücksichtigt.

              Was move_uploaded_file bietet und alle anderen Lösungen (weder rename noch Toms Fußweg) nicht bieten: das upload-Verzeichnis muß im Safe-Mode nicht in open_basedir enthalten sein. Mit rename/fopen kann ich aber nur auf Dateien zugreifen, auf die das gilt. move_uploaded_file erlaubt es aber explizit.
              Damit kann man also ein weiteres Verzeichnis aus open_basedir entlassen.

              Das verstehe ich jetzt nicht. Was hat der Safe-Mode (der mWn sowieso abgeschafft wird) mit open_basedir zu tun?

              Das temporäre Upload-Verzeichnis sollte aber tunlichst für jedes Projekt separat liegen. Damit muss es in open_basedir genannt werden. Schließlich will man doch nicht, dass Andere die Temporärdateien manipulieren können, während sie auf Bearbeitung warten. Das war übrigens neulich auch einer der Diskussionspunkte zu "Dateiupload, was tut move_uploaded_file() wirklich?".

              Wenn move_uploaded_file() eine Prüfsumme für das File gegenprüfen würde, die mit dem Hochladen des Files angelegt würde und sofort in den Hoheitsbereich des Scriptes überführt würde, bevor es das File bewegt, dann wäre da eine zusätzliche Sicherheit. Aber das scheint die Funktion ja nicht zu tun.

              Liebe Grüße aus dem schönen Oberharz

              Tom vom Berg

              --
               ☻_
              /▌
              / \ Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
              1. Moin!

                Er hat in http://forum.de.selfhtml.org/my/?t=206726&m=1403981&aaf=1 noch die "normalen" I/O-Operationen (fopen, fwrite, ...) erwähnt, welche man nutzen kann. Damit bekommt man mindestens ein copy auf dem Fußweg hin.

                Damit bekommt man sogar ein "Copy" hin, dass nicht einfach Zieldateien überschreibt, wenn man das nicht wünscht und das kollaborationsfähig ist, also die Aspekte einer Multiuserumgebung berücksichtigt.

                Und wie entsteht der Zieldateiname?

                Es gibt Methoden, auch ohne fopen(), Locking etc., konfliktfrei in der Multiuserumgebung einen Dateinamen zu finden und mit move_uploaded_file() zu benutzen, ohne sich Dateien zu zerstören:

                Möglichkeit 1: Benutze die Funktion tempnam().

                Möglichkeit 2: Wenn der Upload 1:1 mit einem Datenbankeintrag korreliert, verwende die unique ID des Datenbankeintrags.

                Möglichkeit 3: Ignoriere das Problem, entschärfe es vielleicht durch Trennung der Verzeichnisse einzelner User, sofern es User gibt. Wer sich selbst Dateien überschreibt, wird wissen, was er tut. Wichtig ist nur, dass Dateien nur dort landen, wo sie hinsollen, und dass nur solche Dateien dort landen, die hochgeladen wurden - keine Dateien, die sich sonstwo auf dem System befinden.

                Wenn move_uploaded_file() eine Prüfsumme für das File gegenprüfen würde, die mit dem Hochladen des Files angelegt würde und sofort in den Hoheitsbereich des Scriptes überführt würde, bevor es das File bewegt, dann wäre da eine zusätzliche Sicherheit. Aber das scheint die Funktion ja nicht zu tun.

                Exakt das tut die Funktion doch.

                - Sven Rautenberg

                1. Moin Sven,

                  Es gibt Methoden, auch ohne fopen(), Locking etc., konfliktfrei in der Multiuserumgebung einen Dateinamen zu finden und mit move_uploaded_file() zu benutzen, ohne sich Dateien zu zerstören:

                  Zusätzlich gibt es auch noch die Methode, mit zwar fopen($f,"x") sicherzustellen, dass die Datei nicht existiert, aber danach trotzdem move_uploaded_file() nutzt.

                  LG,
                   CK

                  1. Moin!

                    Es gibt Methoden, auch ohne fopen(), Locking etc., konfliktfrei in der Multiuserumgebung einen Dateinamen zu finden und mit move_uploaded_file() zu benutzen, ohne sich Dateien zu zerstören:

                    Zusätzlich gibt es auch noch die Methode, mit zwar fopen($f,"x") sicherzustellen, dass die Datei nicht existiert, aber danach trotzdem move_uploaded_file() nutzt.

                    Richtig, aber Tom wird argumentieren, dass move_uploaded_file() ja die Zieldatei erst löscht und dann bewegt, und dass parallele Prozesse sich ohne Locking ja sowieso gegenseitig Dateien zerstören können.

                    Dabei ist dann die Frage, wie das Skript eigentlich zu einem gültigen, eindeutigen Dateinamen kommt, vollkommen unbeachtet geblieben.

                    - Sven Rautenberg

                    1. Hello Sven,

                      Richtig, aber Tom wird argumentieren, dass move_uploaded_file() ja die Zieldatei erst löscht und dann bewegt, und dass parallele Prozesse sich ohne Locking ja sowieso gegenseitig Dateien zerstören können.

                      Dabei ist dann die Frage, wie das Skript eigentlich zu einem gültigen, eindeutigen Dateinamen kommt, vollkommen unbeachtet geblieben.

                      Das wurde doch noch gar nicht behandelt...

                      Aber lass uns das bitte nun auch zuende diskutieren. Ich melde mich wieder, wenn ich zurück bin von meinem "Einsatz". Kann ein wenig später werden.

                      Liebe Grüße aus dem schönen Oberharz

                      Tom vom Berg

                      --
                       ☻_
                      /▌
                      / \ Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
                  2. Hello Sven, Hello Christian,

                    Die Kombination aus tempnam() und move_uploaded_file() ist ungeeinget, da zwischen den Arbeitsschritten eine Kontrolllücke entsteht.

                    Es gibt Methoden, auch ohne fopen(), Locking etc., konfliktfrei in der Multiuserumgebung einen Dateinamen zu finden und mit move_uploaded_file() zu benutzen, ohne sich Dateien zu zerstören:

                    Und wie lauten die?

                    Zusätzlich gibt es auch noch die Methode, mit zwar fopen($f,"x") sicherzustellen, dass die Datei nicht existiert, aber danach trotzdem move_uploaded_file() nutzt.

                    Das ergibt aber bestimmt eine wilde Konstruktion und ich bin mir noch nicht einmal sicher, dass Du weißt, wie das ablaufen soll. Ich kann es mir jedenfalls nicht vorstellen. Es sei denn, dass move_uploaded_file() alle POSIX-Empfehlungen missachten würde (Streams sind für die / während der Bearbeitung zu sperren)...

                    MMn geht das auch nicht, ohne eine Kontrolllücke zu erzeugen. Und da haben wir dann schon wieder das Problem...

                    Euch beiden empfehle ich mal das intensive Studium von Christian Seilers Artikel
                    http://aktuell.de.selfhtml.org/artikel/programmiertechnik/dateisperren/

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
          2. Hello Sven,

            Das Problem ist:

            Du erklärst in gewisser Selbstherrlichkeit die Funktion move_uploaded_file() für obsolet, im Widerspruch zur geschriebenen Dokumentation und der herrschenden Meinung, aber du bietest keinerlei Alternative an, wie das, was die Funktion tut, nach deiner Meinung zu realisieren sei.

            Das Problem ist, dass hier eine Diskussion untgerdrückt werden soll. Warum eigentlich?

            Dein Ansatz, das Stück Quellcode zu move_uploaded_file() herauszusuchen, ist doch mMn der bessere Weg.

            Und ich habe es sehr wohl erklärt, wie Ersatz zu leisten ist.

            Durch die Absicherung des Arrays $_FILES, das offiziell erst _nach_ den Funktionen *_uploaded_file() eingeführt worden ist, ist der Dateiname für hochgeladene Files im Element $_FILES[<name>]['tmp_name'] sicher. Er wird vom System vergeben und ist nicht mehr von Usereingaben manipulierbar. Das war mit den Scriptvariablen zum Upload nicht der Fall. Das Problem mit register_globals ist ja hinlänglich bekannt.

            Ein File, dass im Array $_FILES benannt wird, _muss_ also ein uploaded File sein.

            Die übrigen von dir genannten "Sicherheiten" werden von den Filefunktionen

            • fopen
            • flock
            • fread
            • fwrite

            ebenfalls (sinngemäß) erfüllt.

            Die einzige Abweichung ist, dass in der "Liste der hochgeladenen Files", die im $_FILES-Array geführt wird, das File nach dem Auslesen nicht gelöscht wird.

            Welchen Sicherheitsaspekt das bringen sollte, dass man das Temp-File nur einmal kopieren darf, kann ich mir auch nicht vorstellen.

            Ich werde trotzdem versuchen, den zugehörigen Codeabschnitt zu $_FILES zu finden um zu schauen, was da noch unsicher sein kann.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Hi,

              Durch die Absicherung des Arrays $_FILES, das offiziell erst _nach_ den Funktionen *_uploaded_file() eingeführt worden ist, ist der Dateiname für hochgeladene Files im Element $_FILES[<name>]['tmp_name'] sicher. Er wird vom System vergeben und ist nicht mehr von Usereingaben manipulierbar.

              Und schon wieder erzählst du Unsinn.

              Selbstverständlich ist $_FILES zur Laufzeit manipulierbar, so wie die anderen Superglobals auch. Darauf hatte ich dich auch bereits hingewiesen. Wieso zum Teufel stellst du dich so absolut lernresistent an, wenn dir doch nach eigener Aussage angeblich die „Wahrheit“ bzgl. des Themas so am Herzen liegt?

              Ein File, dass im Array $_FILES benannt wird, _muss_ also ein uploaded File sein.

              Nein, muss es nicht. Bitte begreife das doch endlich.

              MfG ChrisB

              --
              RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
              1. Hello,

                Durch die Absicherung des Arrays $_FILES, das offiziell erst _nach_ den Funktionen *_uploaded_file() eingeführt worden ist, ist der Dateiname für hochgeladene Files im Element $_FILES[<name>]['tmp_name'] sicher. Er wird vom System vergeben und ist nicht mehr von Usereingaben manipulierbar.

                Und schon wieder erzählst du Unsinn.

                Du kannst einfach nicht mitdenken.

                Selbstverständlich ist $_FILES zur Laufzeit manipulierbar, so wie die anderen Superglobals auch.

                Durch den Scriptautor. Und wen stört das?
                Es geht doch um Manipulation durch den Client.

                Diese Äußerung von dir zeigt doch, dass Du gar nicht begriffen hast, worum es geht.

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
                1. Hi,

                  Selbstverständlich ist $_FILES zur Laufzeit manipulierbar, so wie die anderen Superglobals auch.

                  Durch den Scriptautor. Und wen stört das?

                  Dich offenbar nicht.
                  Das Szenario, in dem es relevant sein könnte, habe ich genannt.

                  Es geht doch um Manipulation durch den Client.

                  Laut dir geht es um eine "Sicherheit", die $_FILES bieten soll.
                  Tut es in diesem Szenario aber nicht, move_uploaded_file aber sehr wohl.

                  Diese Äußerung von dir zeigt doch, dass Du gar nicht begriffen hast, worum es geht.

                  Ich weiß, das ist dein Standardspruch, wenn dir die Argumente ausgehen.

                  MfG ChrisB

                  --
                  RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                2. Durch den Scriptautor. Und wen stört das?

                  Also ist für dich die Gefahr, dass jemand über eine Sicherheitslücke schadcode einspielt und dann $_FILES manipuliert nicht vorhanden bzw. für dich nicht relevant?
                  In dem Fall frag ich mich, was deine ganzen Aussagen sollen, wenn dich solch gravierende Sicherheitslücken nicht interessieren.

                  Mal ganz ehrlich, ich lese die Diskussion mit aber es gibt keinen einzigen Ansatz von dir um das angebliche Problem zu lösen aber du verteufelst grundsätzlich alles andere. Und ein "alles ist schlecht, wie man es lösen kann, sag ich aber nicht" ist keine Diskussionsgrundlage.

                  1. Hello,

                    Durch den Scriptautor. Und wen stört das?

                    Also ist für dich die Gefahr, dass jemand über eine Sicherheitslücke schadcode einspielt und dann $_FILES manipuliert nicht vorhanden bzw. für dich nicht relevant?

                    Wenn jemand $_FILES manipulieren kann, kann er sicherlich auch $_POST, $_GET, $_COOKIES, ... manipulieren.

                    Ich verstehe Dich wahrscheinlich jetzt überhaupt nicht.

                    Kannst Du mir das Szennario mal etwas genauer erklären?

                    t keine Diskussionsgrundlage.
                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
                    1. Wenn jemand $_FILES manipulieren kann, kann er sicherlich auch $_POST, $_GET, $_COOKIES, ... manipulieren.

                      Absolut richtig. Und was hat das jetzt mit deinem Problem zu tun, das du mit move_uploaded_file() hast?

                      Ich verstehe Dich wahrscheinlich jetzt überhaupt nicht.

                      Würde mich nicht wundern. Mach dir mal Gedanken, wieso du der einzige bist, der für seine Behauptung noch keine programmtechnische Begründung gebracht hast. Und wo die Gefahr mit der Manipulation von $_FILES  liegt, wurde dir mehrfach erklärt. Deine permanente Ingoranz ändert daran nichts.

                      Nur mal so rein menschlich: Was ist mit dir los? So warst du noch nie. Zumindest nicht, was ich sonst von dir hier lese.

                3. Hallo,

                  Selbstverständlich ist $_FILES zur Laufzeit manipulierbar, so wie die anderen Superglobals auch.
                  Durch den Scriptautor.

                  durch den natürlich auch, aber nicht nur.

                  Es geht doch um Manipulation durch den Client.

                  Nein - jedenfalls hatte ich im gesamten Verlauf dieser Diskussion nie den Eindruck, dass es um Manipulationen durch den Client ging. Der Client ist doch wurscht - er schickt einen POST-Request, der einen Dateiupload als Payload enthält. So what?

                  Meiner Ansicht nach geht es die ganze Zeit vielmehr um Manipulation der hochgeladenen Dateien im temp-Verzeichnis durch andere, nebenläufige Prozesse auf dem Server. Oder Manipulation der in $_FILES bereitgestellten Informationen durch Fremdbibliotheken oder -klassen, die der Scriptautor nutzt, ohne sich haarklein über deren Implementierung zu kümmern (was auch wegen der Komplexität teils nicht zumutbar wäre).

                  Ciao,
                   Martin

                  --
                  Alleine sind wir stark ...
                  gemeinsam sind wir unausstehlich!
                  Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                  1. Hello,

                    Selbstverständlich ist $_FILES zur Laufzeit manipulierbar, so wie die anderen Superglobals auch.
                    Durch den Scriptautor.

                    durch den natürlich auch, aber nicht nur.

                    Der kann sowieso alles manipulieren

                    Es geht doch um Manipulation durch den Client.

                    Nein - jedenfalls hatte ich im gesamten Verlauf dieser Diskussion nie den Eindruck, dass es um Manipulationen durch den Client ging. Der Client ist doch wurscht - er schickt einen POST-Request, der einen Dateiupload als Payload enthält. So what?

                    und deshalb ging es selbstverständlich den ganzen Thread lang nur um Manipulationen durch den Client. Oder was meinst Du, sollten *_uploaded_file() sonst absichern?

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
                    1. Hi,

                      und deshalb ging es selbstverständlich den ganzen Thread lang nur um Manipulationen durch den Client. Oder was meinst Du, sollten *_uploaded_file() sonst absichern?

                      Dass Dateien als vermeintliche Upload-Dateien behandelt werden, obwohl sie keine sind, sondern auf dem Server anderweitig ins Upload-Tempverzeichnis eingeschleust wurden, bspw. durch eine Sicherheitslücke an anderer Stelle.

                      Der Client hat seltenst die Möglichkeit, direkt etwas ins Upload-Tempverzeichnis  zu bugsieren, wenn er dafür *nicht* einen HTTP-Upload benutzt.

                      MfG ChrisB

                      --
                      RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
            2. Moin!

              Und ich habe es sehr wohl erklärt, wie Ersatz zu leisten ist.

              Nicht mit Code. Mit Geschwafel und Gejammer.

              Durch die Absicherung des Arrays $_FILES, das offiziell erst _nach_ den Funktionen *_uploaded_file() eingeführt worden ist, ist der Dateiname für hochgeladene Files im Element $_FILES[<name>]['tmp_name'] sicher. Er wird vom System vergeben und ist nicht mehr von Usereingaben manipulierbar. Das war mit den Scriptvariablen zum Upload nicht der Fall. Das Problem mit register_globals ist ja hinlänglich bekannt.

              Du gehst davon aus, dass $_FILES read-only ist und durch eventuelle Lücken im Code nicht geändert werden kann. Dass diese Annahme falsch ist, hat dir ChrisB in seinem Plugin-Beispiel gezeigt.

              Ein File, dass im Array $_FILES benannt wird, _muss_ also ein uploaded File sein.

              Zum Skriptstart vermutlich ja - derzeit nicht bekannte Injection-Lücken mal ausgenommen. Zur weiteren Laufzeit des Skriptes aber nicht mehr.

              Die übrigen von dir genannten "Sicherheiten" werden von den Filefunktionen

              • fopen
              • flock
              • fread
              • fwrite

              ebenfalls (sinngemäß) erfüllt.

              Ok, jetzt bitte mal konkret: Was heißt denn "sinngemäß" bei dir. So eine Einschränkung macht man doch nur, wenn man sich nicht sicher ist.

              Und dann hätten ich auch gerne noch die Bewertung der Performance und des Speicherverbrauchs mit in die Diskussion gebracht.

              Die einzige Abweichung ist, dass in der "Liste der hochgeladenen Files", die im $_FILES-Array geführt wird, das File nach dem Auslesen nicht gelöscht wird.

              Nein. Die wichtigste Abweichung ist, dass du das File bei Benutzung von fopen etc. nicht BEWEGST, also billig nur den Dateipointer im Dateisystem an eine andere Stelle schreibst, sondern garantiert KOPIERST, also den gesamten Dateiinhalt (ggf. sukkzessive) in den Speicher liest und wieder wegschreibst.

              Das mag für eine 10KB-Textdatei in Ordnung sein. Für ein 50MB-Videoupload ist es das mit Sicherheit nicht.

              Welchen Sicherheitsaspekt das bringen sollte, dass man das Temp-File nur einmal kopieren darf, kann ich mir auch nicht vorstellen.

              Du kannst deine einzelne hochgeladene Datei mit bösem Inhalt nicht mehrfach im Dateisystem verteilen, sondern nur an eine einzige Stelle bewegen.

              Ich werde trotzdem versuchen, den zugehörigen Codeabschnitt zu $_FILES zu finden um zu schauen, was da noch unsicher sein kann.

              Kann ja nicht so schwierig sein, ein GREP auf den Quelltext zu machen, um die relevanten Stellen zu finden. Den Code für move_uploaded_file() habe ich durch trial-and-error im SVN-Viewer aufgetrieben, weil ich den Source nicht komplett herunterladen wollte.

              - Sven Rautenberg

            3. Hi!

              Das Problem ist, dass hier eine Diskussion untgerdrückt werden soll. Warum eigentlich?

              Darum geht es nicht. Es ist nur mit der derzeitigen Faktenlage kein Konsens in dem Thema erzielbar. Die offizielle Aussage weicht von der von dir propagierten ab. Es ist nicht zu sehen, dass die offizielle Vorgehensweise schädlich ist. Deswegen ist es unverständlich, warum du immer deine Aussage als Fakt formuliert triffst, dessen Wahrheitsgehalt nicht erwiesen ist. Deine Aussage stützt sich derzeit nur auf Vermutungen ab.

              Durch die Absicherung des Arrays $_FILES, das offiziell erst _nach_ den Funktionen *_uploaded_file() eingeführt worden ist, ist der Dateiname für hochgeladene Files im Element $_FILES[<name>]['tmp_name'] sicher.

              Das ist derzeit lediglich deine Annahme. Beweisen kann man Sicherheit sowieso nicht. Und wenn in der offiziellen Linie kein bekannter Sicherheitsmangel oder ein gravierender Nachteil zu sehen ist, sollte die offizielle Linie die bevorzugte sein. (Ob die Eigenschaft des bedingungslose Überschreibens der eventuell vorhandenen Zeildatei ein Nachteil ist, ist eine Einzelfallentscheidung und kein generell ankreidbares Fehlverhalten.)

              Welchen Sicherheitsaspekt das bringen sollte, dass man das Temp-File nur einmal kopieren darf, kann ich mir auch nicht vorstellen.

              Verschieben. Zumindest ist es dann aus dem oftmals allgemein zugänglichen Bereich raus. Es mit move_uploaded_file() nur einmal verschieben zu können, ist jedenfalls auch kein genereller Nachteil. Zudem sehe ich grad nicht, dass Anwendungsfälle, in denen man die Datei mehrfach braucht, bei einer überwiegenden Mehrheit vorkommen sollen. Wer sie mehrfach braucht, kann immer noch anschließend kopieren.

              Lo!

              1. (Ob die Eigenschaft des bedingungslose Überschreibens der eventuell vorhandenen Zeildatei ein Nachteil ist, ist eine Einzelfallentscheidung und kein generell ankreidbares Fehlverhalten.)

                In einem meiner Anwendungsfälle ist dieses Verhalten sogar erwünscht und spart die Zeit des Prüfen und evtl. Löschen einer Bilddatei.

                Somit würde maximal ein zusätzlicher Flag sinn machen, der ein Überschreiben verhindert, die generelle Aussage von Tom, dass dieses Verhalten grundsätzlich ein Fehler ist, ist grundsätzlich falsch, weil nicht Fallbezogen.
                Wenn jemand allerdings seine eigenen Anwendungsfälle als die einzig relevanten sieht, kann ich die Aussagen von Tomm nachvollziehen. Allerdings ist das dann so weltfremd, dass ich so einen Programmierer nicht für fähig halte, ein Problem allgemeingültig zu lösen, anstatt mit Scheuklappen zu arbeiten.

                1. Hello,

                  In einem meiner Anwendungsfälle ist dieses Verhalten sogar erwünscht und spart die Zeit des Prüfen und evtl. Löschen einer Bilddatei.

                  Ah ja. This Bug is a Feature...

                  Liebe Grüße aus dem schönen Oberharz

                  Tom vom Berg

                  --
                   ☻_
                  /▌
                  / \ Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
                  1. Hi,

                    In einem meiner Anwendungsfälle ist dieses Verhalten sogar erwünscht und spart die Zeit des Prüfen und evtl. Löschen einer Bilddatei.

                    Ah ja. This Bug is a Feature...

                    Wenn ich auf der Kommandozeile mv nutze, dann wird eine etwaig vorhandene Zieldatei ebenfalls überschrieben.
                    Kurz: du erwartest von einer Funktion ein Feature, was diese nicht hat und auch nicht notwendig ist. Da würde ich das ebenfalls nicht als Bug bezeichnen.

                    Speicher diese im Dateisystem doch einfach mit einem Unique-Dateinamen, wie Sven es vorgeschlagen hat, oder nutze mindestens einen Unique-Prefix.

                    Bis die Tage,
                    Matti

                    1. Hello Matti,

                      In einem meiner Anwendungsfälle ist dieses Verhalten sogar erwünscht und spart die Zeit des Prüfen und evtl. Löschen einer Bilddatei.

                      Ah ja. This Bug is a Feature...

                      Wenn ich auf der Kommandozeile mv nutze, dann wird eine etwaig vorhandene Zieldatei ebenfalls überschrieben.
                      Kurz: du erwartest von einer Funktion ein Feature, was diese nicht hat und auch nicht notwendig ist. Da würde ich das ebenfalls nicht als Bug bezeichnen.

                      Lang: Ich erwarte von einer Funktion, die eigens dafür geschaffen wurde, Dateien aus einem transienten Speicherbereich in einen persistenten zu überführen, dass sie auch die Rahmenbedingungen der Aufgabe beachtet.

                      Anderenfalls würde es soch auch ein copy() - unlink() tun, oder?

                      Speicher diese im Dateisystem doch einfach mit einem Unique-Dateinamen, wie Sven es vorgeschlagen hat, oder nutze mindestens einen Unique-Prefix.

                      Ich habe kein Problem damit, die Datei ordungsgemäß zu verschieben. Soweit waren wir außerdem auch noch gar nicht.

                      Es ging erstmal nur um die Unzulänglichkeiten von move_uploaded_file(), die Vorteile und Nachteile dieser Funktion und ob es _inzwischen_ bessere Möglichkeiten gibt.

                      Bzw. da waren wir auch noch nicht angekommen, als die ersten Kreischer laut wurden. Wir waren erst bei der SIcherheit von $_FILES und seinen Elementen. Da die bei (...) inzwischen hergestellt ist (ich habe bisher nichts anderes gehört), liegt die Idee nahe, die eigentlich unzulängliche Funktion (Themen: unerwünschtes überschreiben, TCOTTOU-Probleme) move_uploaded_file() auf ihre Existenzbereichtigung zu überprüfen.

                      Ich meine weitererhin, dass sie seit EInführung von $_FILES mehr Schaden anrichten kann, als sie Nutzen hat.

                      Liebe Grüße aus dem schönen Oberharz

                      Tom vom Berg

                      --
                       ☻_
                      /▌
                      / \ Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
                      1. Hi,

                        Es ging erstmal nur um die Unzulänglichkeiten von move_uploaded_file(), die Vorteile und Nachteile dieser Funktion und ob es _inzwischen_ bessere Möglichkeiten gibt.

                        Du hast *behauptet*, move_uploaded_file wäre obsolet - Alternativen hast du aber immer noch keine anzubieten.

                        MfG ChrisB

                        --
                        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                        1. Moin ChrisB,

                          Es ging erstmal nur um die Unzulänglichkeiten von move_uploaded_file(), die Vorteile und Nachteile dieser Funktion und ob es _inzwischen_ bessere Möglichkeiten gibt.

                          Du hast *behauptet*, move_uploaded_file wäre obsolet - Alternativen hast du aber immer noch keine anzubieten.

                          Naja, die Alternative liegt auf der Hand:

                            
                          $fd = fopen($fname,"x");  
                          fclose($fd);  
                          file_put_contents(file_get_contents($_FILES['myfile']['tmp_name']));  
                          
                          

                          Fehlerbehandlung dazudenken, habe ich hier weg gelassen weil unwichtig für die kurze Erklärung.

                          Aber dadurch wird allerdings move_uploaded_file() natürlich nicht obsolet. Sie hat halt nur andere Schwächen als die obige Methode und ihre Variationen (Race condition vs. Manipulierbarkeit, um ein Beispiel zu nennen).

                          LG,
                           CK

                          1. Moin!

                            Naja, die Alternative liegt auf der Hand:

                            Ich ergänze da mal den Bugfix:

                            $fd = fopen($fname,"x");
                            fclose($fd);
                            file_put_contents($fname, file_get_contents($_FILES['myfile']['tmp_name']));

                              
                            
                            > Fehlerbehandlung dazudenken, habe ich hier weg gelassen weil unwichtig für die kurze Erklärung.  
                            >   
                            > Aber dadurch wird allerdings move\_uploaded\_file() natürlich nicht obsolet. Sie hat halt nur andere Schwächen als die obige Methode und ihre Variationen (Race condition vs. Manipulierbarkeit, um ein Beispiel zu nennen).  
                              
                            Insbesondere verlangt DIESE Methode dort RAM-Speicher für die gesamte Datei am Stück. Und sie kopiert eben in jedem Fall. Mit anderen Worten: Diese Strategie ist ungeeignet für sehr große Dateien, während bei kleinen Dateien in dieser Hinsicht kein großer Unterschied zu bemerken ist.  
                              
                            Oder in Zahlen:  
                              
                            move\_uploaded\_file() vs. CK-Copy-Methode  
                            kleine Dateien:    1  :  1  
                            große Dateien:     1  :  0  
                              
                            Summe:             2  :  1  
                              
                            Vorteil von CK-Copy-Methode: Überschreibt nicht die bereits existierende Datei gleichen Namens im Zielverzeichnis. Wobei DAS ja eigentlich kein Thema ist:  
                              
                            ~~~php
                              
                            $fd = fopen($fname,"x");  
                            fclose($fd);  
                            move_uploaded_file($_FILES['myfile']['tmp_name'], $fname);  
                            
                            

                            [x] done.

                            Ausgleich für Svens muf-Methode - FTW! ;)

                            - Sven Rautenberg

                            1. Moin Sven,

                              Ich ergänze da mal den Bugfix:

                              Merci ;-)

                              Aber dadurch wird allerdings move_uploaded_file() natürlich nicht obsolet. Sie hat halt nur andere Schwächen als die obige Methode und ihre Variationen (Race condition vs. Manipulierbarkeit, um ein Beispiel zu nennen).

                              Insbesondere verlangt DIESE Methode dort RAM-Speicher für die gesamte Datei am Stück. Und sie kopiert eben in jedem Fall. Mit anderen Worten: Diese Strategie ist ungeeignet für sehr große Dateien, während bei kleinen Dateien in dieser Hinsicht kein großer Unterschied zu bemerken ist.

                              Ich schrub ja. Sie hat dafür andere Schwächen. Man könnte natürlich noch umstellen auf erst rename() versuchen, dann bis zu einem gewissen Threshold file_put_contents(file_get_contents()) und darüber blockweises lesen/schreiben, aber auch da gibt es wieder andere Schwächen.

                              Vorteil von CK-Copy-Methode: Überschreibt nicht die bereits existierende Datei gleichen Namens im Zielverzeichnis. Wobei DAS ja eigentlich kein Thema ist:

                              $fd = fopen($fname,"x");
                              fclose($fd);
                              move_uploaded_file($_FILES['myfile']['tmp_name'], $fname);

                              
                              >   
                              > [x] done.  
                                
                              Ich zitiere dich mal: dadurch, dass move\_uploaded\_files() die Datei zuerst löscht, kann es zu einer Race condition kommen, die dafür sorgt, das zwei Prozesse move\_uploaded\_files() auf die gleiche Zieldatei anwenden.  
                                
                              
                              > Ausgleich für Svens muf-Methode - FTW! ;)  
                                
                              Naja, das war dann aber ein Abseits-Tor ;-)  
                                
                              LG,  
                               CK  
                              
                              -- 
                              <http://ck.kennt-wayne.de/>  
                              
                              
                          2. Hi!

                            $fd = fopen($fname,"x");
                            fclose($fd);

                            Was ist der Unterschied zu file_exists() (abgesehen von der Behandlung von Symlinks)?

                            Lo!

                            1. Moin!

                              $fd = fopen($fname,"x");
                              fclose($fd);

                              Was ist der Unterschied zu file_exists() (abgesehen von der Behandlung von Symlinks)?

                              file_exists prüft die Existenz der Datei, hinterlässt für andere Prozesse aber keinerlei Spuren, dass der geprüfte und nicht gefundene Dateiname danach dann in Benutzung ist.

                              fopen(x) prüft, ob die Datei existiert, und nur wenn nicht, wird die Datei angelegt und zum Schreiben geöffnet - wobei das Schreiben hier ja nicht wirklich gebraucht wird, wichtig ist, dass die Datei bei Nichtexistenz angelegt wird, und bei Existenz ein Fehler kommt. Dadurch wird jedes andere Skript, was zeitgleich dasselbe versucht, entweder vorher laufen und die Datei früher anlegen, oder später laufen und die angelegte Datei finden und abbrechen.

                              - Sven Rautenberg

                              1. Hi!

                                file_exists prüft die Existenz der Datei, hinterlässt für andere Prozesse aber keinerlei Spuren, dass der geprüfte und nicht gefundene Dateiname danach dann in Benutzung ist.
                                fopen(x) [...] wichtig ist, dass die Datei bei Nichtexistenz angelegt wird, und bei Existenz ein Fehler kommt. Dadurch wird jedes andere Skript, was zeitgleich dasselbe versucht, entweder vorher laufen und die Datei früher anlegen, oder später laufen und die angelegte Datei finden und abbrechen.

                                Wenn man also annimmt, dass nur dieses (oder die eigenen Scripte, die nach dem selben Verfahren aufgebaut sind) auf die Zieldatei zugreift, dann ist das also eine Art Schutz vor Doppelterstellung. Wenn man jedoch nicht davon ausgehen kann, dann hilft das auch nicht völlig. Dann wäre zu klären, ob nicht beeinflussbare Codeteile im eigenen Verantwortungsbereich (verwendete Software von anderen Herstellern) mit dieser Datei zu arbeiten versuchen. Gegen Angriffe von der Seite (Mithostlingen oder eingenistetem Ungeziefer) sind Dateisperren ja sowieso nicht konzipiert. Welche Szenarien gilt es eigentlich zu verhindern?

                                1. Verschieben von nicht hochgeladenen Dateien (z.B. /etc/passwd in ein per Web zugreifbares Verzeichnis)
                                2. Überschreiben bereits vorhandener Dateien (optional, weil mitunter auch gewünscht)
                                x. _____

                                Punkt 1 kann muf()[*] leisten, $_FILES['x']['tmp_name'] nicht, wenn man davon ausgehen muss, dass andere diese Variable umbelegen.
                                Für 2. kann man muf() allein nicht nehmen, aber das ist mit einem zusätzlichem fopen(x) lösbar.

                                Wenn ich nun nichts übersehen habe, ist muf() immer noch im Vorteil gegenüber $_FILES und das Überschreibproblem recht einfach lösbar.

                                [*] nette Abkürzung für move_uploaded_files()

                                Lo!

                                1. Moin dedlfix,

                                  Für 2. kann man muf() allein nicht nehmen, aber das ist mit einem zusätzlichem fopen(x) lösbar.

                                  Jain, nicht so, wie wir es vorgestellt haben. Man verschiebt so den Punkt der Race condition nur nach hinten. So wäre es vielleicht lösbar:

                                    
                                  $fd = fopen($lockdir . '/' . $file,"x");  
                                  fclose($fd);  
                                  move_uploaded_file($_FILES['myfile']['tmp_name'], $destdir . '/' . $file);  
                                  
                                  

                                  Fehlerbehandlung wieder dazudenken.

                                  So umgeht man die Race condition, die dadurch entsteht, dass muf die Datei zuerst löscht. Allerdings hat man auch zwei Dateisystem-Operationen.

                                  LG,
                                   CK

                                  1. Hi!

                                    Für 2. kann man muf() allein nicht nehmen, aber das ist mit einem zusätzlichem fopen(x) lösbar.
                                    Jain, nicht so, wie wir es vorgestellt haben. Man verschiebt so den Punkt der Race condition nur nach hinten. [...] die dadurch entsteht, dass muf die Datei zuerst löscht.

                                    Achso, innerhalb mufs zwischen Löschen der durch 'x' angelegten Datei und dem Verschieben/Kopieren.

                                    So wäre es vielleicht lösbar:

                                    $fd = fopen($lockdir . '/' . $file,"x");

                                    fclose($fd);
                                    move_uploaded_file($_FILES['myfile']['tmp_name'], $destdir . '/' . $file);

                                    
                                    >   
                                    > Fehlerbehandlung wieder dazudenken.  
                                      
                                    Um sie mal wenigstens minimal hinzuzufügen:  
                                      
                                    ~~~php
                                    if ($fd = fopen($lockdir . '/' . $file,"x")) {  
                                      fclose($fd);  
                                      move_uploaded_file($_FILES['myfile']['tmp_name'], $destdir . '/' . $file);  
                                    } else  
                                      // Schon vorhanden
                                    

                                    Aber, hmm, dann hat man im $lockdir einen Haufen "unnütze" 0-Byte-Dateien rumliegen, beziehungsweise muss sie erst einmal für die bereits vorhandenen $destdir-Dateien anlegen und darf sie nicht löschen. Besonders hübsch ist das nicht.

                                    Lo!

                                    1. Moin!

                                      Aber, hmm, dann hat man im $lockdir einen Haufen "unnütze" 0-Byte-Dateien rumliegen, beziehungsweise muss sie erst einmal für die bereits vorhandenen $destdir-Dateien anlegen und darf sie nicht löschen. Besonders hübsch ist das nicht.

                                      Man kann ja zuerst fopen(x) auf die Zieldatei machen, dann nochmal auf eine Lock-Datei, dann muf(), und danach die Lockdatei wieder löschen.

                                      Je länger wir drüber diskutieren, desto mehr komme ich aber zur Ansicht, dass die Funktion move_uploaded_file() eigentlich vielmehr einen dritten, optionalen Parameter BOOLEAN $overwrite bekommen sollte, mit dem man (default true) das Überschreiben der vorhandenen Datei aktiviert oder (false) einen Error erhält, wenn die Zieldatei schon vorhanden ist.

                                      - Sven Rautenberg

                                      1. Hi!

                                        Aber, hmm, dann hat man im $lockdir einen Haufen "unnütze" 0-Byte-Dateien rumliegen, beziehungsweise muss sie erst einmal für die bereits vorhandenen $destdir-Dateien anlegen und darf sie nicht löschen. Besonders hübsch ist das nicht.
                                        Man kann ja zuerst fopen(x) auf die Zieldatei machen, dann nochmal auf eine Lock-Datei, dann muf(), und danach die Lockdatei wieder löschen.

                                        Wird auch nicht wesentlich hübscher.

                                        Je länger wir drüber diskutieren, desto mehr komme ich aber zur Ansicht, dass die Funktion move_uploaded_file() eigentlich vielmehr einen dritten, optionalen Parameter BOOLEAN $overwrite bekommen sollte, mit dem man (default true) das Überschreiben der vorhandenen Datei aktiviert oder (false) einen Error erhält, wenn die Zieldatei schon vorhanden ist.

                                        Sollte auch nicht allzu schwierig zu implementieren sein. Sagst du dem chris_se Bescheid, dass er mal eben einen Patch dafür entwickeln und einreichen soll, der kennt sich doch mit C und dem Innenleben von PHP aus :-)

                                        Lo!

                                      2. Moin Sven,

                                        Je länger wir drüber diskutieren, desto mehr komme ich aber zur Ansicht, dass die Funktion move_uploaded_file() eigentlich vielmehr einen dritten, optionalen Parameter BOOLEAN $overwrite bekommen sollte, mit dem man (default true) das Überschreiben der vorhandenen Datei aktiviert oder (false) einen Error erhält, wenn die Zieldatei schon vorhanden ist.

                                        ACK. Ich habe das mal als Patch eingereicht:

                                        https://bugs.php.net/bug.php?id=55576

                                        LG,
                                         CK

                                        1. Moin!

                                          Je länger wir drüber diskutieren, desto mehr komme ich aber zur Ansicht, dass die Funktion move_uploaded_file() eigentlich vielmehr einen dritten, optionalen Parameter BOOLEAN $overwrite bekommen sollte, mit dem man (default true) das Überschreiben der vorhandenen Datei aktiviert oder (false) einen Error erhält, wenn die Zieldatei schon vorhanden ist.

                                          ACK. Ich habe das mal als Patch eingereicht:

                                          https://bugs.php.net/bug.php?id=55576

                                          Das ist super.

                                          Ein Kritikpunkt: Du hast den Path von der Parameterlogik her genau umgedreht, das finde ich nicht ganz so schön, weil ich in Parameter eigentlich immer das reintue, was ich haben will - vom Gefühl her sind alle anderen PHP-Funktionen nicht so gestrickt, dass es "NOT XYZ"-Parameter gibt, um was abzustellen.

                                          Im Bug selbst wird schon kritisiert, dass move_uploaded_file() nicht nur für Dateisysteme, sondern für beliebige Stream-Wrapper konzipiert ist - und man wundert sich, warum da überhaupt ein unlink() stattfindet.

                                          - Sven Rautenberg

                                        2. Hello Christian, Hello Sven,

                                          Je länger wir drüber diskutieren, desto mehr komme ich aber zur Ansicht, dass die Funktion move_uploaded_file() eigentlich vielmehr einen dritten, optionalen Parameter BOOLEAN $overwrite bekommen sollte, mit dem man (default true) das Überschreiben der vorhandenen Datei aktiviert oder (false) einen Error erhält, wenn die Zieldatei schon vorhanden ist.

                                          ACK. Ich habe das mal als Patch eingereicht:

                                          https://bugs.php.net/bug.php?id=55576

                                          erstmal vielen Dank für den Einsatz. Das ist wohl ein praktikabler Weg, das eine der zwei Probleme aus dem Weg zu räumen :-)

                                          allerdings steckt das eingentliche SICHERHEITS-Kernproblem mMn immer noch drin in der Funktion. Wenn ein shared TMP-Verzeichnis benutzt wird, ist immer noch keine Sicherheit vorhanden.

                                          Der Patch con Christian würde nur das UNGESCHICKLICHKEITS-Problem der Funktion beseitigen.

                                          Wenn ich die Zeilen

                                          5759        if (!zend_hash_exists(SG(rfc1867_uploaded_files), path, path_len + 1)) {
                                              5760            RETURN_FALSE;
                                              5761        }

                                          betrachte, dann nehme ich hier an. dass nur der Hash über den Namen der Datei gebildet wird, nicht jedoch über deren Inhalt. Aber genau dies müsste geschehen. Das war auch schon in dem alten  Thread mein Anliegen.
                                          http://forum.de.selfhtml.org/archiv/2011/4/t204544/#m1385518

                                          Es müssten also an zwei Stellen Änderungen vorgenommen werden:
                                          1. Beim Upload, bevor überhaupt das Script Kontrolle erlangt:
                                             Dort müsste kein Hash über den Namen, sondern über den Inhalt
                                             der Datei in den Speicherbereich des Scriptes geschrieben werden.

                                          2. in den o.g. Zeilen: hier müsste nicht der Hash über den Namen, sondern über den Inhalt
                                             der Datei geprüft werden.
                                             Die Datei müsste für den "Hash abfragen, rename()-durchführen-Prozess" gesperrt werden
                                             gegen jede Änderung. Das lässt ein "rename()" aber nicht zu, weil es kein Handle, sondern
                                             nur einen Namen akzeptiert.

                                          3. Wir müssen also zu Handle-basierten Funktionen auch in der Code-Schicht von PHP kommen.

                                          Anders sehe ich nicht, wie man _ohne_ eigenes upload_tmp_dir für Sicherheit sorgen könnte.

                                          Liebe Grüße aus dem schönen Oberharz

                                          Tom vom Berg

                                          --
                                           ☻_
                                          /▌
                                          / \ Nur selber lernen macht schlau
                                          http://bergpost.annerschbarrich.de
                                          1. Moin!

                                            allerdings steckt das eingentliche SICHERHEITS-Kernproblem mMn immer noch drin in der Funktion. Wenn ein shared TMP-Verzeichnis benutzt wird, ist immer noch keine Sicherheit vorhanden.

                                            Sicherheit gegen was?

                                            Wenn ich die Zeilen

                                            5759        if (!zend_hash_exists(SG(rfc1867_uploaded_files), path, path_len + 1)) {
                                                5760            RETURN_FALSE;
                                                5761        }

                                            betrachte, dann nehme ich hier an. dass nur der Hash über den Namen der Datei gebildet wird, nicht jedoch über deren Inhalt. Aber genau dies müsste geschehen. Das war auch schon in dem alten  Thread mein Anliegen.

                                            Es wird kein Hash gebildet, weder über den Inhalt der Datei noch über den Namen.

                                            zend_hash_exists() ist eine Funktion oder ein Makro, welches in einem Speicherbereich, der genau wie PHP-Arrays hashbasiert indexiert ist, nachsieht, ob dort ein Eintrag für die fragliche Datei existiert - denn nur dann wurde sie in diesem Skript hochgeladen.

                                            Es müssten also an zwei Stellen Änderungen vorgenommen werden:

                                            1. Beim Upload, bevor überhaupt das Script Kontrolle erlangt:
                                                 Dort müsste kein Hash über den Namen, sondern über den Inhalt
                                                 der Datei in den Speicherbereich des Scriptes geschrieben werden.

                                            Warum?

                                            1. in den o.g. Zeilen: hier müsste nicht der Hash über den Namen, sondern über den Inhalt
                                                 der Datei geprüft werden.
                                                 Die Datei müsste für den "Hash abfragen, rename()-durchführen-Prozess" gesperrt werden
                                                 gegen jede Änderung. Das lässt ein "rename()" aber nicht zu, weil es kein Handle, sondern
                                                 nur einen Namen akzeptiert.

                                            Warum?

                                            1. Wir müssen also zu Handle-basierten Funktionen auch in der Code-Schicht von PHP kommen.

                                            Warum?

                                            Anders sehe ich nicht, wie man _ohne_ eigenes upload_tmp_dir für Sicherheit sorgen könnte.

                                            Warum?

                                            - Sven Rautenberg

                                            1. Hello,

                                              Warum?

                                              1. in den o.g. Zeilen: hier müsste nicht der Hash über den Namen, sondern über den Inhalt
                                                   der Datei geprüft werden.
                                                   Die Datei müsste für den "Hash abfragen, rename()-durchführen-Prozess" gesperrt werden
                                                   gegen jede Änderung. Das lässt ein "rename()" aber nicht zu, weil es kein Handle, sondern
                                                   nur einen Namen akzeptiert.

                                              Warum?
                                              Warum?
                                              Warum?

                                              Bitte nachdenken.

                                              Das upload_tmp_dir ist leider bei den meisten Standareinrichtungen ein shared Directory und das T-Flag schützt nur gegen Löschen und Umbenennen, nicht aber gegen Änderung des Inhaltes. So zumindest auf Unix-Installationen. Wenn dann auch noch der "PHP-User" unterschiedlicher Domains derselbe ist, kann man das Datenändern gar nicht mehr verhindern.

                                              Liebe Grüße aus dem schönen Oberharz

                                              Tom vom Berg

                                              --
                                               ☻_
                                              /▌
                                              / \ Nur selber lernen macht schlau
                                              http://bergpost.annerschbarrich.de
                                              1. Hi!

                                                Bitte nachdenken.

                                                Das ist eine nicht durchdachte Forderung. Jeder denkt anders und nicht immer in die beabsichtigte Richtung. Ich dachte, wir bewegen uns gerade nur noch auf der sachlichen Ebene, also lass bitte diese Provokationen.

                                                Das upload_tmp_dir ist leider bei den meisten Standareinrichtungen ein shared Directory und das T-Flag schützt nur gegen Löschen und Umbenennen, nicht aber gegen Änderung des Inhaltes. So zumindest auf Unix-Installationen. Wenn dann auch noch der "PHP-User" unterschiedlicher Domains derselbe ist, kann man das Datenändern gar nicht mehr verhindern.

                                                Du willst jetzt aber nicht einen Safe Mode für Datei-Uploads einführen?

                                                Lo!

                                                1. Hello,

                                                  Das ist eine nicht durchdachte Forderung. Jeder denkt anders und nicht immer in die beabsichtigte Richtung. Ich dachte, wir bewegen uns gerade nur noch auf der sachlichen Ebene, also lass bitte diese Provokationen.

                                                  Tut mir leid, wenn das so ankommt.

                                                  Ich empfinde es als Provokation, wenn Sven dreimal wie ein kleines Kind "warum, warum, warum" fragt. Ich habe erläutert, worum es geht. Das habe ich sogar schon in
                                                  http://forum.de.selfhtml.org/archiv/2011/4/t204544/#m1385518
                                                  getan.

                                                  Das upload_tmp_dir ist leider bei den meisten Standareinrichtungen ein shared Directory und das T-Flag schützt nur gegen Löschen und Umbenennen, nicht aber gegen Änderung des Inhaltes. So zumindest auf Unix-Installationen. Wenn dann auch noch der "PHP-User" unterschiedlicher Domains derselbe ist, kann man das Datenändern gar nicht mehr verhindern.

                                                  Du willst jetzt aber nicht einen Safe Mode für Datei-Uploads einführen?

                                                  Das hat nichts mit _dem_ "Safe-Mode" zu tun, aber wenn Du es so nennen willst, nenne es ruchi "safe_move_uploaded_file()". Das wäre (mMn) die einzige Maßnahme, die eine Manipulation der hochgeladenen Dateien des Users A.a durch den User B.x verhindern kann, wenn ein gemeinsames Upload-Verzeichnis genutzt wird.

                                                  A.a sei ein User a unter Account (Domain) A
                                                  B.x sei ein User x unter Account (Domain) B, z.B. mit erheblicher krimineller Energie

                                                  Solange das File im Temporärverzeichnis (sogar mit t-Flag angelegt) schlummert, kann es von anderen Usern ggf. manipuliert werden. Da nützt es also nichts, wenn nur "uploaded Files" verschoben werden können, wenn die aber nicht sicher gelagert werden können bis zur Verschiebung.

                                                  Der Sinn der Funktion sollte mMn nicht der sein, den User (Programmierer) vor sich selber zu schützen (das leistet sie ja auch nicht, da er beliebige andere Möglichkeiten habt, die Dateien zu verschieben), sondern vor den Angriffen Dritter.

                                                  Und solange sie das nicht tut, bleibt sie mMn obsolet, seitdem es $_FILES als "sicheres Array" gibt.

                                                  Liebe Grüße aus dem schönen Oberharz

                                                  Tom vom Berg

                                                  --
                                                   ☻_
                                                  /▌
                                                  / \ Nur selber lernen macht schlau
                                                  http://bergpost.annerschbarrich.de
                                                  1. Moin!

                                                    Das ist eine nicht durchdachte Forderung. Jeder denkt anders und nicht immer in die beabsichtigte Richtung. Ich dachte, wir bewegen uns gerade nur noch auf der sachlichen Ebene, also lass bitte diese Provokationen.

                                                    Tut mir leid, wenn das so ankommt.

                                                    Ich empfinde es als Provokation, wenn Sven dreimal wie ein kleines Kind "warum, warum, warum" fragt. Ich habe erläutert, worum es geht. Das habe ich sogar schon in
                                                    http://forum.de.selfhtml.org/archiv/2011/4/t204544/#m1385518
                                                    getan.

                                                    Dir sollte mittlerweile klar geworden sein, dass deine Kontrahenten in der Diskussion deine Schlussfolgerungen hinterfragen. Mindestens deswegen, aber eigentlich grundsätzlich, gehört es sich, dass man in einer fachlichen Argumentation seine Gedankengänge vollständig darlegt und nicht darauf hofft, dass durch kurze Benennung des Ausgangspunktes und des selbst gefundenen Ziels der Weg dorthin allen von alleine klar wird.

                                                    Das hat nichts mit _dem_ "Safe-Mode" zu tun, aber wenn Du es so nennen willst, nenne es ruchi "safe_move_uploaded_file()". Das wäre (mMn) die einzige Maßnahme, die eine Manipulation der hochgeladenen Dateien des Users A.a durch den User B.x verhindern kann, wenn ein gemeinsames Upload-Verzeichnis genutzt wird.

                                                    A.a sei ein User a unter Account (Domain) A
                                                    B.x sei ein User x unter Account (Domain) B, z.B. mit erheblicher krimineller Energie

                                                    Solange das File im Temporärverzeichnis (sogar mit t-Flag angelegt) schlummert, kann es von anderen Usern ggf. manipuliert werden. Da nützt es also nichts, wenn nur "uploaded Files" verschoben werden können, wenn die aber nicht sicher gelagert werden können bis zur Verschiebung.

                                                    Der Sinn der Funktion sollte mMn nicht der sein, den User (Programmierer) vor sich selber zu schützen (das leistet sie ja auch nicht, da er beliebige andere Möglichkeiten habt, die Dateien zu verschieben), sondern vor den Angriffen Dritter.

                                                    Und solange sie das nicht tut, bleibt sie mMn obsolet, seitdem es $_FILES als "sicheres Array" gibt.

                                                    Das Szenario, dass ein böser Angreifer die hochgeladene Datei noch vor ihrer Verschiebung verändert, wird durch die Nutzung von $_FILES nicht ausgeschlossen.

                                                    Insofern hat dieses Szenario keinerlei Einfluss auf die Entscheidung, ob move_uploaded_file() obsolet ist, oder nicht, weil die von dir vorgeschlagene Alternative dasselbe Problem hat.

                                                    - Sven Rautenberg

                                                    1. Hello,

                                                      Das Szenario, dass ein böser Angreifer die hochgeladene Datei noch vor ihrer Verschiebung verändert, wird durch die Nutzung von $_FILES nicht ausgeschlossen.

                                                      Genau. Endlich hast Du es verstanden. Weder $_FILES, noch *_uploaded_file() garantieren, dass das File _nicht_ manipuliert wurde.

                                                      $_FILES & File-Handle-Funktionen ist daher in der Lage, _mehr_ "Sicherheit" zu liefern, als move_uploaded_file(), das bekanntermaßen vorhandene Files noch überschreibt.

                                                      Insofern hat dieses Szenario keinerlei Einfluss auf die Entscheidung, ob move_uploaded_file() obsolet ist, oder nicht, weil die von dir vorgeschlagene Alternative dasselbe Problem hat.

                                                      Das sehe ich anders. Move_uploaded_file() suggeriert eine Sicherheit, die es nicht leistet und hat zudem auch noch handwerkliche Fehler (Überschreiben...)

                                                      Liebe Grüße aus dem schönen Oberharz

                                                      Tom vom Berg

                                                      --
                                                       ☻_
                                                      /▌
                                                      / \ Nur selber lernen macht schlau
                                                      http://bergpost.annerschbarrich.de
                                                      1. Hi,

                                                        Weder $_FILES, noch *_uploaded_file() garantieren, dass das File _nicht_ manipuliert wurde.

                                                        $_FILES & File-Handle-Funktionen ist daher in der Lage, _mehr_ "Sicherheit" zu liefern

                                                        Und wo bitte garantieren die „File-Handle-Funktionen“,

                                                        dass das File _nicht_ manipuliert wurde.

                                                        ?

                                                        Das tun sie keineswegs.
                                                        Mehr Sicherheit in Bezug darauf liefern sie also absolut *nicht*.

                                                        MfG ChrisB

                                                        --
                                                        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                                                      2. Moin!

                                                        Das Szenario, dass ein böser Angreifer die hochgeladene Datei noch vor ihrer Verschiebung verändert, wird durch die Nutzung von $_FILES nicht ausgeschlossen.

                                                        Genau. Endlich hast Du es verstanden. Weder $_FILES, noch *_uploaded_file() garantieren, dass das File _nicht_ manipuliert wurde.

                                                        $_FILES & File-Handle-Funktionen ist daher in der Lage, _mehr_ "Sicherheit" zu liefern, als move_uploaded_file(), das bekanntermaßen vorhandene Files noch überschreibt.

                                                        Indem du alles in einem Topf wirfst und durchrührst, erzeugst du zwar eventuell Verwirrung, aber klare und logische Argumentation sieht anders aus.

                                                        Die Anfälligkeit von hochgeladenen Dateien in einem userübergreifenden TMP-Verzeichnis für Manipulationen hat absolut nichts mit dem durch PHP zu vollziehenden Verschieben der Datei an ihren finalen Platz zu tun.

                                                        Warum hast du plötzlich dieses Argument an den Haaren herbeigezogen? Das Problem ist durch passende Konfiguration zu lösen.

                                                        Insofern hat dieses Szenario keinerlei Einfluss auf die Entscheidung, ob move_uploaded_file() obsolet ist, oder nicht, weil die von dir vorgeschlagene Alternative dasselbe Problem hat.

                                                        Das sehe ich anders. Move_uploaded_file() suggeriert eine Sicherheit, die es nicht leistet und hat zudem auch noch handwerkliche Fehler (Überschreiben...)

                                                        Wenn du alle möglichen Sicherheitsszenarien an den Haaren herbeiziehst und jeweils ohne eigene Argumentation, sondern durch Gedankenübertragung (Zitat Tom: "Bitte nachdenken."), versuchst, dass das Publikum selbst die Sicherheitslücke erkennt, die du angeblich siehst, dann halte ich das für keine seriöse Argumentationsmethode.

                                                        Fassen wir nochmal zusammen:

                                                        move_uploaded_file() garantiert, dass nur wirklich hochgeladene Dateien verschoben werden. Wenn die Zieldatei bereits existiert, wird sie dabei überschrieben. Es ist möglich, mit weiterem Code um move_uploaded_file() herum auch eine Absicherung gegen dieses Überschreiben zu programmieren.

                                                        Der Zugriff auf $_FILES allein garantiert NICHT, dass nur wirklich hochgeladene Dateien verschoben werden. Es ist möglich, mit weiterem Code eine Absicherung gegen Überschreiben zu programmieren.

                                                        Und trotzdem propagierst du weiterhin, move_uploaded_file() wäre obsolet? Du hast immer noch keinen PHP-Code geliefert, der in deinem Killerszenario für jeden möglichen Anwendungsfall von move_uploaded_file() die Überlegenheit von $_FILES darlegt und deshalb die Obsoleterklärung beweist.

                                                        Nur weil eine Funktion nicht in allen Fällen benutzt wird, bedeutet das noch lange nicht, dass sie obsolet ist. Du benutzt ja auch nicht überall strtr(), trotzdem ist sie nicht obsolet.

                                                        - Sven Rautenberg

                                                  2. Hi!

                                                    Du willst jetzt aber nicht einen Safe Mode für Datei-Uploads einführen?
                                                    Das hat nichts mit _dem_ "Safe-Mode" zu tun,

                                                    Deswegen schrieb ich ja "einen". Der Safe Mode ist bekanntlich die falsche Antwort auf Probleme beim Massenhosting mit Einbindung PHPs als Modul in den Apachen gewesen. Das Sicherheitsproblem, wenn alle Kunden/Anwendungen unter einem User laufen, muss anderweitig gelöst werden. Zum Beispiel mit CGI und dediziertem Nutzer je Kunde/Anwendung.

                                                    aber wenn Du es so nennen willst, nenne es ruchi "safe_move_uploaded_file()". Das wäre (mMn) die einzige Maßnahme, die eine Manipulation der hochgeladenen Dateien des Users A.a durch den User B.x verhindern kann, wenn ein gemeinsames Upload-Verzeichnis genutzt wird.

                                                    Das Problem löst sich von selbst, wenn jeder sein eigenes Upload-Verzeichnis konfiguriert bekommt. Die Lösung des Problems ist bereits da, genau wie die Mittel im Betriebssystem plus Tools (suexec) den Safe Mode überflüssig machen.

                                                    Lo!

                                                    1. Hello,

                                                      Du willst jetzt aber nicht einen Safe Mode für Datei-Uploads einführen?
                                                      Das hat nichts mit _dem_ "Safe-Mode" zu tun,

                                                      Deswegen schrieb ich ja "einen". Der Safe Mode ist bekanntlich die falsche Antwort auf Probleme beim Massenhosting mit Einbindung PHPs als Modul in den Apachen gewesen. Das Sicherheitsproblem, wenn alle Kunden/Anwendungen unter einem User laufen, muss anderweitig gelöst werden. Zum Beispiel mit CGI und dediziertem Nutzer je Kunde/Anwendung.

                                                      aber wenn Du es so nennen willst, nenne es ruchi "safe_move_uploaded_file()". Das wäre (mMn) die einzige Maßnahme, die eine Manipulation der hochgeladenen Dateien des Users A.a durch den User B.x verhindern kann, wenn ein gemeinsames Upload-Verzeichnis genutzt wird.

                                                      Das Problem löst sich von selbst, wenn jeder sein eigenes Upload-Verzeichnis konfiguriert bekommt. Die Lösung des Problems ist bereits da, genau wie die Mittel im Betriebssystem plus Tools (suexec) den Safe Mode überflüssig machen.

                                                      Sag ich doch die ganze Zeit.

                                                      Nun habe ich mal eben versucht, einen Pluspunkt für Euren Standpunkt (move_uploaded_file() sei notwenig) zu finden, und dann ist Dir das auch nicht recht.

                                                      Also fassen wir mal zusammen:
                                                      "Die Lösung des Problems ist bereits da"

                                                      Ich substantiiere:
                                                      Durch Wahl eines eigenen Upload-Verzeichnisses pro Domain (Useraccount),
                                                      konsequente Verwendung von open_basedir
                                                      und Benutzung des Arrays $_FILES

                                                      kann man gezielt und sicher Dateien hochladen lassen, ohne Angst haben zu müssen, dass diese vor dem persistenten Speichern noch manipuliert werden.

                                                      Das entbindet den Programmierer selbstverständlich nicht, die übrigen Sicherheitsüberlegungn noch zu berücksichtigen:

                                                      • Inhalt der Datei
                                                      • Ausführbarkeit verhindern
                                                      • ...

                                                      die *_move_uploaded_file()-Funktionen sind damit also obselet geworden und brauchen nicht weiter gepflegt zu werden...

                                                      Liebe Grüße aus dem schönen Oberharz

                                                      Tom vom Berg

                                                      --
                                                       ☻_
                                                      /▌
                                                      / \ Nur selber lernen macht schlau
                                                      http://bergpost.annerschbarrich.de
                                                      1. Hi,

                                                        die *_move_uploaded_file()-Funktionen sind damit also obselet geworden und brauchen nicht weiter gepflegt zu werden...

                                                        Siehe bitte https://forum.selfhtml.org/?t=206726&m=1403956 und nachfolgende Diskussion.

                                                        MfG ChrisB

                                                        --
                                                        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                                                      2. Moin!

                                                        Ich substantiiere:
                                                        Durch Wahl eines eigenen Upload-Verzeichnisses pro Domain (Useraccount),
                                                        konsequente Verwendung von open_basedir
                                                        und Benutzung des Arrays $_FILES

                                                        kann man gezielt und sicher Dateien hochladen lassen, ohne Angst haben zu müssen, dass diese vor dem persistenten Speichern noch manipuliert werden.

                                                        Diese Aussage hast du schon zu Beginn der Diskussion getroffen, ihr wurde substanziiert widersprochen.

                                                        Die Wiederholung der Aussage führt die Diskussion also nicht weiter, sondern im Kreis.

                                                        die *_move_uploaded_file()-Funktionen sind damit also obselet geworden und brauchen nicht weiter gepflegt zu werden...

                                                        Nur die *_uploaded_file()-Funktionen prüfen, ob der darin angegebene Dateiname tatsächlich von einem Upload im aktuellen Skriptaufruf stammt. Diese Prüfung ist durch keine Alternative innerhalb von PHP-Code zu ersetzen.

                                                        - Sven Rautenberg

                                                        1. Hello,

                                                          Nur die *_uploaded_file()-Funktionen prüfen, ob der darin angegebene Dateiname tatsächlich von einem Upload im aktuellen Skriptaufruf stammt. Diese Prüfung ist durch keine Alternative innerhalb von PHP-Code zu ersetzen.

                                                          Du willst also sagen, dass $_FILES nach Belieben von anderen Instanzen manipuliert werden kann?
                                                          Das genau zeichnet doch aber $_FILES, $_GET, $_POST, ... aus, dass das eben nicht mehr möglich ist. Die Arrays werden im ausschließlichen Einflussbereich des Scriptes gespeichert und sollten keinerlei Manipulation mehr ermöglichen.

                                                          Da die Werte

                                                          • $_FILES['uploadfilename']['error']
                                                          • $_FILES['uploadfilename']['tmp_name']
                                                          • $_FILES['uploadfilename']['size']

                                                          vom Server angelegt werden, sollten sie sicher sein!

                                                          Anderenfalls zeig mir bitte die Stelle, an der fremde Instanzen noch Zugriff darauf hätten. Dann hätten wir diese ganze Diskussion tatsächlich abkürzen können!

                                                          Liebe Grüße aus dem schönen Oberharz

                                                          Tom vom Berg

                                                          --
                                                           ☻_
                                                          /▌
                                                          / \ Nur selber lernen macht schlau
                                                          http://bergpost.annerschbarrich.de
                                                          1. Hi,

                                                            Nur die *_uploaded_file()-Funktionen prüfen, ob der darin angegebene Dateiname tatsächlich von einem Upload im aktuellen Skriptaufruf stammt. Diese Prüfung ist durch keine Alternative innerhalb von PHP-Code zu ersetzen.

                                                            Du willst also sagen, dass $_FILES nach Belieben von anderen Instanzen manipuliert werden kann?
                                                            Das genau zeichnet doch aber $_FILES, $_GET, $_POST, ... aus, dass das eben nicht mehr möglich ist. Die Arrays werden im ausschließlichen Einflussbereich des Scriptes gespeichert und sollten keinerlei Manipulation mehr ermöglichen.

                                                            Nein, $_FILES kann von Script selber manipuliert werden. Und da man nicht immer weiß, in welchem Zusammenhang dein Script läuft, muss man da eben auch von ausgehen.

                                                            Beispiele wären:
                                                             - dein Script läuft als Modul/Plugin/... in einem anderen Script.
                                                             - du bindest Fremdmodule ein (welche Schadcode enthalten können)

                                                            muf() ist frei von dieser Fehlerquelle, weil die Prüfung nicht aus PHP-Scope manipuliert werden kann.

                                                            Das wurde dir in diesem Thread schon mindestens(!) dreimal gesagt. Warum verlangst du eigentlich immer noch Beispiele?

                                                            Bis die Tage,
                                                            Matti

                                                            1. Hello Matti,

                                                              Nein, $_FILES kann von Script selber manipuliert werden. Und da man nicht immer weiß, in welchem Zusammenhang dein Script läuft, muss man da eben auch von ausgehen.

                                                              Das ist durchaus fast richtig. Aber ein Filial-Script-Programmierer kann in PHP derzeit noch alles tun. In dem Moment, in dem sein Script eingebunden wird, darf er alles, was das Hauptscript auch darf.

                                                              Es wird Dir bei der Hintergrundrecherche zu Deinem Posting sicherlich nicht entgasngen sein, dass http://de3.php.net/manual/en/ini.core.php#ini.disable-functions nur mit den Rechten
                                                              "php.ini only" möglich ist, also nicht im Script selber weiter eingeschränkt werden kann.

                                                              Wenn dieses Manko mal abgeschafft sein wird, dann haben wir vielleicht PHP 7.0 und ich werde mir Deinen Einwand nochmals zu Herzen nehmen, sollte er dann noch Bestand haben.

                                                              Liebe Grüße aus dem schönen Oberharz

                                                              Tom vom Berg

                                                              --
                                                               ☻_
                                                              /▌
                                                              / \ Nur selber lernen macht schlau
                                                              http://bergpost.annerschbarrich.de
                                                          2. Moin!

                                                            Nur die *_uploaded_file()-Funktionen prüfen, ob der darin angegebene Dateiname tatsächlich von einem Upload im aktuellen Skriptaufruf stammt. Diese Prüfung ist durch keine Alternative innerhalb von PHP-Code zu ersetzen.

                                                            Du willst also sagen, dass $_FILES nach Belieben von anderen Instanzen manipuliert werden kann?

                                                            Das will ich nicht sagen, aber Fakt ist: In $_FILES steht einfach nur ein Dateiname drin, und dieser Wert ist nicht schreibgeschützt. Wenn also irgendwo eine Code-Injection passieren kann, entweder als manipuliertbare Sicherheitslücke oder durch unbewußte Schadcodeeinschleppung (z.B. Installation eines bösartigen Plugins), ist dieser Wert genauso gefährdet.

                                                            Man wird bei objektorientierter Programmierung $_FILES in der Regel auch nicht direkt als "global state" innerhalb einer für das Prüfen und Verschieben von Dateien zuständigen Klasse verwenden, sondern in der Regel einem Request-Objekt alle zugehörigen Superglobalen als Dependency übergeben. $_FILES ist zu diesem Zeitpunkt also längst nicht mehr der Name der Datenstruktur, die der Verschiebecode tatsächlich benutzt. Und deshalb geht dir der Aufmerksamkeitsfaktor von $_FILES = "Hier gehts um hochgeladene Dateien" verloren, weil vermutlich nur noch ein $tmpfile in ein $targetfile kopiert wird - was mit move_uploaded_file() nur dann funktioniert, wenn die Datei tatsächlich hochgeladen war, egal ob der Dateiname ursprünglich aus $_FILES kam, oder sonstwoher.

                                                            Das genau zeichnet doch aber $_FILES, $_GET, $_POST, ... aus, dass das eben nicht mehr möglich ist. Die Arrays werden im ausschließlichen Einflussbereich des Scriptes gespeichert und sollten keinerlei Manipulation mehr ermöglichen.

                                                            http://www.google.de/search?q=php+remote+code+exection+vulnerability

                                                            Ja, man wird drüber streiten können, ob es bei solch einer Lücke tatsächlich noch notwendig ist, irgendwelche Uploads auf existierende, interessante Dateien umzubiegen - aber das Argument, es sei keinerlei Manipulation mehr möglich, das ist falsch. Von "außen" (parallel laufende Skripte etc.) eher nicht (ungeschützer fremder Speicherzugriff auf den Variableninhalt von $_FILES sei mal auszuschließen), aber im laufenden Skript selbstverständlich.

                                                            Da die Werte

                                                            • $_FILES['uploadfilename']['error']
                                                            • $_FILES['uploadfilename']['tmp_name']
                                                            • $_FILES['uploadfilename']['size']

                                                            vom Server angelegt werden, sollten sie sicher sein!

                                                            In der ersten Zeile an Position 0 des ausgeführten Skripts: Ja. Danach nicht mehr.

                                                            Anderenfalls zeig mir bitte die Stelle, an der fremde Instanzen noch Zugriff darauf hätten. Dann hätten wir diese ganze Diskussion tatsächlich abkürzen können!

                                                            https://forum.selfhtml.org/?t=206726&m=1403987

                                                            Deine Reaktion darauf... naja. Sachliche Diskussion ist was anderes.

                                                            - Sven Rautenberg

                      2. Ich meine weitererhin, dass sie seit EInführung von $_FILES mehr Schaden anrichten kann, als sie Nutzen hat.

                        Na dann begründe es doch endlich und erklär uns,  wie die bessere Alternative aussieht. Langsam glaub ich, du bist dazu nicht in der Lage und zu einem Troll mutiert.

                      3. Hallo,

                        abgesehen von der Tatsache, dass du deine Aussagen immer weiter in den Umfang der Beliebigkeit rueckts und dadurch deine intentionale Kernaussage (zur Schaulust aller anderen) eigenstaendig entkraeftest, haettest du uns diesen ganzen dutzende Postings umfassenden Thread so leicht ersparen koennen, indem du ganz einfach in deinem Ursprungsposting direkt erklaert haettest, warum du *_uploaded_file() - entgegen der allgemeinen Auffassung (worunter auch die Positionen der PHP-Entwickler fallen) - als obsolet verstehst.
                        Anderen dann Argumentationsarmut oder gar Boeswilligkeit zu unterstellen zielt schon meilenweit an deinem Vorhaben vorbei. Wenn du tatsaechlich das Gefuehl haben solltest, einen Loesungsansatz vorweisen zu koennen, der bisherige Vorgehensweisen in den Schatten stellt.. nur zu. *Liefere* den Beweis, und keiner wird dir auf die Fuesze treten. Aber so lange nur eine geballtes Bla Bla deinerseits kommt darfst du dich nun wirklich nicht ob der kritikbehafteten Antworten wundern.

                        Grusz,
                        Christopher

    3. move_uploaded_file() ist obsolet, wenn man $_FILES benutzt

      Toms vor über drei Jahren angekündigte detaillierten Ausführungen zu

      Alle OOP-Konzepte, die ich bisher kennengelernt habe, sind auch nur Bastelkisten, Java vielleicht gerade mal ausgenommen.

      fanden nie statt. Alle Jahre wieder...

    4. Ich bin jetzt an einem Punkt, wo ich eine Uploadfunktion schreiben muss. Kann ich damit rechnen, dass du mir jetzt sagst, wie ich es machen muss oder muss ich doch auf die obsoleten Funktionen zurückgreifen?

      Ich denke, die Zeit von deiner Aussage bis heute sollte ausreichen, dass du eine Lösung oder zumindest einen Ansagt präsentierst.

      1. Hello,

        Ich bin jetzt an einem Punkt, wo ich eine Uploadfunktion schreiben muss. Kann ich damit rechnen, dass du mir jetzt sagst, wie ich es machen muss oder muss ich doch auf die obsoleten Funktionen zurückgreifen?

        Das überführen der Datei aus dem Temporärverzeichnis in die persistente Ablage kannst Du gerne mit der mMn obseleten Funktion move_uploaded_file() tun, wenn dir die Zieldateien egal sind, Du sie also notfalls auch überschreiben kannst.

        Die Funktion bietet gegenüber einer generischen Lösung keinen echten Vorteil, sondern auf jeden Fall diesen beschriebenen Nachteil mit dem Überschreiben.

        • fopen(quelle, nur lesend)
        • flock(quelle, shared)
        • fopen(ziel, nicht überschreibend/überschreibend, je nach Wunsch)
        • flock(ziel, exclusive)
        • Schleife fread(quelle, Datenblock) -> fwrite(ziel, Datenblock) bis Ende bei Quelle erreicht
        • fclose(quelle)
        • fclose(ziel)

        Bei jedem Schritt muss eine Fehlerauswertung vorgenommen werden.

        Viel wichtiger ist aber, dass Du dir nochmal durchliest, was ich bisher im Artikel schon geschrieben habe über

        • open_basedir
        • upload_tmp_dir
        • Kontrolle des Dateinamens (keine Pfade!)
        • Kontrolle der Dateiendung (möglichst richtigstellen laut MIME-Type)
        • keine Scripte zulassen
        • am besten nur bestimmte Dateiendungen zulassen aus einer Positivliste
        • Scriptausführung im Ablageverzeichnis (wenn es über HTTP/s erreichbar ist) unterbinden
        • ...

        http://wiki.selfhtml.org/wiki/Artikel:PHP/File_Upload

        Bei Shared Hosting:
        Bei PHP als Modul ist ein eigenes upload_tmp_dir für jeden virtual Host mMn die wichtigste Sicherheitsmaßnahme, die aber nur dann greift, wenn open_basedir auch vernünftig eingestellt wird.

        Bei PHP als CGI/Fast-CGI gibt es noch andere Möglichkeiten, da da jeder Virtual-Host sowieso unter einem eigenen User läuft und bei vernünftigen Einrichtung des Temporärverzeichnisses sowieso nur dieser User zugreifen kann.

        Ich denke, die Zeit von deiner Aussage bis heute sollte ausreichen, dass du eine Lösung oder zumindest einen Ansagt präsentierst.

        Wie kommst Du dazu, über meine Zeit zu verfügen?

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hello,

          Bei Shared Hosting:
          Bei PHP als Modul ist ein eigenes upload_tmp_dir für jeden virtual Host mMn die wichtigste Sicherheitsmaßnahme, die aber nur dann greift, wenn open_basedir

          BEI ALLEN VIRTUAL HOSTS

          auch vernünftig eingestellt wird.

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
        2. Hi,

          Das überführen der Datei aus dem Temporärverzeichnis in die persistente Ablage kannst Du gerne mit der mMn obseleten Funktion move_uploaded_file() tun, wenn dir die Zieldateien egal sind, Du sie also notfalls auch überschreiben kannst.

          Die Funktion bietet gegenüber einer generischen Lösung keinen echten Vorteil

          Gelogen.
          Oder du hast immer noch keine Ahnung, obwohl du inzwischen reichlich Zeit hattest, dich mit den *Argumenten* zu beschäftigen.

          Beides zeichnet fachlich betrachtet kein schönes Bild von dir.

          MfG ChrisB

          --
          RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
          • fopen(quelle, nur lesend)
          • flock(quelle, shared)
          • fopen(ziel, nicht überschreibend/überschreibend, je nach Wunsch)
          • flock(ziel, exclusive)
          • Schleife fread(quelle, Datenblock) -> fwrite(ziel, Datenblock) bis Ende bei Quelle erreicht
          • fclose(quelle)
          • fclose(ziel)

          Ich soll also die ganze Datei durch den Speicher schaufeln? Kannst du mir erklären, wie ich das bei vielen Uploads mache ohne dass das RAM knapp wird?
          Insbesondere, da hier zwei Streams aktiv sind die beide Speicher fressen.

          Ich lade jetzt also 4 Dateien hoch, bei der jede 2 GB gross ist. Wie soll das RAM das verkraften?

          Viel wichtiger ist aber, dass Du dir nochmal durchliest, was ich bisher im Artikel schon geschrieben habe über

          • open_basedir
          • upload_tmp_dir
          • Kontrolle des Dateinamens (keine Pfade!)
          • Kontrolle der Dateiendung (möglichst richtigstellen laut MIME-Type)
          • keine Scripte zulassen
          • am besten nur bestimmte Dateiendungen zulassen aus einer Positivliste
          • Scriptausführung im Ablageverzeichnis (wenn es über HTTP/s erreichbar ist) unterbinden

          Also soll ich meine Funktion so entwerfen, dass ein Anwender den Hoster vorschreiben muss, wie er seinen Server konfigurieren muss? Erklärst du mir auch, wie das bei Massenhostern gehen soll? Hast du für Strato, 1&1 usw. nen Ansprechpartner, der dafür zuständig ist?
          Ansonsten ist dieser Typ insofern fürn Arsch, weil die relevanten Anwender gegen null tendieren.

          Bei Shared Hosting:
          Bei PHP als Modul ist ein eigenes upload_tmp_dir für jeden virtual Host mMn die wichtigste Sicherheitsmaßnahme, die aber nur dann greift, wenn open_basedir auch vernünftig eingestellt wird.

          Und wie hat mein Script darauf Einfluss? Wäre schon schön, wenn deine Tips auch umsetzbar sind.

          Bei PHP als CGI/Fast-CGI gibt es noch andere Möglichkeiten, da da jeder Virtual-Host sowieso unter einem eigenen User läuft und bei vernünftigen Einrichtung des Temporärverzeichnisses sowieso nur dieser User zugreifen kann.

          Und wie kann das Script prüfen ob die  Einrichtung vernünftig ist? Hast du dafür auch nen Ansatz wie man per Script den Server prüfen kann?

          Wie kommst Du dazu, über meine Zeit zu verfügen?

          Du kennst den Unterschied ob ich meine Meinung sage oder dir etwas vorschreibe? Wenn meine geäusserte Meinung nicht zutrifft, steh es dir doch frei, ihr zu widersprechen. Wenn du das nicht tust, könnte das als Zustimmung gewertet werden, dass du dich angegriffen fühlst, suggeriert ähnliches.

          Und ja, mein Posting ist provokativ, verklag mich :P

          1. Hi!

            • fopen(quelle, nur lesend)
            • flock(quelle, shared)
            • fopen(ziel, nicht überschreibend/überschreibend, je nach Wunsch)
            • flock(ziel, exclusive)
            • Schleife fread(quelle, Datenblock) -> fwrite(ziel, Datenblock) bis Ende bei Quelle erreicht
            • fclose(quelle)
            • fclose(ziel)

            Ich soll also die ganze Datei durch den Speicher schaufeln? Kannst du mir erklären, wie ich das bei vielen Uploads mache ohne dass das RAM knapp wird?

            Üblicherweise nimmt man eine Blockgröße von wenigen KB. Damit ist der RAM-Verbrauch sehr überschaubar.

            Insbesondere, da hier zwei Streams aktiv sind die beide Speicher fressen.

            Zweimal wenige KB sind auch noch kein Kollapsgrund.

            Ich lade jetzt also 4 Dateien hoch, bei der jede 2 GB gross ist. Wie soll das RAM das verkraften?

            Sehr gut. Es ist nur die Zeit, die für das Kopieren statt Umbenennen/Verschieben draufgeht. Bei muf() wird sie nur benötigt, wenn das Umbenennen nicht geht, dann kopiert auch muf() die Datei nach obigem Prinzip.

            Viel wichtiger ist aber, dass Du dir nochmal durchliest, was ich bisher im Artikel schon geschrieben habe über

            • open_basedir
            • upload_tmp_dir
            • Kontrolle des Dateinamens (keine Pfade!)
            • Kontrolle der Dateiendung (möglichst richtigstellen laut MIME-Type)
            • keine Scripte zulassen
            • am besten nur bestimmte Dateiendungen zulassen aus einer Positivliste
            • Scriptausführung im Ablageverzeichnis (wenn es über HTTP/s erreichbar ist) unterbinden

            Also soll ich meine Funktion so entwerfen, dass ein Anwender den Hoster vorschreiben muss, wie er seinen Server konfigurieren muss?

            Nein, aber es wäre auch im Interesse des Hosters, wenn er die sicherheitsrelevanten Punkte beachten würde. Sie sind nämlich auch bei der Verwendung von muf() relevant, und zwar im gleichen Maße. muf() stellt nur sicher, dass der Dateiname eine hochgeladene Datei ist. Mit beiden Ansätzen kann eine Manipulation nicht ausgeschlossen werden, wenn die hochgeladenen Dateien in öffentlichen Verzeichnissen rumliegen oder irgendwie anders für andere schreibbar sind.

            Erklärst du mir auch, wie das bei Massenhostern gehen soll? Hast du für Strato, 1&1 usw. nen Ansprechpartner, der dafür zuständig ist?

            Bei den Webhosting-Angeboten von 1&1 ist mir bisher nur die CGI-Variante begegnet und dafür kann man eine eigene php.ini aufsetzen. Zumindest bei 1&1 kann man sich selbst darum kümmern.

            Ansonsten ist dieser Typ insofern fürn Arsch, weil die relevanten Anwender gegen null tendieren.

            Das finde ich nicht.

            Bei Shared Hosting:
            Bei PHP als Modul ist ein eigenes upload_tmp_dir für jeden virtual Host mMn die wichtigste Sicherheitsmaßnahme, die aber nur dann greift, wenn open_basedir auch vernünftig eingestellt wird.
            Und wie hat mein Script darauf Einfluss? Wäre schon schön, wenn deine Tips auch umsetzbar sind.

            Prinzipbedingt hat ein Script keinen Einfluss darauf. Das war weder gefordert, noch hat Tom versprochen, dieses Problem durch seine Kopiermethode zu lösen. Es ist aber nicht generell nicht umsetzbar.

            Bei PHP als CGI/Fast-CGI gibt es noch andere Möglichkeiten, da da jeder Virtual-Host sowieso unter einem eigenen User läuft und bei vernünftigen Einrichtung des Temporärverzeichnisses sowieso nur dieser User zugreifen kann.

            Laufen sollte. Wenn man aber das langsamere CGI statt Modul verwendet, dann sollte man wenigstens den Vorteil der Sicherheit durch eigenen User mitnehmen.

            Und wie kann das Script prüfen ob die  Einrichtung vernünftig ist? Hast du dafür auch nen Ansatz wie man per Script den Server prüfen kann?

            Man kan im Script die Konfigurationswerte auslesen. Allerdings ist es sehr aufwendig, einem Script beizubringen, gute von schlechten Werten zu unterscheiden. Doch wann braucht man das im Script? Sowas wäre eher für Setup-Scripte interessant und sinnvoll. Man kann sich aber auch vorher informieren, ob die Werte bereits ordentlich konfiguriert sind (oder sie passend selbst konfigurieren, wenn man daran nicht gehindert wird).

            Und ja, mein Posting ist provokativ, verklag mich :P

            Leider hat es auch wenig argumentative Substanz. Du hättest lieber die bereits ausgetauschten Argmente aufmerksam lesen sollen. Vieles davon wurde bereits geklärt und ist nicht mehr Gegenstand der Überzeugungsarbeit Tom gegenüber.

            Aus deinem anderen Posting:

            Und selbst wenn ich das Überschreiben verhindern will, wird es mit muf() nur ein Zweizeiler, denn ein file_exists ist doch ein klein wenig weniger Code als die Lösung von dir,die im Übrigen das gleiche Problem bietet, was du anprangerst, da in der Zeit zwischen fopen und flock die Datei von einem anderen Script manipuliert, gelöscht, verschoben, geändert oder sonst was werden kann.

            Manipulation soll und kann damit nicht verhindert werden, dafür sind die Dateirechte und Verzeichniskonfigurationen das Mittel der Wahl. Toms Vorschlag kann wenigstens verhindern, dass zwischen file_exists() und dem Verschieben/Kopieren ein anderer Prozess eine Datei gleichen Namens anlegt, denn fopen($mode: x) offnet die Datei nur, wenn sie nicht existiert. An dieser Stelle kann abgebrochen werden. Dass diese Funktionalität in muf() eingebaut wird, sind bereits Bestrebungen im Gange.

            Somit löst dein Ansatz in keinster Weise dein Problem (was IMO keins ist) sondern vergrössert lediglich den Ressourcenverbrauch und die Codelänge, dafür verlängert sich auch die Verarbeitungsgeschwindigkeit.
            Somit hat deine Lösung als _keine_ Vorteile aber _sehr viele gravierende_ Nachteile.

            Sie hat (noch) den Vorteil, dass sie nicht blind überschreibt. Die muf()-Lösung wird auch zum Mehralszweizeiler, wenn man das Überschreiben ordentlich verhindern will (siehe https://forum.selfhtml.org/?t=206726&m=1404169 ff.). Ansonsten sind die Nachteile eigentlich nur der längere Code und die Manipulierbarkeit der Einträge in $_FILES.

            Lo!

            1. Hello,

              Ich soll also die ganze Datei durch den Speicher schaufeln? Kannst du mir erklären, wie ich das bei vielen Uploads mache ohne dass das RAM knapp wird?

              Üblicherweise nimmt man eine Blockgröße von wenigen KB. Damit ist der RAM-Verbrauch sehr überschaubar.

              Viel wichtiger ist aber, dass Du dir nochmal durchliest, was ich bisher im Artikel schon geschrieben habe über

              • open_basedir
              • upload_tmp_dir
              • Kontrolle des Dateinamens (keine Pfade!)
              • Kontrolle der Dateiendung (möglichst richtigstellen laut MIME-Type)
              • keine Scripte zulassen
              • am besten nur bestimmte Dateiendungen zulassen aus einer Positivliste
              • Scriptausführung im Ablageverzeichnis (wenn es über HTTP/s erreichbar ist) unterbinden

              Also soll ich meine Funktion so entwerfen, dass ein Anwender den Hoster vorschreiben muss, wie er seinen Server konfigurieren muss?

              ... richtig auswählen, nicht bevormunden

              Bei Shared Hosting:
              Bei PHP als Modul ist ein eigenes upload_tmp_dir für jeden virtual Host mMn die wichtigste Sicherheitsmaßnahme, die aber nur dann greift, wenn open_basedir auch vernünftig eingestellt wird.

              Und wie hat mein Script darauf Einfluss? Wäre schon schön, wenn deine Tips auch umsetzbar sind.

              Ok, guter Hinweis. Dass man das per Script feststellen kann, darauf werde ich im Artikel also noch eingehen.

              Du schaust bitte erstmal in die Ausgaben von phpinfo(). Die sagen Dir (fast) alles.

              Leider geben sie auch keine Auskunft darüber, ob die Einstellungen für open_basedir für alle anderen Shared-Hosting-Teilnehmer richtig sind. Denn die sind ja dafür da, dass Dein Script nicht auf die Bereiche der anderen Accounts zugreifen kann und bei den Anderen entsprechend umgekehrt.

              Und wie kann das Script prüfen ob die  Einrichtung vernünftig ist? Hast du dafür auch nen Ansatz wie man per Script den Server prüfen kann?

              Wie gesagt, dein Hinweis ist gut. Siehe phpinfo()

              Aus deinem anderen Posting:

              Und selbst wenn ich das Überschreiben verhindern will, wird es mit muf() nur ein Zweizeiler, denn ein file_exists ist doch ein klein wenig weniger Code als die Lösung von dir,die im Übrigen das gleiche Problem bietet, was du anprangerst, da in der Zeit zwischen fopen und flock die Datei von einem anderen Script manipuliert, gelöscht, verschoben, geändert oder sonst was werden kann.

              File_exists() ist ungeeigent für derartige Aufgaben. Da wären wir dann schon beim nächsten Thema (TOCTTOU). Aber darüber findest Du im Archiv schon genug Stoff, bevor wir mit dem Diskutieren beginnen ;-)

              Manipulation soll und kann damit nicht verhindert werden, dafür sind die Dateirechte und Verzeichniskonfigurationen das Mittel der Wahl. Toms Vorschlag kann wenigstens verhindern, dass zwischen file_exists() und dem Verschieben/Kopieren ein anderer Prozess eine Datei gleichen Namens anlegt, denn fopen($mode: x) offnet die Datei nur, wenn sie nicht existiert. An dieser Stelle kann abgebrochen werden. Dass diese Funktionalität in muf() eingebaut wird, sind bereits Bestrebungen im Gange.

              Somit löst dein Ansatz in keinster Weise dein Problem (was IMO keins ist) sondern vergrössert lediglich den Ressourcenverbrauch und die Codelänge, dafür verlängert sich auch die Verarbeitungsgeschwindigkeit.
              Somit hat deine Lösung als _keine_ Vorteile aber _sehr viele gravierende_ Nachteile.

              Sie hat (noch) den Vorteil, dass sie nicht blind überschreibt. Die muf()-Lösung wird auch zum Mehralszweizeiler, wenn man das Überschreiben ordentlich verhindern will (siehe https://forum.selfhtml.org/?t=206726&m=1404169 ff.). Ansonsten sind die Nachteile eigentlich nur der längere Code und die Manipulierbarkeit der Einträge in $_FILES.

              Eben die Manipulation der Einträge in $_FILES sollte doch aber durch fremde Instanzen nicht möglich sein. Das genau zeichnet doch $_FILES (und $_POST und $_GET, ...) aus.

              Und den Programmierer vor sich selber schützen kann man sowieso nicht wirklich.

              Liebe Grüße aus dem schönen Oberharz

              Tom vom Berg

              --
               ☻_
              /▌
              / \ Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
              1. Hi!

                Sie hat (noch) den Vorteil, dass sie nicht blind überschreibt. Die muf()-Lösung wird auch zum Mehralszweizeiler, wenn man das Überschreiben ordentlich verhindern will (siehe https://forum.selfhtml.org/?t=206726&m=1404169 ff.). Ansonsten sind die Nachteile eigentlich nur der längere Code und die Manipulierbarkeit der Einträge in $_FILES.

                Eben die Manipulation der Einträge in $_FILES sollte doch aber durch fremde Instanzen nicht möglich sein. Das genau zeichnet doch $_FILES (und $_POST und $_GET, ...) aus.

                Fremde Instanzen auf Abstand zu halten ist Aufgabe der System- und PHP-Konfiguration.

                Und den Programmierer vor sich selber schützen kann man sowieso nicht wirklich.

                Das nicht, aber Anwender vor Gefahren von dritter Seite. Wenn jemand ein Plugin oder anderweitig Code in dein System bringen kann, kann er sicher noch ganz andere Dinge als nur $_FILES zu manipulieren. Aber ist das ein Grund auf die Prüfung innerhalb von muf() zu verzichten (wenn das Dateiüberschreiben kein Thema oder mit CKs Patch gelöst ist)? Welcher Vorteil bleibt dir denn noch nach CKs Verbesserungs-Patch?

                Lo!

                1. Hello,

                  Und den Programmierer vor sich selber schützen kann man sowieso nicht wirklich.

                  Das nicht, aber Anwender vor Gefahren von dritter Seite. Wenn jemand ein Plugin oder anderweitig Code in dein System bringen kann, kann er sicher noch ganz andere Dinge als nur $_FILES zu manipulieren. Aber ist das ein Grund auf die Prüfung innerhalb von muf() zu verzichten (wenn das Dateiüberschreiben kein Thema oder mit CKs Patch gelöst ist)? Welcher Vorteil bleibt dir denn noch nach CKs Verbesserungs-Patch?

                  Die Frage lautete anders herum: welchen Vorteil hat move_uploaded_file() jetzt und welchen eventuell später? Wer bestimmt wie, dass der "Plug-In-Schreiber" nur move_uploaded_file() benutzt und nicht die generische Variante oder file_put_contents() ?

                  Da sehe ich nicht wirklich eine Chance, diesen "Plug-In-Berechtigten" wirklich auf Abstand zu halten. Der darf dann sowieso alles, was die Scriptinstanz darf. Oder habe ich jetzt was falsch verstanden?

                  Und wenn der in irgendein Verzeichnis eine Datei legen will, dann tut der das eben mit fopen() & Co. oder file_put_contents() oder sonstwie...

                  Liebe Grüße aus dem schönen Oberharz

                  Tom vom Berg

                  --
                   ☻_
                  /▌
                  / \ Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
                  1. Hi!

                    Welcher Vorteil bleibt dir denn noch nach CKs Verbesserungs-Patch?
                    Die Frage lautete anders herum: welchen Vorteil hat move_uploaded_file() jetzt und welchen eventuell später?

                    Sie hat jetzt und später den Vorteil, dass sie ein Einzeiler ist. Sie hat später eventuell den Vorteil, dass das Überschreibproblem mit einem Einzeiler und ohne weitere Verrenkungen gelöst wird. Sie hat jetzt und später den Vorteil, dass sie den offiziellen Weg darstellt, hochgeladenen Dateien zu verschieben. Damit wird sie auch eher supportet werden als der selbst geschriebene Code. Und dann bleibt immer noch das Sicherstellen, dass die Quelle eine hochgeladene Datei ist.

                    Es ist vielleicht wie addslashes vs. mysql_real_escape_string(). Welchen Vorteil bietet mres() gegenüber as()? Sicherheitstechnisch gesehen keinen, denn alle wirklich notwendigen Zeichen maskiert auch as(). Der von mres() behandelte Rest ist Kosmetik. (Strictly speaking, MySQL requires only that backslash and the quote character used to quote the string in the query be escaped. mysql_real_escape_string() quotes the other characters to make them easier to read in log files. (Die PHP-Funktion greift auf die hier verlinkte MySQL-API-Funktion zu, weswegen die Dokumentation letzterer auch unter PHP relevant ist.)) Und trotzdem sehe ich dich nicht vehement mres() für obosolet erklären. Schon dass mres() der offiziell supportete Weg ist, ist ein nicht zu unterschätzender Vorteil. (Dass mres() im Gegensatz zu as() auch Kodierungen beachten kann ist nur für einige proprietäre asiatische Kodierungen relevant, also "für uns" vernachlässigbar.)

                    Wer bestimmt wie, dass der "Plug-In-Schreiber" nur move_uploaded_file() benutzt und nicht die generische Variante oder file_put_contents() ?

                    Wir gingen bisher davon aus, dass der Plugin-Schreiber der böse ist und dem Rest des Programmes durch eine Datenänderung was unterschieben will. Aber ...

                    Da sehe ich nicht wirklich eine Chance, diesen "Plug-In-Berechtigten" wirklich auf Abstand zu halten. Der darf dann sowieso alles, was die Scriptinstanz darf. Oder habe ich jetzt was falsch verstanden?

                    Nein, das ist soweit richtig. Vermutlich spielt es keine Rolle, dass muf() eine Prüfung mehr drin hat, wenn der Angreifer nahezu beliebigen Code einschleusen und ausführen lassen kann. Doch die anderen Vorteile bleiben. Außerdem wissen wir nicht, welche Verkettung von Umständen in einem real existierenden Fall vorhanden sind und genutzt werden können und ob der Bösewicht nicht anders kann als $_FILES zu manipulieren.

                    Lo!

                    1. Hello,

                      Wer bestimmt wie, dass der "Plug-In-Schreiber" nur move_uploaded_file() benutzt und nicht die generische Variante oder file_put_contents() ?

                      Wir gingen bisher davon aus, dass der Plugin-Schreiber der böse ist und dem Rest des Programmes durch eine Datenänderung was unterschieben will. Aber ...

                      Da sehe ich nicht wirklich eine Chance, diesen "Plug-In-Berechtigten" wirklich auf Abstand zu halten. Der darf dann sowieso alles, was die Scriptinstanz darf. Oder habe ich jetzt was falsch verstanden?

                      Nein, das ist soweit richtig. Vermutlich spielt es keine Rolle, dass muf() eine Prüfung mehr drin hat, wenn der Angreifer nahezu beliebigen Code einschleusen und ausführen lassen kann. Doch die anderen Vorteile bleiben. Außerdem wissen wir nicht, welche Verkettung von Umständen in einem real existierenden Fall vorhanden sind und genutzt werden können und ob der Bösewicht nicht anders kann als $_FILES zu manipulieren.

                      Ich habe heute wärhrend meiner Schicht nochmal darüber nachgedacht (06:00 bis 21:00 nahzu nonstop...). Da konnte ich nichts privates ausprobieren, aber Dank langweiliger Phasen war neben viel zuviel Kaffee immer wieder der Gedanke da, dass wir vielleicht Alle was übersehen in diesem Thread.

                      Vielleicht ist die anfängliche Intention der PHP-Entwickler zusammen mit diesem ziemlich flammenden Thread sogar eine erste Anregung, tatsächlich mal Filialcode zu ermöglichen in PHP. Das wäre dann ein echtes Killerargument FÜR php.

                      neben einem Require/Requeire_Once() und einem Include/Include_Once() gibt es dann vielleicht mal ein Include_Filial() und ein Require_Filial(), dass über einen zusätzlichen Parameter (Array) verfügt, der die auszuschaltenden Funktionen, Klassen und Methoden enthält.

                      Dann hätten wir PHP 7.x schon auf dem Zettel :-))

                      DANN würde mMn auch eine gekapselte Funktion move_uploaded_file() in der conncurrent Version einen Sinn ergeben. Is_uploaded_file() wäre aber auch dann mMn immer noch relativ sinnlos, es sei denn, man würde eine Methode eines Objektes Fileupload-Class daraus machen, die im Objekt einen Merker und (optional) eine Sperre hinterlässt für das abgefragte Dateiobjekt.

                      Aber von OOP verstehe ich ja nichts :-P

                      Liebe Grüße aus dem schönen Oberharz

                      Tom vom Berg

                      --
                       ☻_
                      /▌
                      / \ Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
                      1. Hi!

                        Vielleicht ist die anfängliche Intention der PHP-Entwickler zusammen mit diesem ziemlich flammenden Thread sogar eine erste Anregung, tatsächlich mal Filialcode zu ermöglichen in PHP. Das wäre dann ein echtes Killerargument FÜR php.

                        neben einem Require/Requeire_Once() und einem Include/Include_Once() gibt es dann vielleicht mal ein Include_Filial() und ein Require_Filial(), dass über einen zusätzlichen Parameter (Array) verfügt, der die auszuschaltenden Funktionen, Klassen und Methoden enthält.

                        Stell dir das mal nicht so einfach vor. Die Idee könnte klappen, wenn es sich bei dem zu inkludierenden Code um sofort auszuführenden handelt. Allerdings braucht man dann eine Art Sandbox. Wenn allerdings Klassen- und Funktionsdefinitionen drin sind, die erst einmal nur gelesen werden, dann müsste sich zu diesen Klassen/Funktionen gemerkt werden, welche Klassen/Funktionen sie zur Laufzeit nicht ausführen dürfen. Und das müsste dann durchgereicht werden an alle Klassen/Funktionen, die von diesen Klassen/Funktionen aufgerufen werden. Das heißt, dass bei jedem Funktionsaufruf zumindest einmal geprüft werden muss, ob man normal arbeiten kann oder im Sperrmodus ist (und dann die Liste der gesperrten Klassen/Funktionen durchgeht). Und damit wird PHP generell langsamer, selbst wenn man das Feature nicht nutzt.

                        Lo!

                        1. Hello,

                          neben einem Require/Requeire_Once() und einem Include/Include_Once() gibt es dann vielleicht mal ein Include_Filial() und ein Require_Filial(), dass über einen zusätzlichen Parameter (Array) verfügt, der die auszuschaltenden Funktionen, Klassen und Methoden enthält.

                          Stell dir das mal nicht so einfach vor. Die Idee könnte klappen, wenn es sich bei dem zu inkludierenden Code um sofort auszuführenden handelt. Allerdings braucht man dann eine Art Sandbox. Wenn allerdings Klassen- und Funktionsdefinitionen drin sind, die erst einmal nur gelesen werden, dann müsste sich zu diesen Klassen/Funktionen gemerkt werden, welche Klassen/Funktionen sie zur Laufzeit nicht ausführen dürfen. Und das müsste dann durchgereicht werden an alle Klassen/Funktionen, die von diesen Klassen/Funktionen aufgerufen werden. Das heißt, dass bei jedem Funktionsaufruf zumindest einmal geprüft werden muss, ob man normal arbeiten kann oder im Sperrmodus ist (und dann die Liste der gesperrten Klassen/Funktionen durchgeht). Und damit wird PHP generell langsamer, selbst wenn man das Feature nicht nutzt.

                          Das ist mir schon klar. Aber diese Idee hatte ich ca. 1993 schon mal, als ich noch umfangreiche dBase-Programme erstellt habe für die Variantenkalkulation. Die ist keinesfalls trivial, weil da die diversen Parameter-Ranges und auch die Produktions-Regeln wechselseitig voneinander abhängig sein können.

                          dBase ermöglichte es, den auszuführenden Code aus der Datenbank zu holen. Das tut PHP ja auch (->eval()). Diese Fähigkeit findet man meistens bei Interpreter-Sprachen.

                          Das Konzept ist solange gefährlich, wie die aufrufende Instanz nicht wirklich die kontrollierende ist. In einer Interprreter-Sprache ist dies ja meistens das übergeordnete Runtime-Modul.

                          Bei Compiler-Sprachen hat man aber noch schlimmere Probleme. Einem JIT-Compiler alternativ diverse Kombinationen des Prozessor-Codes zu verbieten, ist fast unmöglich. Da hat man eine Ebene höher bei den Interpreter-Sprachen schon bessere Chancen. Denn da kann man einfach die (fertigen) Funktionen verbieten...

                          Ich denke aber, dass man bei PHP in der prozeduralen Ebene schon relativ leicht eine solche hierarchische Kontrolle einführen könnte.

                          OOP in einer Interpretersprache (ausgenommen die intern benutzte) halte ich ja sowieso für fragwürdig - aber das wisst Ihr ja schon alle :-)

                          Liebe Grüße aus dem schönen Oberharz

                          Tom vom Berg

                          --
                           ☻_
                          /▌
                          / \ Nur selber lernen macht schlau
                          http://bergpost.annerschbarrich.de
                          1. Hi!

                            Das Konzept ist solange gefährlich, wie die aufrufende Instanz nicht wirklich die kontrollierende ist. In einer Interprreter-Sprache ist dies ja meistens das übergeordnete Runtime-Modul.

                            Das Runtime-Modul bekommt seine Informationen von einem Script. Und das will sich wiederum anderen Code unterordnen. Die Herausforderung dabei ist, dass die Ausführung des dem Script untergeordneten Codes in Form von Funktionsaufrufen zu jeder beliebigen Zeit erfolgen kann und nicht nur im Rahmen von eval() oder eines (besonderen) include.

                            Ich denke aber, dass man bei PHP in der prozeduralen Ebene schon relativ leicht eine solche hierarchische Kontrolle einführen könnte.

                            Das denke ich nicht, und das hab ich im vorigen Posting schon dargelegt. Du kannst nicht einfach nur eval() oder dein spezielles include absichern wollen. Du müsstest jeden Funktionsaufruf kontrollieren, ob die aufgerufene Funktion aus dem inkludierten Code kommt oder von einer solchen aufgerufen wurde. Neben einem bei jedem Funktionsstart könnte ich mir nur noch vorstellen, den Code in eine Sandbox zu inkludieren und bei der Ausführung entweder in der Sandbox zu sein (auch für alle weiteren Aufrufe von Funktionen, die außerhalb der Sandbox definiert sind aber aus Sandbox-Code aufgerufen werden). Dann hätte man jedoch zwei unterschiedliche Scopes und auch zu entscheiden, welche globale und vor allem superglobale Variablen man der Sandbox zur Verfügung stellt. Wobei - das Problem mit den Variablen hat man auch in der Variante, dass jeder Funktionsaufruf selbst testet.

                            Das ist jedenfalls ein Haufen Aufwand, und ich bin mir nicht sicher, dass der Aufwand den zu erwartenden Nutzen rechtfertigt. Mit wesentlich weniger Aufwand könnte man das vielleicht sogar heute schon ein vielleicht gleichwertiges Ergebnis erzielen, indem man seine sämtlichen Variablen nicht global rumliegen lässt und die superglobalen einmalig am Scriptanfang ausliest und dann nie wieder darauf zugreift (höchstens auf $_SESSION am Ende schreibend). Dann kann da auch jede drinrumschreiben, ohne dass es den Rest des Programms stört. Allerdings hat die Sache auch wieder einen Haken, denn man will den Plugins ja sicher auch Daten übergeben und von ihnen in Empfang nehmen und macht sich damit gezwungenermaßen Löcher in die Isolierung.

                            OOP in einer Interpretersprache (ausgenommen die intern benutzte) halte ich ja sowieso für fragwürdig - aber das wisst Ihr ja schon alle :-)

                            Du kannst aufhören, das Stichwort OOP ins Spiel bringen zu wollen. Die OOP hat für dein Szenario keinerlei Extrastellung und muss sich in das dafür zu entwerfende Konzept einfügen.

                            Lo!

                            1. Hi!

                              Dann hätte man jedoch zwei unterschiedliche Scopes und auch zu entscheiden, welche globale und vor allem superglobale Variablen man der Sandbox zur Verfügung stellt. Wobei - das Problem mit den Variablen hat man auch in der Variante, dass jeder Funktionsaufruf selbst testet.

                              Und wenn wir schon die Variablen betrachten, so muss man nicht nur für die sichtbaren eine Lösung finden, sondern auch die unsichtbaren nicht aus dem Auge verlieren. Beispielsweise nehmen sich einige mysql_*()-Funktionen, wenn man ihnen keine Verbindungskennung mitgibt, die erstbeste, die bereits geöffnet ist. Und darüber kann Sandbox-Code, ohne dass es die Zugangsdaten über die sichtbaren Variablen in Erfahrung bringen muss, auf den Datenbestand zugreifen. Das ist also noch eine weitere Baustelle, die (meiner Ansicht nach) recht tief in den PHP-Code eingreift. Ich denke nicht, dass das je mehr als ein Gedankenexperiment wird.

                              Lo!

                              1. Hello Dedlfix,

                                das war ja jetzt auch nicht das Hauptanliegen.

                                Aber die Idee fand ich schon überlegenswert. Ich werde mir bei Gelgenheit mal ansehen, wie "disable_functions" umgesetzt wird. Vielleicht verstehe ich das dann auch irgenwann :-O

                                Liebe Grüße aus dem schönen Oberharz

                                Tom vom Berg

                                --
                                 ☻_
                                /▌
                                / \ Nur selber lernen macht schlau
                                http://bergpost.annerschbarrich.de
                          2. OOP in einer Interpretersprache (ausgenommen die intern benutzte) halte ich ja sowieso für fragwürdig - aber das wisst Ihr ja schon alle :-)

                            Dass Du es für fragwürdig hältst, betonst Du tatsächlich deutlich und regelmäßig. Nur fachlich untermauert hast Du es noch nie. Obwohl drei Jahre ein angemessen langer Zeitraum sein sollte.

        3. Die Funktion bietet gegenüber einer generischen Lösung keinen echten Vorteil, sondern auf jeden Fall diesen beschriebenen Nachteil mit dem Überschreiben.

          Kleiner Nachtrag: Der Vorteil ist, dass der Code eine Zeile hat, anstatt ca. 20 Zeilen bei einer eigenen Funktion. Somit steigt die Gefahr, dass derProgrammierer eine Sicherheitslücke einprogrammiert, um den Faktor 20. Da beim Einzeiler praktisch  kein Fehler möglich ist, steigt ie Fehlerquote sogar ins unendliche.

          Und selbst wenn ich das Überschreiben verhindern will, wird es mit muf() nur ein Zweizeiler, denn ein file_exists ist doch ein klein wenig weniger Code als die Lösung von dir,die im Übrigen das gleiche Problem bietet, was du anprangerst, da in der Zeit zwischen fopen und flock die Datei von einem anderen Script manipuliert, gelöscht, verschoben, geändert oder sonst was werden kann.

          Somit löst dein Ansatz in keinster Weise dein Problem (was IMO keins ist) sondern vergrössert lediglich den Ressourcenverbrauch und die Codelänge, dafür verlängert sich auch die Verarbeitungsgeschwindigkeit.

          Somit hat deine Lösung als _keine_ Vorteile aber _sehr viele gravierende_ Nachteile.

          Für mich heisst das, ich bleibe bei meiner Funktion, denn bevor ich nach deinem Plan das Rad neu erfinde und hab dann hinterher ein Ei an der Achse, nutze ich lieber das Rad vom PHP-Hersteller, das nachweislich einen sauberen Geradeauslauf hat.

  2. Hi!

    Ich lade ein Bild hoch, bevor ich es abspeichere überprüfe ich ob es sich um ein jpg handelt.

    Die Prüfungen mit der Fileinfo-Extension und getimagesize() können nur einige herausragende Merkmale des jeweiligen Formats prüfen. Sie können nicht leisten, dir zu versichern, dass ansonsten auch alles in Ordnung mit der Datei ist. Keine der beiden Methoden liest meines Wissens eine Datei vollständig und prüft auf Plausibilität des Inhalts oder auf schädlichen Inhalt. (Da arbeiten Virenscanner deutlich gründlicher.) Fileinfo ist auf die Erkennung vieler Formate ausgelegt und prüft manchmal nur den Dateianfang auf eine bestimmte signifikante Bytefolge. getimagesize() macht sicher so etwas ähnliches, um das Grafikformat zu ermitteln. Für die Größeninformation muss die Funktion nur auf einen bestimmten Datenblock zugreifen. Der Inhalt der restlichen Blöcke ist ihr egal. Dort drin könnte unter Umständen auch PHP-Code versteckt sein.

    Muss ich sonst noch etwas beachten um WIRKLICH nur JPGs zu bekommen?

    Jedenfalls kannst du nicht mit einfachen Mitteln ausschließen, dass eine auf den ersten Blick richtige JPEG-Datei nicht noch irgendwelchen unerwünschten Inhalt hat. Weitere Manipulationen, wenn die Datei erstmal auf dem Server liegt, sind auch nicht mit absoluter Gewissheit ausschließbar. Du kannst aber wenigstens noch ein paar Maßnahmen ergreifen, die es schwieriger machen, einen schädlichen Inhalt zur Wirkung kommen zu lassen. Die Datei sollte wenn möglich nicht in einem Verzeichnis abgelegt werden, in dem der Webserver ausführbaren Inhalt erkennt. Im einfachen Fall sorgt man dafür, dass keine Dateiendung geschrieben werden kann, die den Apachen zum Anwerfen von PHP veranlasst. Das Ausschalten des PHP-Handlers für alle Dateien des Verzeichnisses wäre eine weitere Möglichkeit. Außerhalb des DocumentRoot ablegen geht nur, wenn die Datei nicht direkt ausgeliefert werden soll. Zumindest ist das temporär keine schlechte Idee, wenn du alle hochgeladenen Dateien erstmal einem Virentest oder anderen geeigneten Prüfungen unterziehst, bevor die Allgemeinheit darauf zugreifen darf.

    Vielleicht ist das alles nicht wichtig für dein Vorhaben, aber wenn du "Sicherheit" im Topic erwähnst und nicht genau spezifizierst, was das in deinem Fall bedeutet, dann kann man sich auch recht schnell in irrelevanten Details verlieren.

    if((isset($_POST['submit']))&&(!empty($_FILES['bild']['tmp_name'])))

    $_POST['submit'] muss nicht unbedingt existieren. Formulare können auch mit Enter statt Mausklick auf dem Submit-Button abgesendet werden. Die HTML(4.01)-Spezifikation schreibt nicht vor, dass in dem Fall irgendein unbeteiligter Submit-Button sein name-value-Pärchen mit in den Versand geben muss. Und somit tun das auch nicht alle Browser.

    Es reicht an dieser Stelle, wenn du prüfst, dass $_FILES['bild']['error'] existiert und den Wert UPLOAD_ERR_OK hat.

    $picture_info = getimagesize ($_FILES['bild']['tmp_name']);
    if ($picture_info[2]==2) // nur JPG

    Hier würde ich die IMAGETYPE_XXX-Konstanten (oder in deinem Fall die für JPEG) empfehlen. Der Zahlenwert wird sich sicherlich nicht ändern, aber aus dem Namen der Konstante geht bereits hervor, dass JPEG gemeint ist, so dass der Kommentar obsolet ist.

      echo 'Dies ist kein zulässiges Bildformat!';  
    

    Nicht nur diese Information ist interessant für den Anwender, sondern auch, was er im Fall eines Fehlers besser machen kann, also welches die zulässigen Formate sind.

    Lo!

    1. Formulare können auch mit Enter statt Mausklick auf dem Submit-Button abgesendet werden. Die HTML(4.01)-Spezifikation schreibt nicht vor, dass in dem Fall irgendein unbeteiligter Submit-Button sein name-value-Pärchen mit in den Versand geben muss. Und somit tun das auch nicht alle Browser.

      HTML5 schreibt das übrigens vor.
      Alle großen Browser zeigen dieses Verhalten in den aktuellen Versionen (IE 8 z.B. noch nicht).

      Mathias

  3. Ich lade ein Bild hoch, bevor ich es abspeichere überprüfe ich ob es sich um ein jpg handelt.

    Fällt mir jetzt spontan ein:

    Du nimmst die Datei, die hochgeladen wurde, erzeugst per GD-Lib ein neues JPG und kopierst die hochgeladenen Datei per copyimageresampled() in das neue Bild.

    Wenn das hochgeladene Bild kein Bild war, dürfte es ne Fehlermeldung geben (nicht getestet, nur eine Idee). Wenn das Bild selbst aber nen Virus o.ä. enthält, wird das vermutlich auch nicht helfen. Da wirst du serverseitig wohl nochmal per externen Programm auf Viren etc.prüfen müssen.

    Inwieweit es sicher ist, wenn du den Dateianfang prüfst, weiss ich nicht.

    Sollten diese Vorschläge schonmal im Thread erwähnt worden sein, einfach ignorieren. Beim "neuen" Thema im Thread ist das dann wohl irgendwie untergegangen :D