Jochen: Zeilenumbruch in mysql-DB eintragen

0 72

Zeilenumbruch in mysql-DB eintragen

Jochen
  • mysql
  • php
  1. 0
    Raketenwilli
    1. 0
      Jochen
      1. 0
        Raketenwilli
        1. 0
          Jochen
          1. 0
            Raketenwilli
            1. 0
              Jochen
              1. 0
                Raketenwilli
          2. 0
            encoder
            1. 0
              Der Martin
        2. 0
          Jochen
  2. 0
    Rolf B
    1. 0
      Jochen
  3. 0
    Mitleser 2.0
    1. 0
      Rolf B
      1. 0
        Sven
        1. 0
          TS
          • java
          • php
          • sql
          1. 0
            Jochen
            1. 0
              TS
              • php
              • sicherheit
              1. 0
                Jochen
                1. 0
                  TS
                  1. 0
                    Jochen
                    1. 0
                      TS
                      1. 0
                        Rolf B
                2. 0
                  Rolf B
                  1. 0
                    TS
                    • apache
                    • php
                    • sicherheit
                    1. -2
                      Mitleser 2.0
                      1. 1
                        Robert
                        1. -2
                          Mitleser 2.0
                          1. 0
                            Raketenwilli
                            1. -2
                              Mitleser 2.0
                              1. 0
                                Raketenwilli
                                1. -2
                                  Mitleser 2.0
                                  1. 1
                                    Raketenwilli
                                    1. -3
                                      Mitleser 2.0
                                      1. 1
                                        Raketenwilli
                                        1. 0
                                          Rolf B
                                          1. 0
                                            Raketenwilli
                                            1. 0
                                              Rolf B
                                              1. 1

                                                Youtube nicht vergessen. (ChatGPT lernt dort ...)

                                                Raketenwilli
                                          2. 0
                                            Mitleser 2.0
                                            1. 0

                                              Bash || Bashing

                                              Raketenwilli
                                              1. 0
                                                Rolf B
                                                1. 0
                                                  TS
                                                2. 0
                                                  Der Martin
                                                3. 0
                                                  Raketenwilli
                                                4. 0
                                                  TS
                                                  1. 0
                                                    Rolf B
                                                    1. 0

                                                      Unix/Linux UMASK

                                                      TS
                                                      • bash-script
                                                      • sicherheit
                                                      • unix
                                                      1. 2
                                                        Raketenwilli
                                                        1. 0
                                                          TS
                                                          1. 0
                                                            Raketenwilli
                                        2. 0
                                          Mitleser 2.0
                                          1. 0
                                            TS
                                            1. 0
                                              Mitleser 2.0
                                              1. -1
                                                Mitleser 2.0
                                                1. 0
                                                  Raketenwilli
                                              2. 1
                                                Rolf B
                                                1. 0
                                                  TS
                                                2. 0
                                                  Mitleser 2.0
                              2. 1
                                Robert
                                1. -2
                                  Mitleser 2.0
                3. 2
                  Robert B.
                  1. 0
                    TS
                    • php
                    • sicherheit
                    • zu diesem forum
                  2. 0
                    TS
            2. 2
              Rolf B
              1. 0
                TS
                • dokumentation
                • projekt
                • sicherheit
              2. 0
                Auge
                1. 0
                  TS
                  • datenbank
                  • mariadb
                  • mysql
                  1. 0

                    Warum fragen und spekulieren?

                    Raketenwilli
                    1. 1
                      Rolf B
                      1. 0
                        TS
                        • menschelei

Guten Tag,

ich habe eine Androis-App programmiert.
Damit schaufle ich ein paar daten auf meinen Server. Leider gelingt es mir bisher nur, 1 Zeile zum Upload zu senden.
Das ist nicht wirklich schlimm, also packe ich alles in eine Zeile hinein und splitte dann serverseitig wieder auf.

Array
(
    [0] => Zeile 1 |x| Zeile 2 |x| Zeile 3 |x| und hier noch eine überlange. Zeile, die aber keinen manuellen Zeilenbruch hat
...
)

Die manuellen Zeilenumbrüch aus der App habe ich in |x| gewandelt.

Wie genau muss ich sie jetzt wieder in php in Zeilenumbrüche zurück wandeln, damit ich sie in eine mysql-DB eintragen kann?

$newStr = str_replace("|x|", "\n", $myarray[0]);

fühlt sich irgendwie nicht korrekt an, ich kann aber gar nicht erklären, warum nicht.

Jochen

  1. Die manuellen Zeilenumbrüch aus der App habe ich in |x| gewandelt.

    Keine gute Idee. Warum und zu welchem wirklich besonderen Behufe hast Du das getan?

    $newStr = str_replace("|x|", "\n", $myarray[0]);
    

    fühlt sich irgendwie nicht korrekt an, ich kann aber gar nicht erklären, warum nicht.

    Wenn das ganze Verfahren korrekt wäre, dann wäre das durchaus richtig. Die Syntax jedenfalls stimmt.

    Kasus knacktus ist die fett markierte Frage.

    1. Die manuellen Zeilenumbrüch aus der App habe ich in |x| gewandelt.

      Keine gute Idee. Warum und zu welchem wirklich besonderen Behufe hast Du das getan?

      Es ist mir nicht gelungen, den Zeilenumbruch von Java (Android) bis php zu transportieren. In Java wird er noch erkannt, aber beim Transport geht er verloren. Sicherlich hätte ich den zeilenumbruch auch über \n gleich mitnehmen können, aber da ist mir das Maskieren nicht gelungen. Und als mir das maskieren gelang, war der Zeilenumbruch wieder futsch. Daher meine Notlösung |x|.

      $newStr = str_replace("|x|", "\n", $myarray[0]);
      

      fühlt sich irgendwie nicht korrekt an, ich kann aber gar nicht erklären, warum nicht.

      Wenn das ganze Verfahren korrekt wäre, dann wäre das durchaus richtig. Die Syntax jedenfalls stimmt.

      Hast recht, funktioniert einwandfrei.

      Jochen

      1. Es ist mir nicht gelungen, den Zeilenumbruch von Java (Android) bis php zu transportieren.

        Beide Sprachen und die Transportprotokolle sollten das aber hergeben. Zeig doch mal Deine Bemühungen und die Resultate.

        1. Es ist mir nicht gelungen, den Zeilenumbruch von Java (Android) bis php zu transportieren.

          Beide Sprachen und die Transportprotokolle sollten das aber hergeben. Zeig doch mal Deine Bemühungen und die Resultate.

          Habe ich nicht mehr.
          Und da sie App nur für mich ist und jetzt genau so läuft wie gewünscht, lasse ich es einfach mit der "Notlösung".

          1. Habe ich nicht mehr. Und da sie App nur für mich ist und jetzt genau so läuft wie gewünscht, lasse ich es einfach mit der "Notlösung".

            Schade. Hätte womöglich andere oder Dich selbst bezüglich anderer Projekte interessiert.

            1. Habe ich nicht mehr. Und da sie App nur für mich ist und jetzt genau so läuft wie gewünscht, lasse ich es einfach mit der "Notlösung".

              Schade. Hätte womöglich andere oder Dich selbst bezüglich anderer Projekte interessiert.

              Ja, verstehe.
              Bin nur gerade unter Zeitdruck, vielleicht stelle ich es irgendwann demnächst mal als open source in GITHUB ein.
              Dann komme ich auf diesen Thread zurück, ok?

              1. Habe ich nicht mehr. Und da sie App nur für mich ist und jetzt genau so läuft wie gewünscht, lasse ich es einfach mit der "Notlösung".

                Schade. Hätte womöglich andere oder Dich selbst bezüglich anderer Projekte interessiert.

                Ja, verstehe.
                Bin nur gerade unter Zeitdruck, vielleicht stelle ich es irgendwann demnächst mal als open source in GITHUB ein.
                Dann komme ich auf diesen Thread zurück, ok?

                Alles gut.

          2. Notlösung heißt vermutlich so, weil irgendwann aus einer Lösung pure Not wird 😀

            1. Hallo,

              Notlösung heißt vermutlich so, weil irgendwann aus einer Lösung pure Not wird 😀

              nein, der erste Teil des Wortes ist aus dem Englischen.

              Einen schönen Tag noch
               Martin

              --
              Im Englischen hat eine Katze neun Leben. Im Deutschen vielleicht auch, aber nach Abzug der Steuern bleiben nur noch sieben übrig.
        2. Es ist mir nicht gelungen, den Zeilenumbruch von Java (Android) bis php zu transportieren.

          Beide Sprachen und die Transportprotokolle sollten das aber hergeben. Zeig doch mal Deine Bemühungen und die Resultate.

          Stimmt. 😉

  2. Hallo Jochen,

    oder anders gefragt: Warum implantierst Du ein |x| und nicht gleich ein \n ?

    Ich habe eine Androis-App programmiert.

    Ich unterstelle mal, dass das ein Typo war. Ich habe keine Ahnung von Andoid-Programmierung und weiß deshalb nicht, ob es dort ein multiline input gibt oder nicht. Wenn nicht: Hilft Dir sowas hier vielleicht weiter?

    Und die Alternative einer HTML Seite, die man fullscreen laufen lässt, gibt's immer. Mit Service Worker auch offline (wieder mal eine offene Baustelle im Wiki 😢)…

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      oder anders gefragt: Warum implantierst Du ein |x| und nicht gleich ein \n ?

      Hat Willi auch gefragt und ich habe es dort schon beantwortet.

      Ich habe eine Androis-App programmiert.

      Ich unterstelle mal, dass das ein Typo war. Ich habe keine Ahnung von Andoid-Programmierung und weiß deshalb nicht, ob es dort ein multiline input gibt oder nicht. Wenn nicht: Hilft Dir sowas hier vielleicht weiter?

      Ach sicher gibt es das in Android, aber ich bin selber noch Anfänger und so weit bin ich noch nicht, benötige aber die App schon ganz dringend.
      Aber der Text, den ich eingebe, läuft schon über eine Textarea, das ist nicht das Problem.

      Und die Alternative einer HTML Seite, die man fullscreen laufen lässt, gibt's immer. Mit Service Worker auch offline (wieder mal eine offene Baustelle im Wiki 😢)…

      Ich glaube, hier wäre eine HTML-Seite überfordert.

      • Appstart
      • Frage, ob Kamera oder Photogalerie gestartet werden soll
      • Photo aufnehmen
      • Das wird dann in einer Vorschau angezeigt
      • Dazu ein Formular, in das ich eintragen kann
      • Preis
      • Mwst
      • Gegenkonto
      • Datum (per Kalenderpopup)
      • Beschreibung
      • Rechnungsnummer
      • u.a. falls nötig
      • bei Bedarf um Geodaten oder sonstiges erweiterbar (kein Problem mit Datenschutz, da die App nur für mich selber ist und nicht verbreitet wird)

      Das wird auf meinen Server in meine Buchhaltung hoch geladen, ich erhalte eine ID als Rückmeldung, die ich auf die Quittung notiere. Später im Büro kann ich dann alle Quittungen abheften, aber die Buchführung hat sie schon inne, mitsamt einer Kopie als Photo und der ZuordnungsID zum Original.

      Ich wüßte jetzt z.b. die Kamera über HTML nicht zu steuern.
      Müsste dann also ein Photo machen und über Formularupload gehen, aber da ist die native App schon bequemer.

      Jochen

  3. Du hast ja plausibel dargelegt, dass Du "aus Gründen" hier einen Quirks anwenden musst / willst. Sowas kommt vor. Nur würde ich spontan bei sonen Geschichten eher auf standardisierte Sachen wie meinetwegen Base64 zurückgreifen, bevor man mit Regexen was Eigenes bastelt. Das rächt sich später nur allzuoft…

    1. Hallo Mitleser 2.0,

      nun, sicher, base64 ist der Universalhammer für diese Art von pilzbefallenen Nägeln.

      Aber, Codierung - 💡 *bling*

      Ich könnte mir vorstellen, dass das \n als \x0A im HTTP Body des POST Requests gelandet ist und damit nicht zum URL-Encoding der Formulardaten passte. Ich kenne Java nicht, und die von Sven verwendete HTTP-Library sowieso nicht, aber Probleme mit missachtetem Kontextwechsel gibt's in jeder Programmierumgebung.

      Sven - was ist mit Zeichen wie & oder = ? Machen die auch Probleme? Welche Java-Lib verwendest Du zum senden? Erzeugst Du den POST-Body für den Request an PHP selbst oder macht das die Lib für Dich?

      Wenn & oder = problematisch sind und du den Body selbst erzeugst, dann sieh zu, dass Du in Java ein Gegenstück zur JavaScript-Methode encodeURIComponent findest.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Hallo Rolf, hallo Mitleser,

        gute Anregung, meinen String nicht auf gut Glück zu versenden, auch wenn ich einigermaßen sicher bin, keine Sonderzeichen zu versenden.
        Aber was bei diesem Projekt stimmt, kann beim nächsten schon anders sein.

        Sven - was ist mit Zeichen wie & oder = ? Machen die auch Probleme? Welche Java-Lib verwendest Du zum senden? Erzeugst Du den POST-Body für den Request an PHP selbst oder macht das die Lib für Dich?

        Wenn & oder = problematisch sind und du den Body selbst erzeugst, dann sieh zu, dass Du in Java ein Gegenstück zur JavaScript-Methode encodeURIComponent findest.

        Was hältst/haltet Du/Ihr davon, JSON zu verwenden?

        Java:

        // Create a HashMap to store the key-value pairs
        Map<String, String> data = new HashMap<>();
        data.put("name", "Sven");
        data.put("age", "30");
        data.put("city", "Berlin");
        
        // Convert the HashMap to a JSON string
        String jsonString = new Gson().toJson(data);
        
        // Now send the JSON string to the PHP file
        

        PHP:

        // Get the JSON string from the request body or query parameter
        $jsonString = $_POST['jsonString'];
        
        // Decode the JSON string into an array
        $data = json_decode($jsonString, true);
        
        // Access the data by key
        $name = $data['name'];
        $age = $data['age'];
        $city = $data['city'];
        

        Fände ich strukturierte, wenns funktioniert.
        Müsste ich morgen mal ausprobieren.

        Sven (nicht wundern, ich schreibe unter beiden Accounts, Jochen/Sven und habe mich vertan)

        1. Hello,

          gute Anregung, meinen String nicht auf gut Glück zu versenden, auch wenn ich einigermaßen sicher bin, keine Sonderzeichen zu versenden.
          Aber was bei diesem Projekt stimmt, kann beim nächsten schon anders sein.

          Sven - was ist mit Zeichen wie & oder = ? Machen die auch Probleme? Welche Java-Lib verwendest Du zum senden? Erzeugst Du den POST-Body für den Request an PHP selbst oder macht das die Lib für Dich?

          Wenn & oder = problematisch sind und du den Body selbst erzeugst, dann sieh zu, dass Du in Java ein Gegenstück zur JavaScript-Methode encodeURIComponent findest.

          Was hältst/haltet Du/Ihr davon, JSON zu verwenden?

          Java:

          // Create a HashMap to store the key-value pairs
          Map<String, String> data = new HashMap<>();
          data.put("name", "Sven");
          data.put("age", "30");
          data.put("city", "Berlin");
          
          // Convert the HashMap to a JSON string
          String jsonString = new Gson().toJson(data);
          
          // Now send the JSON string to the PHP file
          

          Wird dieser JSON-String passend zum Transfer encoded?

          PHP:

          // Get the JSON string from the request body or query parameter
          $jsonString = $_POST['jsonString'];
          
          // Decode the JSON string into an array
          $data = json_decode($jsonString, true);
          
          // Access the data by key
          $name = $data['name'];
          $age = $data['age'];
          $city = $data['city'];
          
          // Check, if a JSON string has been posted
          
          if (isset($_POST['jsonString']))
          {  
            // Decode the JSON string into an array
            $data = json_decode($_POST['jsonString'], true);
            
            ## hier exception einbauen:  
            if(false === $data) 
            {
              exit('error');  
            }
            else if(isset($data['name'], $data['age'], $data['city']))  
            { 
              // Continue with $data array elements
               
              ## bitte nicht umkopieren, sondern mit den Array-Elementen
              ## in Sdata weiterarbeiten!
          
            }
          } 
          
          

          Und warum nicht sofort ein passend codiertes Array an PHP posten?

          Siehe auch Link-1 und Link- 2

          Und für die Eintragung per SQL in eine Datenbank muss dann wieder das passende Escaping pro Element beachtet werden. Dann sollte es auch mit den Steuerzeichen, Anführungsstrichen, Backslashes, usw. klappen oder man benutzt gleich ein blockpuffer-orientierte Methode dafür, wie PDO (also nicht die Textschnittstelle!).

          Glück Auf
          Tom vom Berg

          --
          Es gibt soviel Sonne, nutzen wir sie.
          www.Solar-Harz.de
          S☼nnige Grüße aus dem Oberharz
          1. Nu aber, so läuft es und zwar mit Sonderzeichen und ohne Zeilenumbrüche in |x| um,zuwandeln und später wieder herzustellen.

            Java:

            // Create a HashMap to store the key-value pairs
                        Map<String, String> data = new HashMap<>();
                        data.put("description", myDesc);
                        data.put("preis", myPreis);
                        data.put("konto", myKonto);
                        data.put("MwSt", myMwSt);
                        data.put("datum", myDatum);
                        data.put("filename", file.getName());
            
            // Convert the HashMap to a JSON string
                        String jsonString = new Gson().toJson(data);
            
            // Convert the JSON string to a RequestBody
                        RequestBody jsonRequestBody = RequestBody.create(MediaType.parse("application/json"), jsonString.getBytes());
            
            // Now send the JSON string to the PHP file
                        RequestBody fileRequestBody = RequestBody.create(MediaType.parse("*/*"), file);
                        map.put("file\"; filename=\"" + file.getName() + "\"", fileRequestBody);
                        map.put("json", jsonRequestBody);
            

            php:

            if($_SERVER['REQUEST_METHOD'] === 'POST') {
            
                if(isset($_POST['json'])) {
                    $jsonString = $_POST['json']; // JSON-String als Text aus dem Request-Body lesen
                    $jsonData = json_decode($jsonString,true); // JSON-String in ein PHP-Array umwandeln
            
                    //  hier exception einbauen:
                    if(false === $jsonData) {
                        $success = false;
                        $message = "JSON-Error while uploading";
                        $response["success"] = $success;
                        $response["message"] = $message;
                        echo json_encode($response);
                        exit;
                    }
            
                    $myDateiname = $_FILES['file']['name'];
                    $myDateigroesse = $_FILES["file"]["size"];
            
                    $myDescription = $jsonData['description'];
                    $myDescription = utf8_decode($myDescription);
                    $myPreis = $jsonData['preis'];
                    $myKonto = $jsonData['konto'];
                    $myMwSt = $jsonData['MwSt'];
                    $myMwSt = str_replace("% MwSt","",$myMwSt);
                    $myDatum = datum2mysql($jsonData['datum'],'.');
            
                    $fp = fopen('./androidlog.txt', 'a+');
                    fwrite($fp, $_FILES['file']['name']."\r\n");
                    fwrite($fp, print_r($jsonData,true)."\r\n");
                    fclose($fp);
            
            }
            }
            

            ergibt sowas hier:

            IMAGE_20230420_083452.jpg
            Array
            (
                [datum] => 20.04.2023
                [preis] => 36.9
                [konto] => GWG
                [filename] => IMAGE_20230420_081552.jpg
                [description] => Zeile 1
            Zeile 2
            und noch eine lange Zeile die einen Zeilenumbruch innerhalb der Textarea hat und in der nächsten Zeile ein paar Sonderzeichen
            '*+&#@/)?;"
                [MwSt] => 19% MwSt
            )
            

            Jochen

            1. Hello Sven-Jochen, ;-)

              Nu aber, so läuft es und zwar mit Sonderzeichen und ohne Zeilenumbrüche in |x| um,zuwandeln und später wieder herzustellen.

              Sieht doch schon besser aus.

              Java:

              // Create a HashMap to store the key-value pairs
                          Map<String, String> data = new HashMap<>();
                          data.put("description", myDesc);
                          data.put("preis", myPreis);
                          data.put("konto", myKonto);
                          data.put("MwSt", myMwSt);
                          data.put("datum", myDatum);
                          data.put("filename", file.getName());
              
              // Convert the HashMap to a JSON string
                          String jsonString = new Gson().toJson(data);
              
              // Convert the JSON string to a RequestBody
                          RequestBody jsonRequestBody = RequestBody.create(MediaType.parse("application/json"), jsonString.getBytes());
              
              // Now send the JSON string to the PHP file
                          RequestBody fileRequestBody = RequestBody.create(MediaType.parse("*/*"), file);
                          map.put("file\"; filename=\"" + file.getName() + "\"", fileRequestBody);
                          map.put("json", jsonRequestBody);
              

              Bei PHP hätte ich auf jeden Fall noch ein paar Dinge zu bemängeln:

              • das Umkopieren
              
                 $myDescription = $jsonData['description'];
                 $myDescription = utf8_decode($myDescription);
                 $myPreis = $jsonData['preis'];
                 $myKonto = $jsonData['konto'];
                 $myMwSt = $jsonData['MwSt'];
                 $myMwSt = str_replace("% MwSt","",$myMwSt);
                 $myDatum = datum2mysql($jsonData['datum'],'.');
               
              

              Das ist unnötig und zerstört nur den Zusammenhang der Daten.

              • und die Verwertung der übermittelten Filesize.
                Filesize() muss auf jedem Fall auf dem Server geprüft werden, was der Client meldet, kann gelogen sein. Man sollte aber hier auch die handlebasierte Funktion verwenden. Die kann dann auch gleich für den MIME_Type benutzt werden.

              • Prüfung des MIME-Types der Datei
                Bitte auch auf dem Server prüfen und nicht glauben, was der Client meldet. Die Funktion mime_content_type() sollte hier helfen. [Leider hängt das Online-Manual gerade].
                Ohne diese Prüfung könnte man Dir alles auf den Server jublen und dann ist er eventuell schnell geknackt.

              • Den vom Client gemekdeten Filename darf man keinesfalls ungeprüft übernehmen. Der könnte ganze Pfade enthalten, bzw. schäfliche Filenamen (PRN, LPT, ...)

              • Das Vezeichnis für den Fileupload sollte außerhalb der Document-Root liegen und es sollten alle Scriptausführungen in diesem Verzeichnis ausgeschaltet sein! (.htaccess -> engine off).

              • User/Passwort-Prüfung konnte ich jetzt nicht entdecken. Habe ich die übersehen?

              php:

              if($_SERVER['REQUEST_METHOD'] === 'POST') {
              
                  if(isset($_POST['json'])) {
                      $jsonString = $_POST['json']; // JSON-String als Text aus dem Request-Body lesen
                      $jsonData = json_decode($jsonString,true); // JSON-String in ein PHP-Array umwandeln
              
                      //  hier exception einbauen:
                      if(false === $jsonData) {
                          $success = false;
                          $message = "JSON-Error while uploading";
                          $response["success"] = $success;
                          $response["message"] = $message;
                          echo json_encode($response);
                          exit;
                      }
              
                      $myDateiname = $_FILES['file']['name'];
                      $myDateigroesse = $_FILES["file"]["size"];
              
                      $myDescription = $jsonData['description'];
                      $myDescription = utf8_decode($myDescription);
                      $myPreis = $jsonData['preis'];
                      $myKonto = $jsonData['konto'];
                      $myMwSt = $jsonData['MwSt'];
                      $myMwSt = str_replace("% MwSt","",$myMwSt);
                      $myDatum = datum2mysql($jsonData['datum'],'.');
              
                      $fp = fopen('./androidlog.txt', 'a+');
                      fwrite($fp, $_FILES['file']['name']."\r\n");
                      fwrite($fp, print_r($jsonData,true)."\r\n");
                      fclose($fp);
              
              }
              }
              

              ergibt sowas hier:

              IMAGE_20230420_083452.jpg
              Array
              (
                  [datum] => 20.04.2023
                  [preis] => 36.9
                  [konto] => GWG
                  [filename] => IMAGE_20230420_081552.jpg
                  [description] => Zeile 1
              Zeile 2
              und noch eine lange Zeile die einen Zeilenumbruch innerhalb der Textarea hat und in der nächsten Zeile ein paar Sonderzeichen
              '*+&#@/)?;"
                  [MwSt] => 19% MwSt
              )
              

              Du hast also noch einiges zu tun, wenn Dir die Sicherheit des Servers etwas wert ist.

              Glück Auf
              Tom vom Berg

              --
              Es gibt soviel Sonne, nutzen wir sie.
              www.Solar-Harz.de
              S☼nnige Grüße aus dem Oberharz
                • und die Verwertung der übermittelten Filesize.
                  Filesize() muss auf jedem Fall auf dem Server geprüft werden, was der Client meldet, kann gelogen sein. Man sollte aber hier auch die handlebasierte Funktion verwenden. Die kann dann auch gleich für den MIME_Type benutzt werden.

                • Prüfung des MIME-Types der Datei
                  Bitte auch auf dem Server prüfen und nicht glauben, was der Client meldet. Die Funktion mime_content_type() sollte hier helfen. [Leider hängt das Online-Manual gerade].
                  Ohne diese Prüfung könnte man Dir alles auf den Server jublen und dann ist er eventuell schnell geknackt.

                • Den vom Client gemekdeten Filename darf man keinesfalls ungeprüft übernehmen. Der könnte ganze Pfade enthalten, bzw. schäfliche Filenamen (PRN, LPT, ...)

                • Das Vezeichnis für den Fileupload sollte außerhalb der Document-Root liegen und es sollten alle Scriptausführungen in diesem Verzeichnis ausgeschaltet sein! (.htaccess -> engine off).

                • User/Passwort-Prüfung konnte ich jetzt nicht entdecken. Habe ich die übersehen?

                Ein paar Dinge davon werde ich sicher noch einbauen.
                Bedenke aber auch, dass ich der einzige User dieser App bin, soll heißen, die Motivation, meinen eigenen server zu hacken ist gering und meine Möglichkeiten, dies zu tun, sind auf andere Weise deutlich größer. 😉

                • Das Vezeichnis für den Fileupload sollte außerhalb der Document-Root liegen und es sollten alle Scriptausführungen in diesem Verzeichnis ausgeschaltet sein! (.htaccess -> engine off).

                Hört sich interessant an, wie mache ich das genau?

                Jochen

                1. Hello,

                  • User/Passwort-Prüfung konnte ich jetzt nicht entdecken. Habe ich die übersehen?

                  Bedenke aber auch, dass ich der einzige User dieser App bin, soll heißen, die Motivation, meinen eigenen server zu hacken ist gering und meine Möglichkeiten, dies zu tun, sind auf andere Weise deutlich größer. 😉

                  Aber Du machst eine Senke (POST-Kanal) auf dem Server auf. Wie wird deren Verwendung geschützt?

                  • https
                  • User/Passwort

                  Glück Auf
                  Tom vom Berg

                  --
                  Es gibt soviel Sonne, nutzen wir sie.
                  www.Solar-Harz.de
                  S☼nnige Grüße aus dem Oberharz
                    • https

                    Ja.

                    • User/Passwort

                    Nein.
                    Könnte ich das so machen, dass ich im JSON ein Key-Value Paar eintrage, dessen Vorhandesein Bedingung für jegliche Weiterverarbeitung ist?

                    Jochen

                    1. Hello,

                      • https

                      Ja.

                      • User/Passwort

                      Nein.
                      Könnte ich das so machen, dass ich im JSON ein Key-Value Paar eintrage, dessen Vorhandesein Bedingung für jegliche Weiterverarbeitung ist?

                      üblicherweise ja, wenn der Traffic ausschließlich über https stattfindet. Dann befindet sich der Requestbody bereits im verschlüsselten Teil.

                      Besser ist immer noch der Weg über

                        1. Request Namen übertagen
                      • Response mit Rückfrage für Passwort
                        1. Request Passwort übertragen
                      • Response mit Token (eine Art "Session-Cookie", nicht das der eigentlichen Session!)

                      Und weitere Zugriffe dann mit diesem Zugangs-Token vornehmen.

                      Der Vorteil dafür ist, dass für die Übertragung der Credentials zwei separat verschlüsselte Requests benutzt werden (können *1) )und das Token, das ja jedes Mal mitgeschickt wird, spätestens nach Ablauf der Session ungültig wird.

                      Zusätzlich könnte man in PHP noch session_regenerate_id() einsetzen und zusätzlich zum Token einen Fingerprint des Clients nutzen.

                      Das wäre dann aber schon ziemlich paranoid ;-)

                      *1) wenn HTTPS nicht mit keep alive benutzt wird.

                      Glück Auf
                      Tom vom Berg

                      --
                      Es gibt soviel Sonne, nutzen wir sie.
                      www.Solar-Harz.de
                      S☼nnige Grüße aus dem Oberharz
                      1. Hallo TS,

                        Besser ist immer noch der Weg über...

                        Wenn ich das konkretisieren darf:

                        • 1. Request Namen übertragen
                        • Response mit Rückfrage für Passwort und einem Public Key
                        • 2. Request: Passwort mit dem gleichen Algo hashen, den der Server verwendet, dann mit dem Public Key asymmetrisch verschlüsseln und zum Server senden. Wenn ich MDN richtig verstehe, können moderne Browser AES!
                        • Server verschlüsselt den gespeicherten Hash ebenfalls und vergleicht. Bei Erfolg schickt er das Session Token. Ob dieses Token mehr Sicherheit bietet als ein gut gemachter Session Cookie, kann ich nicht beurteilen.

                        Das Prinzip ist auch bekannt als NTLM.

                        Statt einem Vergleich der verschlüsselten Hashes könnte der Server auch den private Key verwenden, um das Passwortpaket zu entschlüsseln. Dafür muss der private Key auf den Server, was sonst nicht nötig wäre. Aber das böte die Möglichkeit, dass der Client das Passwortpaket noch würzt (also salzt und pfeffert).

                        Und wem das nicht reicht, der fahre in die Hölle...

                        Rolf

                        --
                        sumpsi - posui - obstruxi
                2. Hallo Jochen,

                  Das Vezeichnis für den Fileupload sollte außerhalb der Document-Root liegen (...)

                  Hört sich interessant an, wie mache ich das genau?

                  https://www.php.net/manual/en/ini.core.php#ini.upload-tmp-dir

                  und es sollten alle Scriptausführungen in diesem Verzeichnis ausgeschaltet sein! (.htaccess -> engine off).

                  Den hab ich nicht verstanden. Wenn der tmp-Ordner außerhalb des Document Root liegt, kommt eh kein Brauser dran und kann mit PHP darüber herfallen. Oder?

                  Verwertung der übermittelten Filesize.

                  Findet im Moment eh nicht statt. Wird zumindest nicht gezeigt. PHP limitiert Files ohnehin in der Größe (siehe Ini-Schalter upload_max_filesize und post_max_size). Wenn die automatische Limitierung im Upload reicht, braucht's keine weitere Prüfung.

                  Was mir mangels eigener Upload-Entwicklung gerade unklar war: Muss man sich um das Abräumen der tmp-Dateien aus dem Upload kümmern? Macht PHP das am Request-Ende automatisch? Aber dann seh ich grad im Handbuch: "The file will be deleted from the temporary directory at the end of the request"

                  Was man deshalb auf jeden Fall machen muss, ist das Verschieben der Temp-Uploads an den gewünschten Upload-Speicherort. Mit einem am Server vergebenen Namen, wie Tom sagte. Der Name, der vom Client kommt, darf höchstens ein informatives Attribut sein.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. Hello Rolf,

                    Das Vezeichnis für den Fileupload sollte außerhalb der Document-Root liegen (...)

                    Hört sich interessant an, wie mache ich das genau?

                    https://www.php.net/manual/en/ini.core.php#ini.upload-tmp-dir

                    und es sollten alle Scriptausführungen in diesem Verzeichnis ausgeschaltet sein! (.htaccess -> engine off).

                    Den hab ich nicht verstanden. Wenn der tmp-Ordner außerhalb des Document Root liegt, kommt eh kein Brauser dran und kann mit PHP darüber herfallen. Oder?

                    Über HTTP stimmt das, wenn es kein Leck gibt.

                    Aber wer die Gelegenheit über SFTP oder Konsole oder eine Lücke in MySQL hat, darauf zuzugreifen (man weiß ja nie), der könnte auch ein Shell-Script, ein Python-Script, oder ähnliches ausführen lassen.

                    Es müssen daher ALLE Scriptausführungen für das Upload-Verzeichnis ausgeschaltet sein!

                    Glück Auf
                    Tom vom Berg

                    --
                    Es gibt soviel Sonne, nutzen wir sie.
                    www.Solar-Harz.de
                    S☼nnige Grüße aus dem Oberharz
                    1. Aber wer die Gelegenheit über SFTP oder Konsole oder eine Lücke in MySQL hat, darauf zuzugreifen (man weiß ja nie), der könnte auch ein Shell-Script, ein Python-Script, oder ähnliches ausführen lassen.

                      Hat man dann nicht ein viel grundlegenderes Problem? Wenn ich ne Shell hab, dann brauche ich keinen vorigen Upload mehr, um Unfug zu treiben.

                      1. Hello,

                        Aber wer die Gelegenheit über SFTP oder Konsole oder eine Lücke in MySQL hat, darauf zuzugreifen (man weiß ja nie), der könnte auch ein Shell-Script, ein Python-Script, oder ähnliches ausführen lassen.

                        Hat man dann nicht ein viel grundlegenderes Problem? Wenn ich ne Shell hab, dann brauche ich keinen vorigen Upload mehr, um Unfug zu treiben.

                        Dass das nicht stimmt, weißt Du hoffentlich selber.

                        Eine Shell berechtigt nicht unbedingt zur Änderung von Dateirechten oder gar Inhalten von Dateien, die einem nicht gehören. Auch um aus einer CHROOT-Umgebung auszubrechen, gibt es die obskursten Techniken.

                        Und wie man an eingeschränkte Shells auf Hosts kommt, bleibt auch oft ein Mysterium, weil die Beweise anschließend vernichtet sind.

                        Greets Robert

                        1. Dass das nicht stimmt, weißt Du hoffentlich selber.

                          Ach so furchtbar viel weiß ich über das Thema nicht. Spätestens bei Chroot-Umgebungen & Co bin ich raus. Nur:

                          Eine Shell berechtigt nicht unbedingt zur Änderung von Dateirechten oder gar Inhalten von Dateien, die einem nicht gehören.

                          Jetzt sind wir also in einem Szenario, dass ich auf einem Server mit einer so sauberen Shell(User/Rechten) unterwegs bin, dass ich auf das fragliche Web sowieso keinen Zugriff habe, richtig? Ich kann also eh nur maximal an Sachen rumfummeln, die "mir" gehören, bzw. auf die ich Rechte habe?

                          Was bringt mir dann der vorige Upload meines bösen Scripts, wenn ich es nicht ausführen kann? Selbst wenn es nicht optimal konfiguriert ist und ich es doch ausführen kann: was soll es denn böses für das Web selbst tun, wenn da wiederum die Rechte sauber sind? Verstehe ich nicht…

                          Auch um aus einer CHROOT-Umgebung auszubrechen, gibt es die obskursten Techniken.

                          Das mag sein. Wie gesagt, da bin ich nicht im Thema und verstehe auch den Zusammenhang nicht so Recht.

                          Und wie man an eingeschränkte Shells auf Hosts kommt, bleibt auch oft ein Mysterium, weil die Beweise anschließend vernichtet sind.

                          Die Aussage verwirrt mich / verstehe ich nicht. EDIT: Ah, doch, jetzt meine ich Dich zu verstehen. Der Zusammenhang mit der Fragestellung ist mir dennoch unklar.

                          Ich vermute, Raktenwilli wird sich zum Thema noch äußern.

                          1. Ich vermute, Raktenwilli wird sich zum Thema noch äußern.

                            Klar.

                            Mit einem Shell-Zugriff - auch nur mit den beschränkten Rechten eines Benutzers - fallen mir 'ne Menge Möglichkeiten ein, damit Böses zu treiben.

                            Was bringt mir dann der vorige Upload meines bösen Scripts, wenn ich es nicht ausführen kann?

                            Erfahrung? Ein anderer tut es für mich. „Erfahrung“ heißt hier: DAS hat schon mal geklappt. (Und ist übrigens 25 Jahre her, also „sowas von verjährt“ - und mit dem Thema „Verjährung“ kenne ich mich als „Schlosser“ ausweislich der Ergebnisse weitaus besser aus als ein „Prädikatsjurist und Staatsanwalt L.“ aus Dortmund)

                            Tom schrieb:

                            Es müssen daher ALLE Scriptausführungen für das Upload-Verzeichnis ausgeschaltet sein!

                            Dieses Optimum ist leider kaum oder nicht erreichbar. Aber Tom meint sicher das Ausführen von CGI oder PHP/Python (als Modul) durch den Webserver. Das mag wohl gehen.

                            1. Es müssen daher ALLE Scriptausführungen für das Upload-Verzeichnis ausgeschaltet sein!

                              Dieses Optimum ist leider kaum oder nicht erreichbar. Aber Tom meint sicher das Ausführen von CGI oder PHP/Python (als Modul) durch den Webserver. Das mag wohl gehen.

                              Wenn Du meinst, dass er das meint. Er schrub aber: Über HTTP stimmt das, wenn es kein Leck gibt.

                              Seine Aussage ging explizit um "SFTP oder Konsole oder eine Lücke in MySQL".

                              1. Es müssen daher ALLE Scriptausführungen für das Upload-Verzeichnis ausgeschaltet sein!

                                Dieses Optimum ist leider kaum oder nicht erreichbar. Aber Tom meint sicher das Ausführen von CGI oder PHP/Python (als Modul) durch den Webserver. Das mag wohl gehen.

                                Wenn Du meinst, dass er das meint. Er schrub aber: Über HTTP stimmt das, wenn es kein Leck gibt.

                                Seine Aussage ging explizit um "SFTP oder Konsole oder eine Lücke in MySQL".

                                Für den Fall nochmal:

                                „Ein anderer tut es für mich.“

                                1. Für den Fall nochmal:

                                  „Ein anderer tut es für mich.“

                                  Gut, auch da "meine ich zu verstehen". Szenario wäre dann wie? Du böser Bube lädst also via HTTP ein böses Script irgendwohin. Dann sagst Du Deinem Gangster-Brother mit Shell bescheid: "ey, führ mal /var/www/public/boese.php" aus, korrekt?

                                  Aber wenn Dein Gangster-Brother das kann, wofür braucht der Deinen Upload? Ist mir zu hoch und ich freue mich auf Aufklärung, was ich da übersehe / falsch verstehe.

                                  1. Für den Fall nochmal:

                                    „Ein anderer tut es für mich.“

                                    Gut, auch da "meine ich zu verstehen". Szenario wäre dann wie? Du böser Bube lädst also via HTTP ein böses Script irgendwohin. Dann sagst Du Deinem Gangster-Brother mit Shell bescheid: "ey, führ mal /var/www/public/boese.php" aus, korrekt?

                                    Aber wenn Dein Gangster-Brother das kann, wofür braucht der Deinen Upload? Ist mir zu hoch und ich freue mich auf Aufklärung, was ich da übersehe / falsch verstehe.

                                    Die von mir freundlich hinterlassene „KlickMich.bat“ hat der zuständige MCSE (Administrator) prompt und ohne hineinzuschauen ausgeführt. Sowas passiert, wenn man darin unterwiesen wurde, was man tun kann - aber nicht weiß, was man besser nicht tun soll.

                                    Unter Linux könnte es reichen, wenn der den MC benutzt, sich wundert warum die Datei „völlig_harmlos“ so schön grün ist (mit chmod u=rwx,g=rx,o=rx völlig_harmlos erreicht man das) und auf die Enter-Taste haut.

                                    1. Die von mir freundlich hinterlassene „KlickMich.bat“ hat der zuständige MCSE (Administrator) prompt und ohne hineinzuschauen ausgeführt. Sowas passiert, wenn man darin unterwiesen wurde, was man tun kann - aber nicht weiß, was man besser nicht tun soll.

                                      Unter Linux könnte es reichen, wenn der den MC benutzt, sich wundert warum die Datei „völlig_harmlos“ so schön grün ist (mit chmod u=rwx,g=rx,o=rx völlig_harmlos erreicht man das) und auf die Enter-Taste haut.

                                      Wir bewegen uns also im Szenario "Admin sieht grün und drückt drauf". Machen Admins in Upload-Ordnern ja gerne. Okay, dürfte ich in dem Zusammenhang erneut auf die fragliche These des Teilthreads zurückommen?

                                      1. Machen Admins in Upload-Ordnern ja gerne.

                                        In dem Fall war es der Desktop…

                                        Irgend etwas sagt mir aber, dass Du nicht begreifen willst, was ich Dir aufschreibe.

                                        Dann eben so: Das ein berechtigter Benutzer aufpasst wie ein „Schießhund“ sollte allenfalls die letzte Verteidigungslinie sein. Keinesfalls die erste. Und das bedeutet: Es sind mehrere Verteidigungslinien erforderlich.

                                        1. Hallo Raketenwilli,

                                          es ist aber doch so, dass PHP im tmp-Ordner auch nur tmp-Namen verwendet. "KlickMich.bat" existiert nur für die Dauer der Request-Ausführung im RAM des PHP Prozesses.

                                          Dass man Upload-Dateien nicht unter dem vom Benutzer "vorgeschlagenen" Namen speichern soll, hatten wir auch schon.

                                          Der Admin, der ein "Klickmich.bat" sieht und blindlings draufklickt, gehört wohl als BOFH (mit B für braindead) eingruppiert. Sowas macht eher ein IT-inkompatibler Vorstandsassistent. Und der BOFH würde, wenn er die "des is net ekschekuhtebel" Meldung bekommt und das Ding UNBEDINGT ausführen will, auch nicht zu faul sein, das X-Bit irgendwie zu setzen.

                                          Wenn ich, wie von Tom postuliert, eine Lücke im MySQL oder einem anderen Programm finde und damit so weit komme, dass ich eine im Upload-Verzeichnis (dessen physischen Ort ich erstmal kennen muss) hinterlegte Script-Datei starten kann (deren physischen Namen ich auch erstmal kennen muss), dann könnte eine solche Execute-Sperre natürlich eine weitere Hemmschwelle bilden.

                                          Nur - wenn ich so weit bin, brauche ich dann noch mein böses Script?

                                          Und ich weiß auch nicht, ob das X Bit überhaupt beachtet wird, wenn ich das Script nicht direkt starte, sondern bash oder sh aufrufe und dem das Script als Argument übergebe. Ich bin zu windoof, um das zu wissen 😉

                                          Rolf

                                          --
                                          sumpsi - posui - obstruxi
                                          1. Der Admin, der ein "Klickmich.bat" sieht und blindlings draufklickt, gehört wohl als BOFH (mit B für braindead) eingruppiert.

                                            Der ist „bestraft genug“, der arbeitet immer noch in der Bude. Das ist derselbe, welcher den Rechner der Chefsekretärin komplett für jeden zum Lesen und Schreiben frei gegeben hat - was mir am ersten Arbeitstag den Vorwurf einbrachte, ich würde „hacken“. Dabei hatte ich mich nur nur klickend über die Netzwerkumgebung kundig gemacht. Das nächste Mal melde ich das nicht, sondern passe meinen Arbeitsvertrag an zwei Stellen (Gehalt und Urlaub) an.

                                            es ist aber doch so, dass PHP im tmp-Ordner auch nur tmp-Namen verwendet.

                                            Und stell Dir vor: Nach Beendigung der Bearbeitung des Requests wird das Zeug im TempDir sogar gelöscht.

                                            Deshalb kopieren es eben manche Skripte - bequemer Weise ohne Authentifizierung - vorher wo anders hin und glauben an übermittelte Dateinamen und Content-/Mime-Typen. U.a. ein (nicht mehr existentes) Wordpress-Plugin. (Das hätte übrigens auch eine ~/.ssh/authorized_keys schreiben können - Hacker sind halt doch blöd...)

                                            Und ich weiß auch nicht, ob das X Bit überhaupt beachtet wird, wenn ich das Script nicht direkt starte, sondern bash oder sh aufrufe und dem das Script als Argument übergebe.

                                            Das wird es durchaus. Aber eben das von /usr/bin/sh oder /usr/bin/bash (/bin/sh oder /bin/bash bei nicht ganz so modernen Betriebssystemen). Deshalb brauchen ja PHP-Skripte (so man diese via Webserver startet) kein x-Bit: Ausgeführt wird PHP.

                                            1. Hallo Raketenwilli,

                                              Das wird es durchaus. Aber eben das von /usr/bin/sh oder ...

                                              Genau das war mir unklar und ich musste jetzt etwas mit meinem Ubuntu-Subsystem für Windows rumspielen (das ich bisher kaum verwendet habe...).

                                              ./test.sh - beachtet das x-Bit bash test.sh - beachtet das x-Bit nicht

                                              Wenn man also ein Loch in mysql bohren kann und bash starten kann, könnte man beliebige Scripte ausführen. X-Bit hin oder her.

                                              Was ich nicht beurteilen kann, da ich weder Gynäkologe noch Proktologe bin: Ist es einfacher, durch ein enges Loch hindurch /tmp/foo/pwnya.sh zu starten als /usr/bin/bash /tmp/foo/pwnya.sh? Davon hängt dann ab, ob der Entzug des x-Bits im Upload-Ordner irgendeinen Sinn hat.

                                              Rolf

                                              --
                                              sumpsi - posui - obstruxi
                                              1. Davon hängt dann ab, ob der Entzug des x-Bits im Upload-Ordner irgendeinen Sinn hat.

                                                Da geht es wieder um das Unvermögen und schlechte Beisiele in der Literatur oder gar auf YouUnsinn.

                                                Jemand will alle Verzeichnisse für den Webserver betretbar machen und hat dort in einem Clip von 20:05 Minuten (es wurde danach auch neu gebootet) erfahren, dass er dafür die Rechte mit 775 setzen müsste.

                                                idiot@kaputt:~$ find --name * --exec chmod 755
                                                

                                                (Die fünf(5) Fehler in diesem Befehl sind volle ABSICHT, damit das keiner nachmacht.)

                                                Ein halbwegs brauchbarer Shellbenutzer würde das nie tun - aber Webseitenbetreiber mit dem Zeugnis der YouTube-IdiotenAkademie tun SOWAS.

                                                Folge: Alle Dateien sind ausführbar.

                                                Gegen solche könnte es helfen, bei Mounten etwas wie noexec setzen zu können.

                                                #!/usr/bin/bash
                                                # file: test.sh
                                                echo Mist
                                                
                                                • /media/nas-1.iscsi ist mit noexec gemountet:

                                                Der Test:

                                                user@host:/media/nas-1.iscsi$ chmod 755 test.sh
                                                user@host:/media/nas-1.iscsi$ ./test.sh
                                                bash: ./test.sh: Keine Berechtigung
                                                

                                                Gelobt sei der Herr, der die Mountoption setzte, dafür.

                                                Der Sinn: Jemand könnte etwas wie eine Datei namens ls hinterlassen. (Das ist nur ein Beispiel) Ein kleiner Tippfehler wie .\ls könnte sodann in die Katastrophe führen. Noch schlimmer wird es, wenn ein „Professor X“ in der YouVideoglotzerHochschule, der schnell, einfach, ohne Arbeit und dauerhaft Geld von zu Hause verdienen will, folgendes empfiehlt:

                                                Um Dateien im aktuellen Verzeichnis einfach ausführen zu können, schreiben Sie ganz einfach und ohne Nachzudenken

                                                PHAT=.:$PATH
                                                

                                                in Ihre Profildatei.

                                                (BAD! BAD! BAD! Do not! Nicht machen!)

                                                Und schon: Peng! ls ist nicht mehr der Befehl zum Listen von Dateien, sondern das böswillig abgelegte Skript im Verzeichnis, welches auf diese Sorte „YouTube-root“ wartet.

                                                (Deshalb hab ich oben wieder einen Fehler eingebaut...)

                                                Allerdings stellt die Bereitstellung einer solchen Ressource ziemlich happige Anforderungen…

                                          2. Nur - wenn ich so weit bin, brauche ich dann noch mein böses Script?

                                            Danke. Sämtliche Antworten auf diese entscheidende Frage haben diesen Aspekt bislang weitgehend ignoriert. Vielleicht hast Du ja mehr Glück.

                                            Bis zur womöglichen Klärung ist die ganze Nummer hier m.E. eine Scheindiskussion, die mit der Fragestellung nicht mehr allzuviel am Hut hat.

                                            1. Nur - wenn ich so weit bin, brauche ich dann noch mein böses Script?

                                              Danke. Sämtliche Antworten auf diese entscheidende Frage haben diesen Aspekt bislang weitgehend ignoriert.

                                              Diese, nennen wir es unzutreffend „Erkenntnis“ gilt nur für Dich und kommt nur deshalb zu Stande, weil Du die vorgetragenen Sachverhalte gar nicht zur Kenntnis nehmen willst. Ich habe sogar den sich stetig verfestigenden Eindruck, dass es Dir gar nicht um die vorgebliche Sache geht.

                                              Hand aufs Herz: Geht es Dir um „Bash“ oder „Bashing“?

                                              1. Hallo Raketenwilli,

                                                vermutlich beides.

                                                Dieser Satz von Tom ist ja das Schwein des Angrunzens:

                                                Es müssen daher ALLE Scriptausführungen für das Upload-Verzeichnis ausgeschaltet sein!

                                                Und da haben wir beide ja eigentlich herausgearbeitet, dass der Nutzen dieser Schaltung sehr begrenzt ist. Weil ich, wenn ich etwas "starten" kann, auch die bash starten könnte und ihr das Script übergeben. Und bash kümmert sich einen feuchten Grunz um das X-Bit am Script.

                                                Meine eigenen Basteleien haben aber auch ergeben, dass eine Datei, die ich per Texteditor erstelle, unter Ubuntu automatisch kein X-Bit hat. Ich würde annehmen, dass PHP den Upload-Dateien auch kein X-Bit gibt. Ich habe aber keine Ahnung vom Linux-Betrieb.

                                                Tom's Ansatz ist nicht falsch. PHP Uploads sollten per Default grundsätzlich nicht ausführbar sein - dafür gibt's keinen sinnvollen Grund. Ist meine Erfahrung, dass das X-Bit nicht automatisch erscheint, ein Sonderfall meines WSL-Ubuntu oder ist das generell so? Wenn nicht, was muss man tun, um das herbeizuführen? Diese Frage finde ich durchaus interessant.

                                                Rolf

                                                --
                                                sumpsi - posui - obstruxi
                                                1. Hello,

                                                  Hallo Raketenwilli,

                                                  vermutlich beides.

                                                  Dieser Satz von Tom ist ja das Schwein des Angrunzens:

                                                  Es müssen daher ALLE Scriptausführungen für das Upload-Verzeichnis ausgeschaltet sein!

                                                  Und da haben wir beide ja eigentlich herausgearbeitet, dass der Nutzen dieser Schaltung sehr begrenzt ist. Weil ich, wenn ich etwas "starten" kann, auch die bash starten könnte und ihr das Script übergeben. Und bash kümmert sich einen feuchten Grunz um das X-Bit am Script.

                                                  Aber zum Glück um die Rechte der affketierten Ressourcen!

                                                  Glück Auf
                                                  Tom vom Berg

                                                  --
                                                  Es gibt soviel Sonne, nutzen wir sie.
                                                  www.Solar-Harz.de
                                                  S☼nnige Grüße aus dem Oberharz
                                                2. Hallo,

                                                  Tom's Ansatz ist nicht falsch. PHP Uploads sollten per Default grundsätzlich nicht ausführbar sein - dafür gibt's keinen sinnvollen Grund.

                                                  sehe ich auch so.

                                                  Ist meine Erfahrung, dass das X-Bit nicht automatisch erscheint, ein Sonderfall meines WSL-Ubuntu oder ist das generell so?

                                                  Das ist generell so. PHP speichert die Upload-Datei in ein vorkonfiguriertes Verzeichnis, setzt aber kein x-Bit. Wozu auch?

                                                  Wenn nicht, was muss man tun, um das herbeizuführen?

                                                  Das müsste man im PHP-Script mutwillig selbst tun.

                                                  Einen schönen Tag noch
                                                   Martin

                                                  --
                                                  Im Englischen hat eine Katze neun Leben. Im Deutschen vielleicht auch, aber nach Abzug der Steuern bleiben nur noch sieben übrig.
                                                3. Weil ich, wenn ich etwas "starten" kann, auch die bash starten könnte

                                                  „Kasus Knacktus“ ist nach meiner Ansicht das „ich“. Wie ich es sehe, geht es darum, dass Dateien, die ein (nicht sorgfältig authentifizierter) Benutzer der Website hinterlassen kann, nicht von einem anderen (Prozess wie Apache oder deren Kindprozesse oder einem Shell-Nutzer) ausgeführt werden können. Dieses Oster-Szenario(¹) ist viel weniger abstrakt als manche glauben.

                                                  Der Satz von Tom …

                                                  Es müssen daher ALLE Scriptausführungen für das Upload-Verzeichnis ausgeschaltet sein!

                                                  … mag überzogen klingen und kann es durchaus auch auch sein, weil er bei kleinlicher Auslegung ein Szenario beschreibt, welches bei begrenztem Mehrwert nur schwierig zu erreichen ist. Für mich würde es, so man die Kirche im Dorfe lassen will, genügen, wenn die Uploads in einem Verzeichnis landen, auf welches der Webserver keinen direkten Zugriff hat (also außerhalb des Document-Root liegt) - oder, wenn das doch sein soll, wenigstens nichts davon ausführt. Sei es nun als Skript - oder wie im Falle von PHP und Python - durch ein Modul. Außerdem sollte ein nicht durch sorgfältig authentifizierte Nutzer getriggertes Upload-Skript natürlich nichts an bestehenden Dateien verändern.


                                                  ¹) Oster-Szenario: Der Hase legt die Eier aber die Kinder finden und essen sie. Man kann (außerhalb geschlossener und kontrollierter Umgebungen) nur hoffen, dass es der echte Osterhase war… Also kontrolliert man die Funde, bevor diese zum Essen frei gegeben werden.

                                                4. Hello,

                                                  Ist meine Erfahrung, dass das X-Bit nicht automatisch erscheint, ein Sonderfall meines WSL-Ubuntu oder ist das generell so? Wenn nicht, was muss man tun, um das herbeizuführen? Diese Frage finde ich durchaus interessant.

                                                  MMn müsste es reichen, wenn ein autorisierter Benutzer die UMASK passend setzt.

                                                  Kommt also immer darauf an, wer welche Rechte auf welche Verzeichnisse hat. Ggf. auch versehentlich.

                                                  Solche Angriffe werden aber i.d.R. in mehrere Schritte aufgeteilt. Darum merkt man sie leider auch erst, wenn es zu spät ist.

                                                  Wir hatten sowas leider erst. Und keiner wills gewesen sein. Da wurde bei einer Datenwiederherstellung einigen Diensten, die gar keine benötigen / keine haben sollten, eine Shell gegeben. Und bums, hatten wir nen Doppelwumms auf dem Server. Relevante Daten waren plötzlich einfach weg.

                                                  Glück Auf
                                                  Tom vom Berg

                                                  --
                                                  Es gibt soviel Sonne, nutzen wir sie.
                                                  www.Solar-Harz.de
                                                  S☼nnige Grüße aus dem Oberharz
                                                  1. Hallo TS,

                                                    wie erklärt man denn einem Apache oder einem PHP FastCGI Prozess, welche UMASK er haben soll? Hat der überhaupt eine UMASK? Ich hab ja keine Ahnung von Linux, aber mein schnelles man-stöbern sagt, dass UMASK ein Feature der Shell ist.

                                                    Meine Suche nach "Wie setzt man die Default-UMASK" zeigt mir Hinweise auf Files in /etc (profile, bashrc, profile.d/umask.sh) und .bashrc in meinem /home-Ordner - aber zieht das auch für einen Dienst wie Apache?

                                                    Rolf

                                                    --
                                                    sumpsi - posui - obstruxi
                                                    1. Hello Rolf,

                                                      wie erklärt man denn einem Apache oder einem PHP FastCGI Prozess, welche UMASK er haben soll? Hat der überhaupt eine UMASK? Ich hab ja keine Ahnung von Linux, aber mein schnelles man-stöbern sagt, dass UMASK ein Feature der Shell ist.

                                                      Ein Kernel-Feature der Shell, der API (wie PHP sie nutzt) und der Voreinstellungen für den User, unter dem der Prozess läuft.

                                                      Ich wette, Raketenwilli kann das wesentlich besser aufdröseln, wo man die umask überall beeinflussen kann, als ich. :-)

                                                      Hier ist schon mal ein Link auf eine Beschreibung, die ich für den Anfang ganz gut finde.

                                                      Glück Auf
                                                      Tom vom Berg

                                                      --
                                                      Es gibt soviel Sonne, nutzen wir sie.
                                                      www.Solar-Harz.de
                                                      S☼nnige Grüße aus dem Oberharz
                                                      1. umask bringt das Thema nicht weiter: Denn das Ausführen-Recht wird für Dateien nicht automatisch vergeben. Egal wie die umask gesetzt ist.

                                                        Aber Du kannst zwecks Härtung gerne bei AppArmor und/oder SeLinux weiterforschen…

                                                        1. Hello JR,

                                                          umask bringt das Thema nicht weiter: Denn das Ausführen-Recht wird für Dateien nicht automatisch vergeben. Egal wie die umask gesetzt ist.

                                                          Vielen Dank.

                                                          Hab's auch gerade nochmal ausprobiert. Umask kann also nicht zur Lücke umgennutzt werden.

                                                          Binätdateien können also nicht so einfach gestartet werden.

                                                          Es kommen jetzt neben den unbekannten Stellen noch die Scripserver in Frage:

                                                          • php
                                                          • python
                                                          • nodeJS
                                                          • perl
                                                          • ...

                                                          Und was ist mit den Diensten? Wenn man die kapern kann, könnte da der Angriffsvektor liegen, oder? Ich habe da immer besondere Angst vor einer Lücke in einem php/mysql-Skript, also Zugriff über PHP auf den MySQL-Server ohne passendes Escaping.

                                                          Glück Auf
                                                          Tom vom Berg

                                                          --
                                                          Es gibt soviel Sonne, nutzen wir sie.
                                                          www.Solar-Harz.de
                                                          S☼nnige Grüße aus dem Oberharz
                                                          1. Und was ist mit den Diensten? Wenn man die kapern kann, könnte da der Angriffsvektor liegen, oder? Ich habe da immer besondere Angst vor einer Lücke in einem php/mysql-Skript, also Zugriff über PHP auf den MySQL-Server ohne passendes Escaping.

                                                            Da hilft es, die Privilegien a) zu kennen und b) sparsam zu vergeben.

                                                            https://dev.mysql.com/doc/refman/8.0/en/grant.html#grant-privileges

                                                            Es kommen jetzt neben den unbekannten Stellen noch die Scripserver in Frage:

                                                            • php
                                                            • python
                                                            • nodeJS
                                                            • perl

                                                            Ja. Natürlich muss man aufpassen, dass man sich da kein Eier legt. Aber diese Angst ist mit dem Speichern außerhalb des Document-Roots und/oder ggf. der Dekonfiguaration der Skriptausführung (also Module,CGI) für Verzeichnisse fast erschlagen - es sei denn man kuckt zu viel Youtube und macht de Scheiß nach.

                                                            Die andere Variante, nämlich zu viel Angst zu haben, ist auch nicht so supergesund… Ich bekomme ordentliches Geld dafür, bei klarem Kopf zu bleiben.

                                        2. Irgend etwas sagt mir aber, dass Du nicht begreifen willst, was ich Dir aufschreibe.

                                          Wenn, dann liegt es an meinem mangelnden Verständnis, garantiert nicht am Willen. Wirklich.

                                          Mein(!) gedankliches Grundproblem bleibt bestehen: wenn ich eine Shell habe, dann darf ich genau das tun und lassen, was mir erlaubt ist.

                                          Jetzt kommt meine Frage:

                                          Welchen "Vorteil" habe ich, wenn durch einen PHP-Upload irgendwo ein Script liegt, welches ich ausführen kann? Was kann das Script dann mehr/besser, als ich es ohnehin via Shell schon könnte?

                                          Antwort sehr gerne als ein einfaches, konkret nachvollziehbares Beispiel. Danke!

                                          1. Hello,

                                            Welchen "Vorteil" habe ich, wenn durch einen PHP-Upload irgendwo ein Script liegt, welches ich ausführen kann? Was kann das Script dann mehr/besser, als ich es ohnehin via Shell schon könnte?

                                            Mittels einer Shell darfst Du durchaus Binärdateien ausführen, auf die Du Zugriff hast, aber Du darfst in diesem Pfad nicht unbedingt neue Dateien speichern und ausführbar machen. Und schon gar nicht mit den Rechten eines qualifizierten Benutzers (z. B. root).

                                            Die Dienste, wie z. B. PHP, dürfen das aber eventuell trotzdem, auch wenn sie ihr eingebautes EXEC-Recht für die User abgeschaltet haben.

                                            Das heißt, der Eine lädt hoch, der Zweite macht ausführbar und der Dritte führt aus.

                                            Glück Auf
                                            Tom vom Berg

                                            --
                                            Es gibt soviel Sonne, nutzen wir sie.
                                            www.Solar-Harz.de
                                            S☼nnige Grüße aus dem Oberharz
                                            1. Mir ist das offensichtlich weiterhin zu hoch. Machen wir das doch mal konkret. Sagen wir mal ich habe eine Shell "evil@example.org". Mit der kann ich mich laut meinen Rechten auf dem System bewegen, wie auch immer die gesetzt sind.

                                              Dann lädt jemand via "https://example.org/upload.php" ein Script nach "/var/xyz/script.sh" hoch.

                                              Jetzt ists halt doof gelaufen und ich kann "/var/xyz/script.sh" ausführen. Was genau kann "/var/xyz/script.sh" dann mehr, als ich es ohnehin via Shell könnte?

                                              1. Mir ist das offensichtlich weiterhin zu hoch. Machen wir das doch mal konkret. Sagen wir mal ich habe eine Shell "evil@example.org". Mit der kann ich mich laut meinen Rechten auf dem System bewegen, wie auch immer die gesetzt sind.

                                                Dann lädt jemand via "https://example.org/upload.php" ein Script nach "/var/xyz/script.sh" hoch.

                                                Jetzt ists halt doof gelaufen und ich kann "/var/xyz/script.sh" ausführen. Was genau kann "/var/xyz/script.sh" dann mehr, als ich es ohnehin via Shell könnte?

                                                Bis auf Widerspruch: gar nix. Wäre ja irgendwie auch komisch. Also was soll die ganze Nummer hier eigentlich?

                                                Das einzig, halbwegs (für mich) plausible Argument hierzu bislang war Jörgs These, dass ein Admin(berechtiger User) sonen Ding aus Versehen startet und Dank seiner Berechtigungen dann entsprechendes Unheil anrichten kann. Okay, ja. Mann kann sich auch ein Loch ins Knie bohren und so…

                                                Sollte ich da was übersehen: bitte gerne her mit Argumenten.

                                                1. Jetzt ists halt doof gelaufen und ich kann "/var/xyz/script.sh" ausführen. Was genau kann "/var/xyz/script.sh" dann mehr, als ich es ohnehin via Shell könnte?

                                                  Kasus knacktus ist die genaue Wortwahl: Es könnte etwas tun, was Du nicht tun wolltest.

                                                  Was nun dieses „etwas“ dann ist oder sein könnte bietet Raum für eine gewaltige Menge an Spekulationen…

                                              2. Hallo Mitleser,

                                                wie Jörg schrub: Es kann genau das, was Du kannst, aber wenn es nicht von Dir ist, dann tut es vielleicht was, was Du gar nicht wolltest.

                                                Meine Frage ist aber: Wieso sollte so eins Script an einen Ort kommen, wo ein Admin es unbeabsichtigt ausführt? Wenn die erste Verteidigungslinie ordentlich ist, dann kann es doch nur im Upload-Ordner des Web-Projekts landen. Und da sollten einem Admin doch automagisch alle Alarmglocken gebimmelt haben.

                                                Dass PHP eine Upload-Datei von sich aus nicht executable macht, sollten wir doch mittlerweile geklärt haben, und wenn ich einen Nonsense gebaut habe und mir irgendwer tatsächlich ein Script an eine Stelle hochladen kann, wo ich es mit etwas anderem wervexele und irrigtümlicherweise starte, dann starte ich es entweder direkt und kriege ein "des derfst Du net!" auf's Maul, oder ich starte penetranterweise bash und übergebe es als Parameter, was das X-Bit ignoriert, und dann hilft die ganze X-Bit Diskussion nichts.

                                                Also mein Fazit ist: das X-Bit nützt nix. Die UMASK nützt nix. Die existenten Verteidigungslinien sind:

                                                • PHP setzt von sich aus eh kein X-Bit. Toms Forderung, dass der Upload in einem Ordner landen muss, wo kein Executable-Recht gesetzt ist, ist damit implizit gegeben.
                                                • Ein sauber programmiertes Script sorgt dafür, dass der Upload nicht irgendwo™️ landet

                                                Weitere Maßnahmen können sein:

                                                • Man benennt Uploads mit wilden Zufallsnamen und hat eine zweite Informationsstelle, in der steht, welcher Zufallsname welchem Upload-File entspricht.
                                                • Man speichert Upload-Files nicht im Filesystem, sondern in einer DB. Oder man "verschlüsselt" sie - da reicht schon eine XOR-Maske. Hauptsache, sie sind nicht unmittelbar von Shell oder Desktop aus nutzbar.

                                                Dass ein Angreifer es durch eine Hintertür schafft, ein solches File zu descramblen und zu starten, scheint mir unwahrscheinlich. Bzw. wenn er das schafft, braucht er das File nicht und kann ohnehin bereits ganz anderen Schabernack anrichten.

                                                Rolf

                                                --
                                                sumpsi - posui - obstruxi
                                                1. Hello,

                                                  wobei "nicht ausführbar" auch bedeutet "mit keinem Interpreter ausführbar".

                                                  Ob das nun binär, eine Shell, oder Perl, oder PHP, oder Python, oder NodeJS, oder Java für Server, oder, ..., ist, ist unerheblich.

                                                  Glück Auf
                                                  Tom vom Berg

                                                  --
                                                  Es gibt soviel Sonne, nutzen wir sie.
                                                  www.Solar-Harz.de
                                                  S☼nnige Grüße aus dem Oberharz
                                                2. Es gibt immer zig Angriffsvektoren auf welches Setup auch immer. Da wird man auch gerne mal überrascht. Gesunde Paranoia ist also erstmal hilfreich.

                                                  Das hiesige Setup "Php-Upload mit kongenialem Shell-Fritze" ist ein Nebenkriegsschauplatz. Völlig überwertetet.

                                                  Halt das System aktuell und guck auf die Rechte. Das sollte und kann man tun. With great power comes great responsibility. Fertig.

                                                  Achso... Hello Tom: Backup ist auch ne ganz gute Sache. Womöglich sogar wichtiger als Ängste um irgendwelche Exploits in irgendeinem Dienst, wie z.B. Mysql.

                              2. Seine Aussage ging explizit um "SFTP oder Konsole oder eine Lücke in MySQL".

                                Und sind damit die älterern Aussagen ungültig?

                                Ich habe das so verstanden, dass eine Warnung auf der anderen aufgebaut hat.

                                Lies bitte nochmal.

                                Greetz Robert

                                1. Und sind damit die älterern Aussagen ungültig?

                                  Ich habe das so verstanden, dass eine Warnung auf der anderen aufgebaut hat.

                                  Lies bitte nochmal.

                                  Gerne. Hilf Du mir bitte vorab, indem Du den Deiner Einschätzung nach Kern der Sache noch einmal auf den Punkt bringst. Danke!

                3. Moin Jochen,

                  Bedenke aber auch, dass ich der einzige User dieser App bin, soll heißen, die Motivation, meinen eigenen server zu hacken ist gering und meine Möglichkeiten, dies zu tun, sind auf andere Weise deutlich größer. 😉

                  ist der Server im Internet erreichbar? Was hindert jemanden daran deinen Service direkt zu kontaktieren, ohne App?

                  Viele Grüße
                  Robert

                  1. Hello,

                    Bedenke aber auch, dass ich der einzige User dieser App bin, soll heißen, die Motivation, meinen eigenen server zu hacken ist gering und meine Möglichkeiten, dies zu tun, sind auf andere Weise deutlich größer. 😉

                    ist der Server im Internet erreichbar? Was hindert jemanden daran deinen Service direkt zu kontaktieren, ohne App?

                    Genau das hatte ich ebenfalls bemängelt!

                    Aber vermutlich hätte ich daraus, wie meistens, mindetens drei publizierte Denkschritte machen müssen, damit man mir folgen kann ;-P

                    Jetzt warte ich nur noch auf diverse Kommentare von Followern ;-)

                    Glück Auf
                    Tom vom Berg

                    --
                    Es gibt soviel Sonne, nutzen wir sie.
                    www.Solar-Harz.de
                    S☼nnige Grüße aus dem Oberharz
                  2. Hello,

                    das hatte ich schon vor ca. 3 Stunden gefragt. Frage, aber vermutlich muss man sowas mehrmals fragen, damit es auch gelesen wird. :-(

                    Moin Jochen,

                    Bedenke aber auch, dass ich der einzige User dieser App bin, soll heißen, die Motivation, meinen eigenen server zu hacken ist gering und meine Möglichkeiten, dies zu tun, sind auf andere Weise deutlich größer. 😉

                    ist der Server im Internet erreichbar? Was hindert jemanden daran deinen Service direkt zu kontaktieren, ohne App?

                    Viele Grüße
                    Robert

                    Glück Auf
                    Tom vom Berg

                    --
                    Es gibt soviel Sonne, nutzen wir sie.
                    www.Solar-Harz.de
                    S☼nnige Grüße aus dem Oberharz
            2. Hallo Jochen,

              worauf Tom abzielte, war eine Überprüfung des empfangenen JSON-Objekts (das Du in PHP als assoziatives Array empfängst).

              Eine Festlegung, welche Einträge Pflichtfelder sind, und eine Prüfung auf Erfüllung dieser Pflicht ist eine gute Idee. Du möchtest ja beispielsweise nicht str_replace mit NULL als drittem Parameter aufrufen. Ab PHP 8.1 haut Dir das eine deprecated-Meldung um die Ohren (warum auch immer die NULL mal erlaubt war).

              Was Du definitiv nochmal gut überlegen solltest, ist utf8_decode.

              Erster Grund für die Ablösung ist PHP 8.2, ab da ist diese Funktion deprecated. Schlauerweise sagt das PHP Handbuch nicht, was man statt dessen tun sollte, unter anderem deshalb, weil es 4 Alternativen gibt:

              • Den alten Kram in die Tonne kloppen und statt dessen konsequent mit Unicode arbeiten. Darauf gehe ich im Anschluss ein - das ist zwar die beste Alternative, bei existierenden Projekten aber einiges an Arbeit.
              • iconv (setzt ein "neueres Posix-konformes Betriebssystem" voraus - was auch immer das genau heißt)
              • mb_convert_encoding (Die Multibyte-Extension braucht keine externen Libs, muss aber bein Compilieren von PHP aktiviert werden)
              • UConverter::transcode (Teil der intl-Extension, braucht die ICU Library)

              Lies Dir unter php.net durch, wie man die Funktionen verwendet. Du möchtest von UTF-8 nach ISO-8859-15 konvertieren.

              Mit geht ein bisschen das Verständnis für die ganzen Voraussetzungen ab, die im PHP Handbuch für diese 3 Varianten gelistet sind. Zum einen bin ich kein PHP Selbstkompilierer, zum anderen bin ich mit PHP unter Linux unerfahren. Ich würde einfach ausprobieren, welche Variante funktioniert - vermutlich tun es alle 3. Welche davon speichersparender oder schneller ist, weiß ich auch nicht.

              Wenn es funktioniert, wäre meine unmaßgebliche Empfehlung als zweitbeste Lösung diese:

              $description = iconv("UTF-8", "ISO-8859-15//TRANSLIT", $jsonData['description']);
              

              Die TRANSLIT-Option sucht Ersatzzeichen für nicht übersetzbare Codepoints und würde Dir aus "Pjotr Żyła" ein "Pjotr Zyla" machen. Nicht wirklich gut, aber besser als "?y?a" (utf8_decode), "ya" (UConverter::transcode), "ya" (iconv mit "ISO-8859-15//IGNORE" oder FALSE (iconv mit "ISO-8859-15", ohne Option).

              Wichtig ist dann auch, dass deine DB-Verbindung und deine Datenbank-Collation auf ISO-8859-15 eingestellt sind. Der MYSQL-Default ist schwedisch. Besser ist natürlich UTF8, und zwar in der mb4-Variante. Auch da hat MYSQL den blöden Default "mb3", also UTF-8 Encoding mit maximal 3 Byte langen Codes, was beim Speichern eines Emojis zu einem SQL Fehler führt.

              Und nun zur besten Lösung: Dass Du diese Funktion verwendest, bedeutet ja, dass Du PHP-seitig ISO-8859-1 (oder Latin-1) als Zeichencodierung verwendest. Das ist oft hinreichend für Anwendungen in deutscher Sprache, bis auf das € Zeichen. Das ist in ISO-8859-1 nicht enthalten, das gibt's nur in ISO-8859-15 (Latin-9).

              Der schon erwähnte "Pjotr Żyła" springt Dir damit aber ins Gesicht. Und wenn der springt, hat das Wucht… Den speicherst Du bei ISO-8859-15 je nach Transcodingverfahren als ?y?a, Zyla, ya oder ya. Moderne Software sollte intern definitiv Unicode verwenden. Dazu musst Du

              • PHP auf Unicode einstellen (was es per Default eigentlich sein sollte). Aber guck in deine PHP.ini, was da an encoding-Schaltern gesetzt ist.
              • Deinen PHP Sourcecode als UTF-8 speichern (und zwar ohne BOM, sonst haut er Dir das BOM schneller raus als Du Fragezeichen Pe Ha Pe sagen kannst)
              • Wenn Du eine Datenbank nutzt: Deine DB-Connection für Unicode einrichten (kann man beim Öffnen der Connection angeben oder im Server als Default setzen), und deine Datenbank und deine Tabellen vom bekloppten MySQL Default "schwedisch" auf mb4 umstellen (UTF-8 mit bis zu 4 Bytes langen Encodings - mb3 rastet aus wenn es ein Emoji bekommt). Diese Frage bei Stackoverflow scheint Antworten zu haben, die ziemlich ausführlich sind
              • gründlich testen
              • Bei jedem Aufruf einer Stringfunktion in PHP dringend überlegen, ob man dafür nicht besser das mb_...-Gegenstück verwendet.

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Hello Rolf,

                Hallo Jochen,

                worauf Tom abzielte, war eine Überprüfung des empfangenen JSON-Objekts (das Du in PHP als assoziatives Array empfängst).

                ... und diverser anderer Sicherheitslücken!

                Wenn es funktioniert, wäre meine unmaßgebliche Empfehlung als zweitbeste Lösung diese:

                $description = iconv("UTF-8", "ISO-8859-15//TRANSLIT", $jsonData['description']);
                

                Die TRANSLIT-Option sucht Ersatzzeichen für nicht übersetzbare Codepoints und würde Dir aus "Pjotr Żyła" ein "Pjotr Zyla" machen. Nicht wirklich gut, aber besser als "?y?a" (utf8_decode), "ya" (UConverter::transcode), "ya" (iconv mit "ISO-8859-15//IGNORE" oder FALSE (iconv mit "ISO-8859-15", ohne Option).

                Hast Du damit schon Erfahrungen?
                Dann hätte ich Interesse an Input.

                Wichtig ist dann auch, dass deine DB-Verbindung und deine Datenbank-Collation auf ISO-8859-15 eingestellt sind. [...]

                ...und dass das passende Escaping für die Datenbank zur rechten Zeit verwendet wird!

                Ich finde das, was Sven-Jochen hier "nur für sich" programmiert, durchaus interessant für Viele. Mich würde eine funktionierende Lösung auf jeden Fall interessieren, und wenn er dazu bereit wäre, sollten wir ihn auf jeden Fall intensiv dabei unterstützen, auf allen Gebieten:

                • RAD (Applets), Java, das interessierte doch Dich kützlich erst?
                • PHP Sicherheit
                • Apache Sicherheit bei PHP-Verwendung
                • Datenbank (MySQL)
                • TLS -> HTTPs

                usw.

                Diese Basis-App zum Uploaden von Informationen könnte dann als Basis für Weiterenticklungen herhalten. Eine Solide Doku mit Erklärungen und Nennung der kritischen Fragestellungen wäre aber wichtig. Der Hinweis auf GIT war deshalb schon gut.

                Glück Auf
                Tom vom Berg

                --
                Es gibt soviel Sonne, nutzen wir sie.
                www.Solar-Harz.de
                S☼nnige Grüße aus dem Oberharz
              2. Hallo

                Für die ausführlichen Ausführungen erst einmal ein + von mir. Aber nichts ist ohne aber.

                • Den alten Kram in die Tonne kloppen und statt dessen konsequent mit Unicode arbeiten. Darauf gehe ich im Anschluss ein - das ist zwar die beste Alternative, bei existierenden Projekten aber einiges an Arbeit.

                Trotz des damit verbundenen Aufwands – und der ist, wie du schon schreibst, erheblich – ist das die einzig zioelführende und zukunftsweisende Option.

                Wichtig ist dann auch, dass deine DB-Verbindung und deine Datenbank-Collation auf ISO-8859-15 eingestellt sind. Der MYSQL-Default ist schwedisch.

                Wenn der MySQL-Server nicht vor Urzeiten installiert/eingerichtet wurde, ist das nicht mehr richtig. Schon seit einigen Jahren (etwa 10?) begegnet mir in den Datenbanken neu eingerichteter Webspaces nur noch utf8 als Standardeinstellung, in den letzten paar Jahren nur noch utf8mb4. Wie gesagt, das gilt für in dieser Zeit neu eingerichtete Datenbanken.

                Auch auf selbst installierten MySQL- beziehungsweise MariaDB-Installationen sehe ich nur noch utf8mb4 als vorgegebene Standardeinstellung. Wenn Sven-Jochen seine Daten nicht auf einen Server sendet, dessen Datenbank vor mehr als 10 Jahren eingerichtet wurde, sollte die Standardkodierung mindestens utf8(mb3) sein. Davon unabhängig besteht noch die von dir weiter unten beschriebene Voraussetzung der Festsetzung der richtigen Kodierung der Verbindung.

                Besser ist natürlich UTF8, und zwar in der mb4-Variante. Auch da hat MYSQL den blöden Default "mb3", also UTF-8 Encoding mit maximal 3 Byte langen Codes, was beim Speichern eines Emojis zu einem SQL Fehler führt.

                Oh ja, das kann, wenn einem das nicht bewusst ist, bei der Fehlersuche zu Beinbrüchen führen.

                • Bei jedem Aufruf einer Stringfunktion in PHP dringend überlegen, ob man dafür nicht besser das mb_...-Gegenstück verwendet.

                Spätestens, wenn man die empfangenen Strings manipuliert oder in den Strings Zeichen zählt, ist das Pflicht.

                Tschö, Auge

                --
                „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
                1. Hello,

                  Wenn der MySQL-Server nicht vor Urzeiten installiert/eingerichtet wurde, ist das nicht mehr richtig. Schon seit einigen Jahren (etwa 10?) begegnet mir in den Datenbanken neu eingerichteter Webspaces nur noch utf8 als Standardeinstellung, in den letzten paar Jahren nur noch utf8mb4. Wie gesagt, das gilt für in dieser Zeit neu eingerichtete Datenbanken.

                  Und welche Datenbasis ist da Default?

                  • InnoDB
                  • MyISAM
                  • andere ?

                  Glück Auf
                  Tom vom Berg

                  --
                  Es gibt soviel Sonne, nutzen wir sie.
                  www.Solar-Harz.de
                  S☼nnige Grüße aus dem Oberharz
                  1. Hm. Dieser Kommentar in der bei mir vorliegenden Datei /etc/mariadb.conf.d/50-server.cnf ist wohl nicht ganz richtig:

                    #
                    # * Character sets
                    #
                    
                    # MySQL/MariaDB default is Latin1, but in Debian we rather default to the full
                    # utf8 4-byte character set. See also client.cnf
                    character-set-server  = utf8mb4
                    collation-server      = utf8mb4_general_ci
                    

                    denn (Zitate)

                    MySQL Server has a server character set and a server collation. By default, these are utf8mb4 and utf8mb4_0900_ai_ci , but they can be set explicitly at server startup on the command line or in an option file and changed at runtime.

                    https://dev.mysql.com/doc/refman/8.0/en/charset-server.html

                    und

                    In MariaDB, the default character set is latin1, and the default collation is latin1_swedish_ci (however this may differ in some distros, see for example Differences in MariaDB in Debian).

                    https://mariadb.com/kb/en/character-set-and-collation-overview/

                    Und welche Datenbasis ist da Default?

                    Zitate:

                    InnoDB is a good general transaction storage engine, and, from MariaDB 10.2, the best choice in most cases. It is the default storage engine from MariaDB 10.2.

                    https://mariadb.com/kb/en/choosing-the-right-storage-engine/

                    und

                    The default engine is InnoDB in MySQL 8.0.

                    https://dev.mysql.com/doc/refman/8.0/en/storage-engine-setting.html

                    Was ich mich gerade frage: Google liefert diese Seiten an erster Stelle wenn man nach „mysql“ oder „mariadb“ und „character set“ bzw. „default engine“ sucht... Warum also spekulieren?

                    1. Hallo Raketenwilli,

                      Was ich mich gerade frage: Google liefert diese Seiten an erster Stelle...

                      Google ist individualisiert, solange Du das nicht intensiv bekämpfst.

                      D.h. was bei Dir an Stelle 1 steht, könnte bei Tom auf Seite 3 landen. Also oben ohne…

                      Rolf

                      --
                      sumpsi - posui - obstruxi
                      1. Hello,

                        Was ich mich gerade frage: Google liefert diese Seiten an erster Stelle...

                        Google ist individualisiert, solange Du das nicht intensiv bekämpfst.

                        D.h. was bei Dir an Stelle 1 steht, könnte bei Tom auf Seite 3 landen. Also oben ohne…

                        Wenn ich da 'was übersehen habe, bleiben erst recht Fragen:

                        • gegen wen kämpfen wir eigentlich? (Suchmaschinen, Desinformation, Filterblase, ...)
                        • wie weit zurück muss man das eigentliche Problem in der Historie der Problemkette eigentlich suchen?

                        Glück Auf
                        Tom vom Berg

                        --
                        Es gibt soviel Sonne, nutzen wir sie.
                        www.Solar-Harz.de
                        S☼nnige Grüße aus dem Oberharz