javascriptnewbie: PHP array an javascript function übergeben

0 48

PHP array an javascript function übergeben

javascriptnewbie
  • javascript
  1. 0
    dedlfix
  2. 0
    Der Martin
    1. 0
      molily
    2. 0
      javascriptnewbie
      1. 0
        M.
        1. 0

          Gute Idee

          Tom
          • menschelei
      2. 1
        ChrisB
        1. 0
          javascriptnewbie
          1. 0
            molily
            1. 0
              javascriptnewbie
              1. 0
                M.
              2. 6
                molily
      3. 0
        Tom
        1. 0
          javascriptnewbie
          1. 0
            Tom
            1. 0
              Sven Rautenberg
              1. 0

                Nicht nur meckern, zeigen! Escaping für JavaScript-Variablen

                Tom
                1. 0
                  molily
                  1. 0
                    tami
                    1. 0
                      molily
                      1. 0
                        tami
                  2. 0
                    Tom
                    1. 0
                      molily
              2. 0

                PHP json_encode - kontextspezifisches Escaping

                tami
                1. 0
                  tami
                  1. 0
                    molily
                    1. 0
                      Sven Rautenberg
                      1. 0
                        molily
                        1. 0
                          molily
                        2. 0

                          JSON in HTML einbetten

                          molily
                          1. 1

                            JSON in HTML einbetten - RoR "vs" ZF

                            tami
                            1. 0
                              tami
                              1. 0
                                Tom
                                1. 0
                                  molily
                            2. 0
                              molily
                              1. 0
                                tami
                                1. 0
                                  tami
                              2. 0

                                JSON-Paket mit composer vom Zend Framework holen

                                tami
                              3. 2

                                JSON in HTML einbetten

                                molily
                                • php
                          2. 0

                            Reihenfolge der Auswertung?

                            Tom
                            1. 0
                              tami
                            2. 0
                              tami
                            3. 0

                              Reihenfolge der Auswertung? Codierung, kleine Korrektur

                              Tom
                            4. 0
                              molily
                              1. 0
                                Tom
                                1. 0
                                  molily
                  2. 0
                    Tom

Hallo,

ich möchte ein php array an eine javascript funktion übergeben und in dieser mit dem array arbeiten.
bekomme aber immer undefined.

Hier wie es aussieht

<input type="radio" name="Settings" value=""  
					onclick=getformfunction('.$ergebnis.')></input>

dabei ist $ergebnis das array was wie folgt aussieht

  
Array  
(  
    [1] => Array  
        (  
            [W_Container_Type_Id] => 3  
            [W_Container_Id] => 17  
            [Container_Nr] => 1  
            [W_Container_Type_Name] => Aktiver Süßwasserbehälter  
        )  
  
    [2] => Array  
        (  
            [W_Container_Type_Id] => 3  
            [W_Container_Id] => 18  
            [Container_Nr] => 2  
            [W_Container_Type_Name] => Aktiver Süßwasserbehälter  
        )

dann kommt die javascript funktion

  
 <script type="text/javascript" language="javascript" >  
      function getformfunction(ergebnis)  
      {  
	var ArrayLaenge = ergebnis.length;  
	for (i=0; i< ArrayLaenge; i++)  
	{  
		document.write(ergebnis[i] + " ");  
	}  
</script>  

so wollte ich es erstmal testen
aber es kommt immer undefined

was mache ich da falsch?

Gruß Jürgen

  1. Tach!

    ich möchte ein php array an eine javascript funktion übergeben und in dieser mit dem array arbeiten.
    was mache ich da falsch?

    Es geht generell nicht, vom Browser aus auf Variablen in PHP zuzugreifen. Wenn der Browser arbeitet, ist PHP längst Geschichte. Es geht lediglich, die Werte in die Ausgabe einzubetten, in einer Form, wie sie der Browser lesen kann. Zum Beispiel formatiert als Json oder du schreibst direkt ein Javascript-Array und fügst die Werte ein. Beachte dabei aber den Kontextwechsel (da gibts einen Abschnitt zu Javascript in der Fortsetzung).

    dedlfix.

  2. Hi,

    ich möchte ein php array an eine javascript funktion übergeben und in dieser mit dem array arbeiten.
    bekomme aber immer undefined.

    ist dir klar, wie PHP und Javascript zusammenspielen - nämlich eigentlich gar nicht?
    Erst wird PHP auf dem Server ausgeführt, erzeugt ein HTML-Dokument und sendet es an den Client (Browser). Dann erst kommt der Browser und fängt an, HTML zu interpretieren und Javascript auszuführen.

    <input type="radio" name="Settings" value=""

      			onclick=getformfunction('.$ergebnis.')></input>
    
      
    Schau dir den Quellcode an, der im Browser ankommt. Ich vermute, dass der obige Schnipsel mit echo ausgegeben wird. Aber was gibt echo tatsächlich aus, wenn man ihm ein Array anbietet? Genau, den String "Array". Letztendlich steht in deinem Browser-Quellcode also `getformfunction(Array)`{:.language-javascript}. Javascript interpretiert das so, dass der Funktion als Parameter eine Variable mit dem Namen "Array" übergeben werden soll - diese Variable gibt es nicht, daher 'undefined'.  
      
    
    > ~~~javascript
    
     <script type="text/javascript" language="javascript" >  
    
    >       function getformfunction(ergebnis)  
    >       {  
    > 	var ArrayLaenge = ergebnis.length;  
    > 	for (i=0; i< ArrayLaenge; i++)  
    > 	{  
    > 		document.write(ergebnis[i] + " ");  
    > 	}  
    > </script>
    
    

    In dieser Funktion steckt ein weiteres Problem: Du darfst document.write() nach dem Laden und Rendern des Dokuments nicht mehr benutzen, weil es dann das komplette Dokument löschen und neu anfangen würde.

    was mache ich da falsch?

    Einiges. ;-)
    Bitte mach dir erstmal klar, welche Aktionen hier genau ablaufen sollen, und beschreibe diese Abläufe in Klartext (also ohne Programmcode). Und dann kann man überlegen, wie man das tatsächlich realisieren könnte. Mit dem bisherigen Ansatz geht's offensichtlich nicht.

    So long,
     Martin

    --
    Computer funktionieren grundsätzlich nicht richtig.
    Wenn doch, hast du etwas falsch gemacht.
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Hallo,

      Randnotiz:

      Javascript interpretiert das so, dass der Funktion als Parameter eine Variable mit dem Namen "Array" übergeben werden soll - diese Variable gibt es nicht, daher 'undefined'.

      Natürlich gibt es http://de.selfhtml.org/javascript/objekte/array.htm@title=Array, es ist die Array-Konstruktorfunktion.

      Mathias

    2. Einiges. ;-)
      Bitte mach dir erstmal klar, welche Aktionen hier genau ablaufen sollen, und beschreibe diese Abläufe in Klartext (also ohne Programmcode). Und dann kann man überlegen, wie man das tatsächlich realisieren könnte. Mit dem bisherigen Ansatz geht's offensichtlich nicht.

      So long,
      Martin

      Hallo,

      ja
      das PHP zuerst auf dem Server läuft und Javascript ist mir klar
      so dachte ich ich hole mir alles was ich später im javascript benötige zuerst durch PHP, packe dies in ein array, übergebe dies dann im PHP-code an die onclick-variable $ergebnis

      wenn es mit dem Array nicht geht wie kann ich dann werte an Javascript übergeben die ich mir zuvor durch php geholt habe?

      also mit einem array was in php konstruiert wurde geht es also nicht.

      kann ich dann aus dem PHP-array einen string basteln, meinetwegen mit "," als Trennzeichen und diesen string übergebe ich dann an javascript und dort zerpflücke ich ihn wieder?

      gibt es dazu ein Beispiel wenn es so gehen sollte?

      Gruß Jürgen

      1. Mahlzeit,

        das PHP zuerst auf dem Server läuft und Javascript ist mir klar
        so dachte ich ich hole mir alles was ich später im javascript benötige zuerst durch PHP, packe dies in ein array, übergebe dies dann im PHP-code an die onclick-variable $ergebnis

        Das tust du ja nicht. ein "echo $ergebnis" gibt ja auch nicht das aus, was du erwartest, oder?

        wenn es mit dem Array nicht geht wie kann ich dann werte an Javascript übergeben die ich mir zuvor durch php geholt habe?

        Klar geht es, du musst es nur richtig machen.
        Du iterierst durch das Array und erzeugst den Code, der in JS auch eins erzeugt.

        also mit einem array was in php konstruiert wurde geht es also nicht.

        Wieso sollte es nicht?

        kann ich dann aus dem PHP-array einen string basteln, meinetwegen mit "," als Trennzeichen und diesen string übergebe ich dann an javascript und dort zerpflücke ich ihn wieder?

        Klar, du kannst es auch auf Lochkarte stanzen und diese dem Seitenbesucher per Drohne zustellen lassen.

        --
        42
        1. Hello,

          Klar, du kannst es auch auf Lochkarte stanzen und diese dem Seitenbesucher per Drohne zustellen lassen.

          Mensch Bayer, Das ist eine gute Idee!

          Da brauche ich ja nur noch einen ganz flachen Briefschlitz und kann endlich meine alte Hollerith nochmal aus dem Keller holen.

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          Die ultimative Seite für Selbermacher
      2. Hi,

        kann ich dann aus dem PHP-array einen string basteln, meinetwegen mit "," als Trennzeichen und diesen string übergebe ich dann an javascript und dort zerpflücke ich ihn wieder?

        Könntest du, ist aber fehleranfällig.

        Nutze JSON stattdessen. PHP hat die Funktion json_encode dafür.

        MfG ChrisB

        --
        Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
        1. Hi,

          kann ich dann aus dem PHP-array einen string basteln, meinetwegen mit "," als Trennzeichen und diesen string übergebe ich dann an javascript und dort zerpflücke ich ihn wieder?

          Könntest du, ist aber fehleranfällig.

          Nutze JSON stattdessen. PHP hat die Funktion json_encode dafür.

          MfG ChrisB

          hallo,

          ok Danke.
          Ich hatte mir das mit dem JSON total kompliziert vorgestellt... dachte ich müsste eine halbe neue Programmiersprache neu lernen... sorry hatte da schon die Panik bekommen.

          Trotzdem noch eine Frage

          Ich habe das so verstanden
          mit $dassollanjavasuebegbenewerden = json_encode($meinphparray);
          schreibe ich also mein phparray in den string den ich dann so an javascript übergeben kann
          ist das richtig?

          auf javascriptseite also in der javascriptfunktion in der ich dann diesen string bekomme, wie zerpflücke ich diesen dort... gibts dafür auch eine Gegenstück für javascript?
          habe beim Googeln noch nicht die richtige Seite gefunden

          Gruß Jürgen

          1. Hallo,

            das Gegenstück zum Parsen von JSON in JavaScript ist JSON.parse().

            Mathias

            1. Hallo,

              das Gegenstück zum Parsen von JSON in JavaScript ist JSON.parse().

              Mathias

              Hallo,

              danke für den Hinweis...

              ich habe jetzt jedoch das Problem das wenn ich mit $varibaleanjavascript = json_encode($dassitmeinarray);
              meine javascript taugliche Übergabe erzeugen will, dass mir dann der string der durch json_encode erzeugt wird, kommas enthält.

              Wenn ich jetzt dann die javascript funktion mit

              onclick=dasistdiejavascriptfunction($varibaleanjavascript, $variable2, $variable3)

              die variablen übergeben will knallt es mir alles zusammen da ich dann keine saubere Trennung mehr habe.

              Muss ich das dann irgendwie pharsen oder kann ich die json-trennzeichen (anstatt kommas z.b. zwei --) ändern?

              Gruß Jürgen

              1. Mahlzeit,

                Muss ich das dann irgendwie pharsen oder kann ich die json-trennzeichen (anstatt kommas z.b. zwei --) ändern?

                Ein String gehört grundsätzlich in Anführungszeichen. Das dürfte so ziemlich das Erste sein, was man bei einer Programmiersprache lernt.

                --
                42
              2. Hallo,

                ich habe jetzt jedoch das Problem das… der string der durch json_encode erzeugt wird, kommas enthält.

                Ich fürchte, solange du dir einige Grundlagen nicht aneignest, wird es immer wieder »knallen« in deinem Code.

                Du wurdest schon mehrfach darauf hingewiesen, dich in die Grundlagen eines Kontextwechsel einzulesen und dir jeweils den generierten HTML-Code anzusehen. Wenn ich mich recht entsinne, ist das schon der zweite oder dritte Thread von dir zum Thema, und wir sind noch keinen nennenswerten Schritt voran gekommen.

                Die Leute hier würden nicht so darauf herumreiten, wenn dieses Verständnis nicht essentiell wichtig für die Webprogrammierung wäre. Es kann zu schwerwiegenden Programmfehlern und Sicherheitslücken führen, wenn diese Grundlagen nicht beachtet werden. Es kann gefährlich werden, wenn du PHP und JavaScript ohne diese Kenntnisse programmierst.

                onclick=dasistdiejavascriptfunction($varibaleanjavascript, $variable2, $variable3)

                Das ist problematisch und wird nicht funktionieren, klar, weil du den Kontextwechsel nicht beachtet hast.

                Erst einmal solltest du dich mit den Grundlagen beschäftigen, dazu gibt es im SELFHTML-Wiki einen Artikel, der dir auch schon mehrfach gezeigt wurde:

                http://wiki.selfhtml.org/wiki/Artikel:Kontextwechsel

                Du musst dir im Klaren sein, dass du hier verschiedene Sprachen verschachtelst (PHP, HTML, JavaScript) und jede Sprache in sich noch einmal aus Teilen besteht (u.a. PHP-Strings, HTML-Attribute, JavaScript-Strings). Immer wenn du gewisse Zeichenketten in eine Sprache einbettest, musst du sie kontextgerecht MASKIEREN.

                HTML besteht z.B. aus Tags und Attributen. Je nachdem, an welcher Stelle du mit PHP HTML-Code generierst, musst du entsprechende Maskierungen vornehmen, damit der Inhalt »sicher« in die Sprache HTML überführt wird und selbst nicht als HTML verarbeitet wird (bzw. nur soweit du es willst).

                Du willst hier JavaScript-Code (das ist JSON letztlich) in ein Attribut einfügen. Dieses Attribut ist ein Event-Handler, sein Inhalt wird also als JavaScript verarbeitet.

                Erst einmal der HTML-Code:

                <button title="">Button</button>

                Attributwerte in HTML werden mit " oder ' begrenzt. Diese Begrenzer dürfen schon einmal nicht unmaskiert im Attributwert vorkommen, sonst wird der Attributwert beendet. Beispiel (fehlerhafter Code!):

                <button title="Sie fragte: "Wo geht’s hier zum Bahnhof?"">Button</button>

                Das title-Attribut hat den Wert »Sie fragte: «, danach versucht der fehlertolerante HTML-Parser aus den restlichen Worten neue Attribute zu bauen. Es kommt ungefähr dieser Quatsch hier heraus:

                <button title="Sie fragte: " wo="" geht’s="" hier="" zum="" bahnhof?""="">Button</button>

                Wenn die Begrenzer im Attributwert vorkommen sollen, müssen sie maskiert werden. D.h. sie werden durch harmlose Zeichen ersetzt, die vom Browser wieder zurückübersetzt werden. In HTML ist das durch http://de.selfhtml.org/html/referenz/zeichen.htm@title=Zeichenreferenzen möglich. Beispiel:

                ' wird durch &apos; ersetzt
                " wird durch &quot; ersetzt

                (gibt noch weitere Möglichkeiten, die ich hier einmal verschweige)

                Anwendung:

                <button title="Sie fragte: &quot;Wo geht’s hier zum Bahnhof?&quot;">Button</button>

                Wenn du HTML-Code in PHP generierst, dann kannst du diese Ersetzung mithilfe einer Funktion vornehmen:

                http://php.net//manual/de/function.htmlspecialchars.php

                Falls dir diese Funktion noch nicht in Fleisch und Blut übergegangen ist, solltest du dir vielleicht noch einmal ein PHP-Grundlagenbuch zu Gemüte führen. Es ist eine der wichtigsten Funktionen in PHP (zumindest wenn mit PHP direkt HTML generiert wird).

                Anwendungsbeispiel:

                <?php  
                [code lang=php]$title = 'Sie fragte: "Wo geht’s hier zum Bahnhof?"';  
                $masked_title = htmlspecialchars($title);  
                
                ~~~?>  
                <button title="<?php echo $masked\_title ?>">Button</button>[/code]  
                  
                HTML-Ausgabe:  
                  
                `<button title="Sie fragte: &quot;Wo geht’s hier zum Bahnhof?&quot;">Button</button>`{:.language-html}  
                  
                Das Einbetten von JavaScript in HTML-Attribute funktioniert ähnlich.  
                  
                ~~~html
                <?php  
                [code lang=php]// PHP-Array, der ans JavaScript weitergegeben wird  
                $array = array("kleiner Bär", "kleiner Tiger", "Tigerente", "\"Quatsch\", 'mit Soße'");  
                // In einen JSON-String umwandeln (das ist gültiger JavaScript-Code)  
                $json = json_encode($array);  
                // Dann HTML-maskieren, da es in den Kontext eines HTML-Attributs eingebettet wird  
                $masked_json = htmlspecialchars($json);  
                
                ~~~?>  
                <script>  
                ~~~javascript
                // JavaScript-Funktion, den den Array entgegen nimmt  
                function output (array) {  
                  alert(array[0]);  
                }  
                
                ~~~</script>  
                <button onclick="output(<?php `echo $masked_json`{:.language-php} ?>)">Button</button>[/code]  
                  
                Das generierte HTML:  
                  
                `<button onclick="output([&quot;kleiner B\u00e4r&quot;,&quot;kleiner Tiger&quot;,&quot;Tigerente&quot;,&quot;\&quot;Quatsch\&quot;, 'mit So\u00dfe'&quot;])">Button</button>>`{:.language-html}  
                  
                Sieht wirr aus, ist aber nötig, weil hier mehrere Sprachen verschachtelt sind und mehrere Maskierungen nötig sind.  
                  
                
                > Muss ich das dann irgendwie pharsen  
                  
                »Pharsen« gibt es nicht, es gibt »parsen«, das [bedeutet aber etwas anderes](http://de.wikipedia.org/wiki/Parser).  
                  
                
                > oder kann ich die json-trennzeichen (anstatt kommas z.b. zwei --) ändern?  
                  
                JSON ist immer gleich aufgebaut und nutzt immer dieselben Trennzeichen, das ist der Vorteil von JSON.  
                  
                Um solchen Privatunterricht zu PHP-Grundlagen zu vermeiden, gibt es unzählige Fachartikel und Bücher zum Thema, die du bitte lesen mögest.  
                  
                Grüße  
                Mathias
                
                -- 
                [Chaplin.js - JavaScript application architecture on top of Backbone.js](http://chaplinjs.org/)
                
      3. Hello Jürgen,

        interessante Ideen bekommt man auch beim Lesen von
        http://www.mediaevent.de/javascript/array-assoziativ.html

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        Die ultimative Seite für Selbermacher
        1. Hello Jürgen,

          interessante Ideen bekommt man auch beim Lesen von
          http://www.mediaevent.de/javascript/array-assoziativ.html

          Hallo diese Beispiele kenne ich zum Teil
          das sind aber Varianten wie man arrays in Javascript erzeugt
          das brauch ich ja gar nicht.

          Ich wollte wissen wie man eine PHP-Array an javascript übergibt

          was ich hier bis jetzt gelesen habe soll es mit einer Json Methode gehen und/oder wenn ich das PHP-Array zuvor serverseitig in einen String zusammenpacke und diesen an javascript später übergebe und dort dann wieder zerlege was auch für mich nachvollziehbar Fehleranfällig und eher die unsaubere Methode wäre.

          Shit .. jetzt muss ich wohl oder übel mir doch dieses Json-Zeugs reinziehen:(

          wenn jemand eine gute Besipielseite dazu hat evtl. sogar mit arrays was ich eben brauche dann wäre das super

          Danke!

          Gruß Jürgen

          1. Hello Jürgen,

            interessante Ideen bekommt man auch beim Lesen von
            http://www.mediaevent.de/javascript/array-assoziativ.html

            Hallo diese Beispiele kenne ich zum Teil
            das sind aber Varianten wie man arrays in Javascript erzeugt
            das brauch ich ja gar nicht.

            Ich wollte wissen wie man eine PHP-Array an javascript übergibt

            Indem man sich für eine der oben beschriebenen Varianten entscheidet und dann mittels PHP den passenden JavaScript-Text aus dem PHP-Array generiert.

            Du kannst das auch als aktive Komponente bauen in PHP und dann mit dem passenden Header an JavaScript übergeben, bzw. das HTML-Dolument muss es als JavaScript-Datei einbinden. Das wäre dann aber ggf. global.

            Beispiel: ein Array "buecher" aus $_SESSION an JavaScript übergeben

              
              
            <?php ### fill_array.php ### utf-8 ### ÄÖÜäöü  
              
            session_start();  
            $_SESSION['buecher'][]='Haus der Finsternis';  
            $_SESSION['buecher'][]='Programmieren mit PHP';  
            $_SESSION['buecher'][]='Geldwäsche ohne Waschmaschine';  
              
            ?>  
              
            <?php ### buecher.js.php ###  
                header('Content-Type: Text/Javascript; Charset=utf-8');  
                session_start();  
                echo 'var buecher = new Array("' . implode('","', $_SESSION['buecher']) .'");' . PHP_EOL;  
            ?>  
              
            
            

            und dann das Array im HTML-Kontext laden:

              
              
            <html>  
            <head>  
                <meta Charset="utf-8">  
            	<title>Array an JavaScript übergeben</title>  
            </head>  
            <body>  
              
            <script type="text/javascript" src="buecher.js.php"></script>  
              
            <script type="text/javascript">  
            var key;  
            for (key in buecher)  
            {  
                alert("Schlüssel " + key + " mit Wert " + buecher[key]);  
            }  
              
            </script>  
              
            </body>  
            </html>  
            
            

            Ich habe es ausprobiert und es klappt.
            Wie man jetzt das Array lokal in eine Funktion reinladen könnte, müsstest Du mal selber ausprobieren.

            Natürlich kannst Du den Umweg über das Hinzuladen der JavaScript-Ressource auch weglassen. War nur mal ein Spielchen zum Woechenendeabend :-)

            Shit .. jetzt muss ich wohl oder übel mir doch dieses Json-Zeugs reinziehen:(

            Nee, musst Du nicht.

            Hast Du ein "assoziatives Array" oder ein "echtes" JavsScript-Array, also nur indiziert?

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            Die ultimative Seite für Selbermacher
            1. Moin!

              <?php ### buecher.js.php ###
                  header('Content-Type: Text/Javascript; Charset=utf-8');
                  session_start();
                  echo 'var buecher = new Array("' . implode('","', $_SESSION['buecher']) .'");' . PHP_EOL;
              ?>

              In dem Code ist keinerlei kontextgerechtes Escaping drin! Er ist gefährlich! Bitte nicht benutzen!

              - Sven Rautenberg

              1. Hello,

                <?php ### buecher.js.php ###
                    header('Content-Type: Text/Javascript; Charset=utf-8');
                    session_start();
                    echo 'var buecher = new Array("' . implode('","', $_SESSION['buecher']) .'");' . PHP_EOL;
                ?>

                In dem Code ist keinerlei kontextgerechtes Escaping drin! Er ist gefährlich! Bitte nicht benutzen!

                Bitte nicht nur meckern, sondern zeigen, wie es geht!
                Du müsstest dafür nur über eine halbe Zeile diskutieren.

                Hier ging es erstmal nur um das Verfahren. Das Escaping notwendig ist, hat dedlfix schon ziemlich am Anfang geschrieben.

                Was müssen wir also escapen? Das zu diskutieren, wäre doch wünschenswert!
                Denn hier ist ein "htmlspecialchars()" fehl am Platze, obwohl die Daten auch indirekt in den HTML-Kontext gestellt werden.

                Ein Beispiel, warum und wie das notwendig sein könnte, hat Mathias gezeigt:
                https://forum.selfhtml.org/?t=217757&m=1496841

                Das trifft aber nicht alles auf die Variablen und die Bezichner (Keys) in diesem Besipiel zu.

                Also escapen oder verhindern:

                • Quotations

                • Ecapezeichen (Backslashes)

                • etliche nicht druckbare Zeichen (Steuerzeichen)

                • geschweifte Klammern (?)

                • Werte quotieren (!)

                • Bezeichner quotieren (?)

                • und was noch alles?

                Welche Zeichen sind in JavaScript-Bezeichnern zulässig?

                Da es hier um die Erzeugung von Arrays bzw. Objekten geht, beträfe dies die Elementbezeichner. Der Variablenbezeichner wird vom Programmierer vorgegeben.

                Außerdem muss vor dem Zugriff auf das Subarray im $_SESSIONS-Array sel

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                Die ultimative Seite für Selbermacher
                1. Hallo,

                  echo 'var buecher = new Array("' . implode('","', $_SESSION['buecher']) .'");' . PHP_EOL;

                  Bitte nicht nur meckern, sondern zeigen, wie es geht!

                  Die saubere Lösung hatte ChrisB schon aufgezeigt, sie lautet JSON.

                  Was müssen wir also escapen? Das zu diskutieren, wäre doch wünschenswert!

                  Das kommt auf den Kontext an. Hier ist der Kontext ein JavaScript-String.

                  In einem JavaScript-String sind die Stringbegrenzer (" bzw. ') sowie Escape-Sequenzen problematisch (\n, \u1234, \123, \x12, \ vor einem Zeilenumbruch…).

                  Also escapen oder verhindern:

                  • Quotations

                  • Ecapezeichen (Backslashes)

                  • etliche nicht druckbare Zeichen (Steuerzeichen)

                  • geschweifte Klammern (?)

                  • Werte quotieren (!)

                  • Bezeichner quotieren (?)

                  Das hier alles zu diskutieren ist müßig, weil man es nicht händisch tun muss und auch nicht tun sollte. Beliebige Usereingaben oder Sessiondaten sollte man gar nicht in JavaScript als JavaScript schreiben.

                  Wenn man sie in HTML einbindet, dann JSON-kodiert in ein Attribut oder in einem unsichtbaren Element, natürlich HTML-kodiert. Am besten vorher mit einem einschlägigen HTML-Sanitizer behandeln.

                  In einem externen JavaScript sollte man sie nicht unterbringen, denn das kann einfach von einer anderen Site eingebunden werden – und schon sind die Sessiondaten gestohlen. (Gut, man könnte das mit einem POST und einem CSRF-Token absichern, aber wozu der Aufwand.)

                  Welche Zeichen sind in JavaScript-Bezeichnern zulässig?

                  http://es5.github.io/#x7.6

                  Aber ich sehe nicht, was das mit dem Beispielcode zu tun hat.

                  Da es hier um die Erzeugung von Arrays bzw. Objekten geht, beträfe dies die Elementbezeichner.

                  Was sind Elementbezeichner? Du meinst Eigenschaftsnamen bei Objekten?

                  Mir scheint, du verkomplizierst die Sache. Das ist bei sicherheitskritischen Fragen immer gefährlich.

                  Mathias

                  1. hi molily,

                    Hallo,

                    echo 'var buecher = new Array("' . implode('","', $_SESSION['buecher']) .'");' . PHP_EOL;

                    Bitte nicht nur meckern, sondern zeigen, wie es geht!

                    Die saubere Lösung hatte ChrisB schon aufgezeigt, sie lautet JSON.

                    Was müssen wir also escapen? Das zu diskutieren, wäre doch wünschenswert!

                    Das kommt auf den Kontext an. Hier ist der Kontext ein JavaScript-String.

                    Was ist mit: "Escaping Javascript

                    Javascript string literals in HTML are subject to significant restrictions particularly due to the potential for unquoted attributes and any uncertainty as to whether Javascript will be viewed as being CDATA or PCDATA by the browser. To eliminate any possible XSS vulnerabilities, Javascript escaping for HTML extends the escaping rules of both ECMAScript and JSON to include any potentially dangerous character. Very similar to HTML attribute value escaping, this means escaping everything except basic alphanumeric characters and the comma, period and underscore characters as hexadecimal or unicode escapes.

                    Javascript escaping applies to all literal strings and digits. It is not possible to safely escape other Javascript markup.

                    To escape data in the Javascript context, use Zend\Escaper\Escaper‘s escapeJs method. An extended set of characters are escaped beyond ECMAScript’s rules for Javascript literal string escaping in order to prevent misinterpretation of Javascript as HTML leading to the injection of special characters and entities."?

                    http://framework.zend.com/manual/2.1/en/modules/zend.escaper.escaping-javascript.html bzw. https://forum.selfhtml.org/?t=217757&m=1496870

                    mfg

                    tami

                    1. Javascript string literals in HTML are subject to significant restrictions particularly due to the potential for unquoted attributes and any uncertainty as to whether Javascript will be viewed as being CDATA or PCDATA by the browser.

                      Diese »uncertainty« gibt es nicht, solange man HTML 4 oder HTML 5 schreibt. In HTML 4 ist script CDATA und in HTML 5 ist es ähnlich definiert.

                      Es lässt sich nur schwer Code schreiben, der in HTML und XML sicher ist, weil eben die Parsing-Regeln anders sind. Ich würde es gar nicht erst versuchen.

                      Problematisch ist eher, dass nicht alle existierenden Browser die neuen HTML5-Parsingregeln umsetzen, man also mit vielen weiteren Interpretationen rechnen muss. Insbesondere ältere IEs sind hier betroffen. Da jeder aktuelle IE per Meta-Tag in den Kompatibilitätsmodus versetzt werden kann und damit die Fehler eines beliebigen alten IEs simuliert, ist selbst jeder IE 11 entsprechend angreifbar.

                      Zu XSS generell empfehle ich die Paper und Präsentationen von Mario Heiderich:
                      https://cure53.de/#publications

                      Mathias

                      1. hi molily,

                        Problematisch ist eher, dass nicht alle existierenden Browser die neuen HTML5-Parsingregeln umsetzen, man also mit vielen weiteren Interpretationen rechnen muss. Insbesondere ältere IEs sind hier betroffen. Da jeder aktuelle IE per Meta-Tag in den Kompatibilitätsmodus versetzt werden kann und damit die Fehler eines beliebigen alten IEs simuliert, ist selbst jeder IE 11 entsprechend angreifbar.

                        s.a. https://gist.github.com/padraic/3066656:

                        "The following is a sample implementation in PHP from Zend Framework 2.0: https://github.com/zendframework/zf2/raw/master/library/Zend/Escaper/Escaper.php

                        Symfony's Twig also recently added similar escaping options: https://github.com/fabpot/Twig/raw/master/lib/Twig/Extension/Core.php"

                        mfg

                        tami

                  2. Hello,

                    Was müssen wir also escapen? Das zu diskutieren, wäre doch wünschenswert!

                    Das kommt auf den Kontext an. Hier ist der Kontext ein JavaScript-String.

                    In einem JavaScript-String sind die Stringbegrenzer (" bzw. ') sowie Escape-Sequenzen problematisch (\n, \u1234, \123, \x12, \ vor einem Zeilenumbruch…).

                    Aua, ja die habe ich auf jeden Fall vergessen.

                    Also escapen oder verhindern:

                    • Quotations

                    • Ecapezeichen (Backslashes)

                    • etliche nicht druckbare Zeichen (Steuerzeichen)

                    • geschweifte Klammern (?)

                    • Werte quotieren (!)

                    • Bezeichner quotieren (?)

                    Das hier alles zu diskutieren ist müßig, weil man es nicht händisch tun muss und auch nicht tun sollte. Beliebige Usereingaben oder Sessiondaten sollte man gar nicht in JavaScript als JavaScript schreiben.

                    Es ist aber hilfreich, zumindestmal eine Checkliste zusammengestellt zu haben. JavaScript-Escaping ist mMn um einiges kompliziertere, als HTML-Escaping.

                    In einem externen JavaScript sollte man sie nicht unterbringen, denn das kann einfach von einer anderen Site eingebunden werden – und schon sind die Sessiondaten gestohlen. (Gut, man könnte das mit einem POST und einem CSRF-Token absichern, aber wozu der Aufwand.)

                    Man würde ja aber keine Daten einbinden, die nicht ohnehin öffentlich sind. Wenn ich die Daten im Beispiel aus der Session-Datei geholt habe, dann, weil das hier am einfachsten darzustellen war.

                    Welche Zeichen sind in JavaScript-Bezeichnern zulässig?

                    http://es5.github.io/#x7.6

                    Mir scheint, du verkomplizierst die Sache. Das ist bei sicherheitskritischen Fragen immer gefährlich.

                    Anders herum.

                    Ich versuche das Grundverständnis dafür wiederherzustellen, an welchen Stellen die Gefahrenpotentiale liegen. JavaScript sollte doch keine Geheimwissenschaft sein, insbesondere, wo wir es nun in Zukunft wohl alle einsetzen werden. Das Puzzlespiel wächst ja langsam zu einem Bild heran. Die halbfertigen Neuerungen (oder bisher nur mäßig benutzten) der letzten Zeit erreichen nahzu alle zusammen einen betriebsfertigen und omnipräsenten Zustand. Das ist heftig!

                    Multi-Byte-Kodierung
                    AJAX
                    HTML 5
                    Websockets

                    "Apps"
                    Positionsbestimmung
                    Ausbau der Mobilnezte

                    usw.

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    Die ultimative Seite für Selbermacher
                    1. Hallo,

                      In einem externen JavaScript sollte man sie nicht unterbringen, denn das kann einfach von einer anderen Site eingebunden werden – und schon sind die Sessiondaten gestohlen. (Gut, man könnte das mit einem POST und einem CSRF-Token absichern, aber wozu der Aufwand.)

                      Man würde ja aber keine Daten einbinden, die nicht ohnehin öffentlich sind.

                      Würde man nicht? Du hast es gedankenlos getan, andere schon vor dir. So sind z.B. Sicherheitslücken in GMail entstanden. Das Adressbuch wurde als externes JavaScript/JSON geladen. Mit ein paar Tricks konnte das eine fremde Site auslesen.

                      Es ist ferner wichtig zu verstehen, dass es verschiedene Arten von »öffentlich« im Web gibt:

                      1. Ressourcen, die von einem beliebigen HTTP-Client angefordert werden können (das sind alle).
                      2. Ressourcen, die im Browser von einer anderen Site aus per HTML/CSS/JS/SVG/… angefordert und ausgelesen werden können (das sind möglichst wenige).

                      Alle Ressourcen können durch Sessions, HTTP Basic Auth usw. personalisiert und abgesichert werden.

                      Bei letzteren Ressourcen besteht die Gefahr von Cross-Site Request Forgery (CSRF), da der Session-Cookie und andere Credentials mitgesendet werden.

                      HTML-Dateien sind durch die Same-Origin-Policy vor dem Auslesen durch fremde Sites im Browser geschützt. Es sei denn, der server erlaubt es explizit mittels CORS.

                      Scripte sind nicht derartig geschützt. Scripte können problemlos von anderen Servern eingebunden werden, werden dann im Kontext der aktuellen Seite ausgeführt. Das ist gleichzeitig ein Feature von JavaScript und eine Quelle unzähliger Sicherheitsprobleme.

                      Wenn ich die Daten im Beispiel aus der Session-Datei geholt habe, dann, weil das hier am einfachsten darzustellen war.

                      Ein sehr schlechtes Beispiel, das könnte jemand lesen und für bare Münze nehmen.

                      Ich versuche das Grundverständnis dafür wiederherzustellen, an welchen Stellen die Gefahrenpotentiale liegen.

                      Dann würde ich vorschlagen, erst einmal Recherche zu betreiben. Es gibt viele gute Artikel zum Thema, auch im Forumsarchiv gibt es viele entsprechende Diskussionen. Das unstrukturierte Fragen hier bringt m.E. wenig Erkenntnis.

                      Mathias

              2. hi Sven,

                Moin!

                <?php ### buecher.js.php ###
                    header('Content-Type: Text/Javascript; Charset=utf-8');
                    session_start();
                    echo 'var buecher = new Array("' . implode('","', $_SESSION['buecher']) .'");' . PHP_EOL;
                ?>

                In dem Code ist keinerlei kontextgerechtes Escaping drin! Er ist gefährlich! Bitte nicht benutzen!

                Wäre denn json_encode ausreichend?

                "

                <?php  
                $arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);  
                  
                echo json_encode($arr);  
                ?>
                

                The above example will output:

                {"a":1,"b":2,"c":3,"d":4,"e":5}

                http://php.net/manual/en/function.json-encode.php.

                Ggfs. auch: http://stackoverflow.com/questions/12062146/is-json-encode-sufficient-xss-protection.

                mfg

                tami

                1. hi tami,

                  hi Sven,

                  Moin!

                  <?php ### buecher.js.php ###
                      header('Content-Type: Text/Javascript; Charset=utf-8');
                      session_start();
                      echo 'var buecher = new Array("' . implode('","', $_SESSION['buecher']) .'");' . PHP_EOL;
                  ?>

                  In dem Code ist keinerlei kontextgerechtes Escaping drin! Er ist gefährlich! Bitte nicht benutzen!

                  Wäre denn json_encode ausreichend?

                  "

                  <?php

                  $arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);

                  echo json_encode($arr);
                  ?>

                  
                  >   
                  > The above example will output:  
                  >   
                  > {"a":1,"b":2,"c":3,"d":4,"e":5}  
                  >   
                  > [http://php.net/manual/en/function.json-encode.php](http://php.net/manual/en/function.json-encode.php).  
                  >   
                  > Ggfs. auch: [http://stackoverflow.com/questions/12062146/is-json-encode-sufficient-xss-protection](http://stackoverflow.com/questions/12062146/is-json-encode-sufficient-xss-protection).  
                    
                  Und <http://framework.zend.com/manual/2.1/en/modules/zend.escaper.escaping-javascript.html>  
                    
                  mfg  
                    
                  tami
                  
                  1. Hallo,

                    Und http://framework.zend.com/manual/2.1/en/modules/zend.escaper.escaping-javascript.html

                    Da steht aber ziemlicher Quatsch.

                    Das erste Beispiel ist kein XSS, zumindest nicht in neueren Browsern. Denn Zeichenreferenzen werden in script-Elementen nicht vom HTML5-Parser umgesetzt, sondern wörtlich an den JS-Interpreter weitergegeben. War auch so in HTML 4 definiert.

                    Die Sicherheitslücke wird wahrscheinlich erst dadurch geschaffen, dass das Dokument als XHTML ausgeliefert wird:

                    <?php header('Content-Type: application/xhtml+xml; charset=UTF-8'); ?>

                    Das sollte man tunlichst unterlassen! Schön bei text/html bleiben und den HTML5-Parser nutzen.

                    Es ist aber richtig, dass json_encode NICHT ausreicht für das Einbetten von Daten in ein script-Element. htmlspecialchars kann nämlich nicht angewandt werden, weil Zeichenreferenzen wie gesagt ignoriert werden.

                    In der JSON-Serialisierung kann </script><script>alert('XSS')</script> vorkommen, was das script-Element beendet und Code einschleust. Man müsste hier in JSON-strings </script> durch </script> ersetzen. Das ist aber sehr aufwändig und fehlerträchtig.

                    Soweit ich weiß (ich bin KEIN Sicherheitsexperte), bettet man JSON daher besser in Elemente oder Attribute ein, nicht in <script>…</script>. Dort kann nämlich normales HTML-Escaping angewandt werden.

                    Das zweite, vermeintlich sichere Beispiel auf der Zend-Seite verstehe ich nicht. Da wird syntaktisch fehlerhafter JavaScript-Code generiert. Was ist überhaupt das Ziel? Ein String an JavaScript zu übergeben geht viel einfacher. Da würde ich eher einen HTML-Sanitizer wie HTML Purifier verwenden.

                    Mathias

                    1. Moin!

                      Und http://framework.zend.com/manual/2.1/en/modules/zend.escaper.escaping-javascript.html

                      Da steht aber ziemlicher Quatsch.

                      Ein Framework-Escaper muss nicht nur funktionieren, wenn alles richtig gemacht wurde, sondern immer - auch wenn wissentlich oder unwissentlich Dinge falsch gemacht wurden, überdies auch, wenn angreifbare Browser ins Spiel kommen.

                      - Sven Rautenberg

                      1. Hallo,

                        Und http://framework.zend.com/manual/2.1/en/modules/zend.escaper.escaping-javascript.html

                        Ein Framework-Escaper muss nicht nur funktionieren, wenn alles richtig gemacht wurde, sondern immer - auch wenn wissentlich oder unwissentlich Dinge falsch gemacht wurden, überdies auch, wenn angreifbare Browser ins Spiel kommen.

                        Ja, das ist richtig. Aber wer eine Seite als application/xhtml+xml ausliefert, wird noch viele weitere Probleme bekommen, einige davon können sich zu Sicherheitslücken ausdehnen. Da ist das korrekte Escaping von generiertem JavaScript in script-Elementen noch das kleinere Problem. Es fängt schon dabei an, dass PHP Stringketten verknüpft, was eine denkbar schlechte Art und Weise ist, wohlgeformtes XML zu produzieren.

                        Es stört mich auch nicht, dass der Escaper XHTML berücksichtigt, sondern dass dieses Beispiel wie stillschweigend den XML-Parser anschaltet und es als üblichen Fehler darstellt. Das ist doch arg konstruiert. Verarbeitung als XML ist eher der Edge-Case und lenkt davon ab, dass das Einbetten von JSON in <script> bei text/html ebenfalls problematisch ist (s.a. mein anderes Posting).

                        Wie es aussieht, ist obige Seite veraltet und wurde durch eine Reihe von neuen Beispielen ersetzt. Da kommt XHTML gar nicht mehr vor:

                        http://framework.zend.com/manual/2.3/en/modules/zend.escaper.escaping-javascript.html

                        (Tami hatte an anderer Stelle schon auf die neue Version hingewiesen, glaube ich.)

                        Ich find das »Example of Good Javascript Escaping« immer noch verwirrend, denn es produziert nach wie vor einen Syntaxfehler (»In the above example, the Javascript parser will most likely report a SyntaxError, but at least the targeted application remains safe from such attacks.«).

                        Was soll die Aufgabenstellung sein? Ziel sollte doch sein, immer syntaktisch validen Code zu produzieren. Eine Seite durch Eingaben gezielt »kaputt« zu machen ist ein DoS-Angriff, der verhindert werden muss.

                        Ein besseres Beispiel wäre: Man will eine PHP-Objektstruktur an JavaScript übergeben.

                        <?php  
                        [code lang=php]$obj = new stdClass();  
                        $obj->foo = 'user-provided string, arbitrary data, e.g. $_GET["something"]';  
                        $json = json_encode($obj);  
                        $escaper = new Zend\Escaper\Escaper('utf-8');  
                        $output = $escaper->escapeJs($json);
                        

                        ?>
                        <script>
                        var obj = <?php echo $output ?>;
                        </script>[/code]

                        (Ungetestet, ich weiß nicht, ob das so herum überhaupt geht.)

                        Ziel ist hier, dass das immer funktioniert, keine Syntaxfehler erzeugt und sämtliche Eingaben ohne XSS sauber in ein JavaScript-Objekt überführt.

                        Mathias

                        1. <?php

                          [code lang=php]$obj = new stdClass();
                          $obj->foo = 'user-provided string, arbitrary data, e.g. $_GET["something"]';
                          $json = json_encode($obj);
                          $escaper = new Zend\Escaper\Escaper('utf-8');
                          $output = $escaper->escapeJs($json);

                          
                          > <script>  
                          > `var obj = <?php echo $output ?>;`{:.language-javascript}  
                          > </script>[/code]  
                          >   
                          > (Ungetestet, ich weiß nicht, ob das so herum überhaupt geht.)  
                            
                          Getestet, ist anscheinend »sicher«, aber erzeugt ebenfalls einen Syntaxfehler. Ausgabe:  
                            
                          `var obj = \x7B\x22foo\x22\x3A\x22user\x2Dprovided\x20string,\x20arbitrary\x20data,\x20e.g.\x20\x24_GET\x5B\x5C\x22something\x5C\x22\x5D\x22\x7D;`{:.language-javascript}  
                            
                          Das ist natürlich kein gültiges JavaScript. Wie denken sich die Zend-Leute das? Kann escapeJs für solche Fälle verwendet werden? Es kann nicht sein, dass ich die Werte \*vor\* der JSON-Serialisierung mit escapeJs behandle. Dann kommen gültige Wert verstümmelt im JavaScript an.  
                            
                          Ich wüsste hier keine Lösung. Daher wies ich darauf hin, JSON stattdessen [in ein Attribut oder Element](https://forum.selfhtml.org/?t=217757&m=1496873) auszugeben. Das scheint wohl Best Practice zu sein, siehe das [OWASP XSS Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.233.1_-_HTML_escape_JSON_values_in_an_HTML_context_and_read_the_data_with_JSON.parse).  
                            
                          Mathias
                          
                        2. Habe mal geschaut, wie Ruby on Rails das macht, ein vom Umfang her vergleichbares Webframework.

                          Rails 4 überschreibt die to_json-Methode von Hashes, sodass gefährliche Zeichen in Strings im JSON mit Unicode-Escape-Sequenzen kodiert werden.

                          Der Ruby-Hash
                          {foo: '</script><script>alert(/XSS/)</script>'}
                          wird durch to_json zum JSON
                          {"foo":"\u003C/script\u003E\u003Cscript\u003Ealert(/XSS/)\u003C/script\u003E"}

                          In Rails 3.x muss man das Verhalten explizit aktivieren mit:

                          ActiveSupport.escape_html_entities_in_json = true

                          Als Alternative gibt es in ERB (einer Templating-Sprache) eine Methode json_escape, die ähnlich vorgeht.

                          Mathias

                          1. hi molily,

                            Habe mal geschaut, wie Ruby on Rails das macht, ein vom Umfang her vergleichbares Webframework.

                            Rails 4 überschreibt die to_json-Methode von Hashes, sodass gefährliche Zeichen in Strings im JSON mit Unicode-Escape-Sequenzen kodiert werden.

                            Der Ruby-Hash
                            {foo: '</script><script>alert(/XSS/)</script>'}
                            wird durch to_json zum JSON
                            {"foo":"\u003C/script\u003E\u003Cscript\u003Ealert(/XSS/)\u003C/script\u003E"}

                            {"foo":"\u003C\/script\u003E\u003Cscript\u003Ealert(\/XSS\/)\u003C\/script\u003E"}

                            bringt mir:

                            <?php  
                            require_once 'Zend/Loader/StandardAutoloader.php';  
                            $loader = new Zend\Loader\StandardAutoloader(array('autoregister_zf' => true));  
                            $loader->register();  
                            class ToJason {  
                                public $foo = '</script><script>alert(/XSS/)</script>';  
                            }  
                            $phpNative = new ToJason;  
                            $json = Zend\Json\Json::encode($phpNative);  
                            var_dump($json);
                            

                            mfg

                            tami

                            1. hi tami,

                              hi molily,

                              Habe mal geschaut, wie Ruby on Rails das macht, ein vom Umfang her vergleichbares Webframework.

                              Rails 4 überschreibt die to_json-Methode von Hashes, sodass gefährliche Zeichen in Strings im JSON mit Unicode-Escape-Sequenzen kodiert werden.

                              Der Ruby-Hash
                              {foo: '</script><script>alert(/XSS/)</script>'}
                              wird durch to_json zum JSON
                              {"foo":"\u003C/script\u003E\u003Cscript\u003Ealert(/XSS/)\u003C/script\u003E"}

                              {"foo":"\u003C\/script\u003E\u003Cscript\u003Ealert(\/XSS\/)\u003C\/script\u003E"}

                              bringt mir:

                              <?php

                              require_once 'Zend/Loader/StandardAutoloader.php';
                              $loader = new Zend\Loader\StandardAutoloader(array('autoregister_zf' => true));
                              $loader->register();
                              class ToJason {
                                  public $foo = '</script><script>alert(/XSS/)</script>';
                              }
                              $phpNative = new ToJason;
                              $json = Zend\Json\Json::encode($phpNative);
                              var_dump($json);

                                
                              in der Encoder.php dann für Strings:  
                                
                              ~~~php
                                 /**  
                                   * JSON encode a string value by escaping characters as necessary  
                                   *  
                                   * @param string $string  
                                   * @return string  
                                   */  
                                  protected function _encodeString(&$string)  
                                  {  
                                      // Escape these characters with a backslash or unicode escape:  
                                      // " \ / \n \r \t \b \f  
                                      $search  = array('\\', "\n", "\t", "\r", "\b", "\f", '"', '\'', '&', '<', '>', '/');  
                                      $replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\\u0022', '\\u0027', '\\u0026',  '\\u003C', '\\u003E', '\\/');  
                                      $string  = str_replace($search, $replace, $string);  
                                
                                      // Escape certain ASCII characters:  
                                      // 0x08 => \b  
                                      // 0x0c => \f  
                                      $string = str_replace(array(chr(0x08), chr(0x0C)), array('\b', '\f'), $string);  
                                      $string = self::encodeUnicodeString($string);  
                                
                                      return '"' . $string . '"';  
                                  }
                              

                              mfg

                              tami

                              mfg

                              tami

                              1. Hello,

                                /**

                                * JSON encode a string value by escaping characters as necessary
                                     *
                                     * @param string $string
                                     * @return string
                                     */
                                    protected function _encodeString(&$string)
                                    {
                                        // Escape these characters with a backslash or unicode escape:
                                        // " \ / \n \r \t \b \f
                                        $search  = array('\', "\n", "\t", "\r", "\b", "\f", '"', ''', '&', '<', '>', '/');
                                        $replace = array('\\', '\n', '\t', '\r', '\b', '\f', '\u0022', '\u0027', '\u0026',  '\u003C', '\u003E', '\/');
                                        $string  = str_replace($search, $replace, $string);

                                // Escape certain ASCII characters:
                                        // 0x08 => \b
                                        // 0x0c => \f
                                        $string = str_replace(array(chr(0x08), chr(0x0C)), array('\b', '\f'), $string);
                                        $string = self::encodeUnicodeString($string);

                                return '"' . $string . '"';
                                    }

                                  
                                  
                                Da fehlt mMn mindestens NULL  
                                Und was ist mit 0xFF?  
                                Und dann würde ich im Replace-Array die Schreibweise einheitlich als Unicode-Entity wählen.  
                                Die übrigen Steuerzeichen zwischen 0x00 und 0x1F sollten mMn auch noch unterdrückt oder ersetzt werden.  
                                  
                                  
                                  
                                  
                                Liebe Grüße aus dem schönen Oberharz  
                                  
                                  
                                Tom vom Berg  
                                ![](http://selfhtml.bitworks.de/Virencheck.gif)  
                                  
                                
                                -- 
                                 ☻\_  
                                /▌  
                                / \ Nur selber lernen macht schlau  
                                [Die ultimative Seite für Selbermacher](http://getscript.de/)
                                
                                1. $string = self::encodeUnicodeString($string);

                                  Da fehlt mMn mindestens NULL
                                  Und was ist mit 0xFF?
                                  Und dann würde ich im Replace-Array die Schreibweise einheitlich als Unicode-Entity wählen.
                                  Die übrigen Steuerzeichen zwischen 0x00 und 0x1F sollten mMn auch noch unterdrückt oder ersetzt werden.

                                  Kurz und knapp: Schau dir die Implementierung von encodeUnicodeString an.

                                  Mathias

                            2. $json = Zend\Json\Json::encode($phpNative);

                              Guter Hinweis. Ich war bei meinen Recherchen darauf gestoßen, dass Zend einen eigenen JSON-Encoder bietet und hatte vermutet, dass der entsprechende Vorzüge gegenüber der eingebauten Low-Level-Funktion json_encode hat.

                              Übrigens ist der als separates Composer-Paket unter zendframework/zend-json verfügbar, der Zend Escaper unter zendframework/zend-escaper. Es spricht also nichts dagegen, sie in einem beliebigen PHP-Projekt einzusetzen. (Soweit ich das als PHP-Laie sagen kann.)

                              Mathias

                              1. hi molily,

                                $json = Zend\Json\Json::encode($phpNative);

                                Guter Hinweis. Ich war bei meinen Recherchen darauf gestoßen, dass Zend einen eigenen JSON-Encoder bietet und hatte vermutet, dass der entsprechende Vorzüge gegenüber der eingebauten Low-Level-Funktion json_encode hat.

                                Übrigens ist der als separates Composer-Paket unter zendframework/zend-json verfügbar, der Zend Escaper unter zendframework/zend-escaper. Es spricht also nichts dagegen, sie in einem beliebigen PHP-Projekt einzusetzen. (Soweit ich das als PHP-Laie sagen kann.)

                                So verstehe ich das Zend-Framework. Mag sein, dass du den autoloader und die Zend-Klasse noch brauchst. So war das bei PEAR aber auch, dass du die Pear.php noch brauchtest ...;

                                mfg

                                tami

                                1. hi tami,

                                  hi molily,

                                  $json = Zend\Json\Json::encode($phpNative);

                                  Guter Hinweis. Ich war bei meinen Recherchen darauf gestoßen, dass Zend einen eigenen JSON-Encoder bietet und hatte vermutet, dass der entsprechende Vorzüge gegenüber der eingebauten Low-Level-Funktion json_encode hat.

                                  Übrigens ist der als separates Composer-Paket unter zendframework/zend-json verfügbar, der Zend Escaper unter zendframework/zend-escaper. Es spricht also nichts dagegen, sie in einem beliebigen PHP-Projekt einzusetzen. (Soweit ich das als PHP-Laie sagen kann.)

                                  So verstehe ich das Zend-Framework. Mag sein, dass du den autoloader und die Zend-Klasse noch brauchst. So war das bei PEAR aber auch, dass du die Pear.php noch brauchtest ...;

                                  composer.json im Ordner Zend/Json:

                                  {  
                                      "name": "zendframework/zend-json",  
                                      "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP",  
                                      "license": "BSD-3-Clause",  
                                      "keywords": [  
                                          "zf2",  
                                          "json"  
                                      ],  
                                      "autoload": {  
                                          "psr-0": {  
                                              "Zend\\Json\\": ""  
                                          }  
                                      },  
                                      "target-dir": "Zend/Json",  
                                      "require": {  
                                          "php": ">=5.3.23",  
                                          "zendframework/zend-stdlib": "self.version"  
                                      },  
                                      "require-dev": {  
                                          "zendframework/zend-http": "self.version",  
                                          "zendframework/zend-server": "self.version"  
                                      },  
                                      "suggest": {  
                                          "zendframework/zend-http": "Zend\\Http component",  
                                          "zendframework/zend-server": "Zend\\Server component"  
                                      },  
                                      "extra": {  
                                          "branch-alias": {  
                                              "dev-master": "2.3-dev",  
                                              "dev-develop": "2.4-dev"  
                                          }  
                                      }  
                                  }  
                                  
                                  

                                  Was auch immer das _genau_ heißen mag.

                                  mfg

                                  tami

                              2. hi molily,

                                $json = Zend\Json\Json::encode($phpNative);

                                Guter Hinweis. Ich war bei meinen Recherchen darauf gestoßen, dass Zend einen eigenen JSON-Encoder bietet und hatte vermutet, dass der entsprechende Vorzüge gegenüber der eingebauten Low-Level-Funktion json_encode hat.

                                Übrigens ist der als separates Composer-Paket unter zendframework/zend-json verfügbar, der Zend Escaper unter zendframework/zend-escaper. Es spricht also nichts dagegen, sie in einem beliebigen PHP-Projekt einzusetzen. (Soweit ich das als PHP-Laie sagen kann.)

                                • PHP (neuere Version) runtergeladen von: http://windows.php.net/download/ (VC9 Threadsafe, für Windows) [weil composer 5.3+ erwartet]
                                • liegt jetzt in c:/php
                                • ggfs. noch die Umgebungsvariable PATH um diesen Pfad erweitern
                                • php.ini aus dem vorhandenen template erstellt (also php.ini-developer gespeichert unter php.ini) (im verzeichnis php) mit "extension_dir = "ext"" (weil da die extensions bei mir drinne sind, s. download oben) und "extension=php_openssl.dll" versehen (bzw. einkommentiert/auskommentiert wie das auch immer heißt), weil sonst der (vermutlich via php unnötige) download von composer.phar nicht funktioniert
                                • in c:/composer-test die composer.phar platziert, die ich mit "php -r "readfile('http://getcomposer.org/installer');" | php" heruntergladen hatte (lag dann in meinem User-Dir), kann man auch so runterladen, ist eine PHP-Archiv-Datei("PH"-"Ar")
                                • die composer.json angepasst (im verzeichnis c:/composer-test) zu:
                                {  
                                    "repositories": [  
                                    {  
                                        "type": "composer",  
                                        "url": "https://packages.zendframework.com/"  
                                    }  
                                    ],  
                                    "require": {  
                                        "zendframework/zend-json": "2.0.*"  
                                    }  
                                 }  
                                
                                ~~~ gemäß <http://framework.zend.com/downloads/composer>  
                                - dann: php composer.phar install ...  
                                D:\composer-test>php composer.phar install  
                                Loading composer repositories with package information  
                                Installing dependencies (including require-dev)  
                                  - Installing zendframework/zend-stdlib (2.0.8)  
                                    Downloading: 100%  
                                  
                                  - Installing zendframework/zend-json (2.0.8)  
                                    Downloading: 100%  
                                  
                                zendframework/zend-stdlib suggests installing pecl-weakref (Implementation of we  
                                ak references for Stdlib\CallbackHandler)  
                                zendframework/zend-json suggests installing zendframework/zend-server (Zend\Serv  
                                er component)  
                                Writing lock file  
                                Generating autoload files  
                                  
                                Im Verzeichnis ist jetzt das Verzeichnis "vendor" enstanden.  
                                  
                                Der Code (aus dem Verzeichnis, in dem der Ordner "vendor" liegt)  
                                ~~~php
                                <?php  
                                require_once "vendor/autoload.php";  
                                class ToJason {  
                                    public $foo = '</script><script>alert(/XSS/)</script>';  
                                }  
                                $phpNative = new ToJason;  
                                $json = Zend\Json\Json::encode($phpNative);  
                                var_dump($json);  
                                
                                

                                "funzt".

                                php -f "json_test.php"

                                string(82) "{"foo":"\u003C/script\u003E\u003Cscript\u003Ealert(/XSS/)\u003C/script\u003E"}"

                                Exit code: 0

                                mfg

                                tami

                              3. Ich war bei meinen Recherchen darauf gestoßen, dass Zend einen eigenen JSON-Encoder bietet und hatte vermutet, dass der entsprechende Vorzüge gegenüber der eingebauten Low-Level-Funktion json_encode hat.

                                Das ist so nicht richtig.

                                Ich habe mir den Code von Zend Framework 2.3.1 noch einmal angesehen. Da wird intern standardmäßig json_encode aufgerufen, sofern die statische Klassenvariable Zend\Json\Json::$useBuiltinEncoderDecoder nicht auf true gesetzt wird.

                                https://github.com/zendframework/zf2/blob/release-2.3.1/library/Zend/Json/Json.php#L40
                                https://github.com/zendframework/zf2/blob/release-2.3.1/library/Zend/Json/Json.php#L117-L125

                                Der Code für die manuelle Serialisierung von Strings, den tami gepostet hat, wird standardmäßig nicht aufgerufen. Ob das Zend Framework irgendwo $useBuiltinEncoderDecoder auf true setzt, weiß ich natürlich nicht.

                                Das führt mich dazu, dass das eingebaute json_encode das entsprechende Escaping vornimmt, wenn man denn nur die korrekten Options übergibt:

                                http://php.net/manual/en/function.json-encode.php
                                http://www.php.net/manual/en/json.constants.php

                                Zend macht hier letztlich nichts anderes als:

                                $encodedResult = json_encode(  
                                    $valueToEncode,  
                                    JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP  
                                );
                                

                                Der Zend-Json-Encoder macht noch mehr, aber wenn man nur diese Funktionalität will, braucht man die entsprechenden Module nun nicht einbinden.

                                Damit wäre das auch geklärt. :-)

                                Mathias

                          2. Hello,

                            {"foo":"\u003C/script\u003E\u003Cscript\u003Ealert(/XSS/)\u003C/script\u003E"}

                            Was ich noch nicht verstehe:
                            Warum codiert man dann für die Übertragung von X nach JavaScript nicht gleich alle nicht numerischen Ausgaben in Unicode. Das wird von HTML nicht interpretiert und JavaScript intgerpretiert es dann.

                            Was mir auch noch nicht klar ist, ist die Verarbeitungsreihenfolge.

                            1. HTML/JS-Dokument wird ausgeliefert.
                            2. HTML-Parser interpretiert das Markup
                            3. HTML-Parser ersetzt die Entities im HTML
                            4. HTML-Parser stürzt sich auf das JavaScript und übergibt es an den JS-Parser

                            Wann wird gerendert?

                            oder wie genau läuft das ab und/oder ist wie verschachtelt?

                            Die Reihenfolge hat doch einen gravierenden Einfluss auf die Escaping-Stategien.

                            Und noch eine Frage:
                            Ist es irgendwie schädlich oder falsch, wenn man Variablenwerte in JS immer in "" einschließt?

                            Liebe Grüße aus dem schönen Oberharz

                            Tom vom Berg

                            --
                             ☻_
                            /▌
                            / \ Nur selber lernen macht schlau
                            Die ultimative Seite für Selbermacher
                            1. hi Tom,

                              Und noch eine Frage:
                              Ist es irgendwie schädlich oder falsch, wenn man Variablenwerte in JS immer in "" einschließt?

                              http://wiki.selfhtml.org/wiki/JavaScript/JSON - es ist die definition (http://json.org/.

                              mfg

                              tami

                            2. hi Tom,

                              Hello,

                              {"foo":"\u003C/script\u003E\u003Cscript\u003Ealert(/XSS/)\u003C/script\u003E"}

                              Was ich noch nicht verstehe:
                              Warum codiert man dann für die Übertragung von X nach JavaScript nicht gleich alle nicht numerischen Ausgaben in Unicode. Das wird von HTML nicht interpretiert und JavaScript intgerpretiert es dann.

                              Offenbar reicht das hier: https://forum.selfhtml.org/?t=217757&m=1496934

                              mfg

                              tami

                            3. Hello,

                              {"foo":"\u003C/script\u003E\u003Cscript\u003Ealert(/XSS/)\u003C/script\u003E"}

                              Was ich noch nicht verstehe:
                              Warum codiert man dann für die Übertragung von X nach JavaScript nicht gleich alle nicht numerischen Ausgaben in Unicode.

                              Gemeint war hier die textuelle Angabe als "Unicode-Entitäten", also wie  \u0022
                              Es hat je keinen Sinn, wirklich Unicode auszugeben...

                              Ich habe aber in PHP noch keine Funktion dafür gefunden.

                              Das wird von HTML nicht interpretiert und JavaScript intgerpretiert es dann.

                              Was mir auch noch nicht klar ist, ist die Verarbeitungsreihenfolge.

                              1. HTML/JS-Dokument wird ausgeliefert.
                              2. HTML-Parser interpretiert das Markup
                              3. HTML-Parser ersetzt die Entities im HTML
                              4. HTML-Parser stürzt sich auf das JavaScript und übergibt es an den JS-Parser

                              Wann wird gerendert?

                              oder wie genau läuft das ab und/oder ist wie verschachtelt?

                              Die Reihenfolge hat doch einen gravierenden Einfluss auf die Escaping-Stategien.

                              Und noch eine Frage:
                              Ist es irgendwie schädlich oder falsch, wenn man Variablenwerte in JS immer in "" einschließt?

                              Liebe Grüße aus dem schönen Oberharz

                              Tom vom Berg

                              --
                               ☻_
                              /▌
                              / \ Nur selber lernen macht schlau
                              Die ultimative Seite für Selbermacher
                            4. {"foo":"\u003C/script\u003E\u003Cscript\u003Ealert(/XSS/)\u003C/script\u003E"}

                              Warum codiert man dann für die Übertragung von X nach JavaScript nicht gleich alle nicht numerischen Ausgaben in Unicode.

                              Was meinst du damit? In JSON-Strings sämtiche Zeichen wie oben mit Unicode-Escape-Sequences maskieren? Man tut es nicht, weil ein Zeichen dadurch 6 anstatt im Idealfall einen Byte verbraucht. Sieht man an obigem Beispiel ja.

                              Was mir auch noch nicht klar ist, ist die Verarbeitungsreihenfolge.

                              1. HTML/JS-Dokument wird ausgeliefert.
                              2. HTML-Parser interpretiert das Markup
                              3. HTML-Parser ersetzt die Entities im HTML
                              4. HTML-Parser stürzt sich auf das JavaScript und übergibt es an den JS-Parser

                              Das ist im Groben richtig, allerdings werden Zeichen- und Entity-Referenzen in script-Elementen NICHT ersetzt, wie gesagt.

                              Wann wird gerendert?

                              Die Seite im Browser? Die wird inkrementell gerendert, während der Parser noch aktiv ist und sich der DOM-Tree nach und nach aufbaut. Siehe den HTML5-Parsing-Algorithmus:

                              http://www.w3.org/TR/html5/syntax.html#parsing

                              Die Reihenfolge hat doch einen gravierenden Einfluss auf die Escaping-Stategien.

                              Die Verarbeitungsreihenfolge entspricht zumeist der Sprachverschachtelung. Verschachtelte Sprachen können nur »von außen nach innen« geparst werden.

                              Bei HTML gibt es den Sonderfall, dass eingebettetes JavaScript das Parsing anhält und das Dokument während des Parsens verändern kann (siehe das Schaubild im HTML5-Standard). Siehe auch meine JavaScript-Doku zur Einbindung von JavaScript mit dem script-Element.

                              Es gibt also mehr eine Gleichzeitigkeit beim Parsen von HTML und Parsen/Ausführen von JavaScript. Das hat aber keine besonderen Auswirkungen auf die Escape-Strategie. Für das Escaping zählt die Verschachtelung und die Regeln des HTML-Parsers für den Inhalt von script-Elementen.

                              Ist es irgendwie schädlich oder falsch, wenn man Variablenwerte in JS immer in "" einschließt?

                              Hat das denn jemand behauptet?

                              Strings in JavaScript kann man in " oder ' einschließen, das sagte ich bereits.

                              JSON verwendet immer Double-Quotes als Stringbegrenzer, erlaubt keine Single-Quotes.

                              Mathias

                              1. Hello,

                                Ist es irgendwie schädlich oder falsch, wenn man Variablenwerte in JS immer in "" einschließt?

                                Hat das denn jemand behauptet?

                                Weiß ich nicht. Ich habe jedenfalls danach gefragt, weil das Beispiel mit dem XSS dann nämlich noch nicht funktioniert hätte. Da hätte noch das führende doppelte Anführungszeichen gefehlt, um den aktuellen String abzuschließen, in den die Attacke eingeschleust wurde.

                                Die Idee dahinter war eigentlich nur, für mich herauszufinden, welche Codes minimalistisch ersetzt werden müssten, damit es nicht kracht. Wie Du schon richtig sagst: man will den Stream ja nicht unnötig aufblasen, indem man alle Ein-Byte-Werte durch Sechs-Byte-Zeichenketten ersetzt.

                                Ich gehe aber davon aus, dass _das_ dann sicher wäre(?).

                                Und mir geht es auch darum, in PHP nicht zuviel Overhead zu erzeugen. Wenn man durch eine einfache Replace-Funktion für Sicherheit sorgen kann, muss man ja nicht ein Monster-Modul hinzuladen...
                                (siehe Tamis Vorschlag).

                                Strings in JavaScript kann man in " oder ' einschließen, das sagte ich bereits.

                                Mit Zahlenwerten funktioniert das doch auch. Oder habe ich da einen Spezialfall erwischt?
                                Ich habe mir dazu das Beispiel aus http://de.selfhtml.org/javascript/sprache/variablen.htm umgebaut und alle numerischen Werte auch in "" verpackt.

                                JSON verwendet immer Double-Quotes als Stringbegrenzer, erlaubt keine Single-Quotes.

                                Jo, so langsam kommt doch der Bodenkontakt wieder.

                                Das mit der "Gleichzeitigkeit" beim Auflösen mag ich aber noch nicht so hinnehmen. Oder arbeiten die Browser beim Parsen schon mit Multithreading? Dann müsste man Prioritäten festlegen können! Sonst könnt es Deadlocks geben.

                                Liebe Grüße aus dem schönen Oberharz

                                Tom vom Berg

                                --
                                 ☻_
                                /▌
                                / \ Nur selber lernen macht schlau
                                Die ultimative Seite für Selbermacher
                                1. Hallo,

                                  Die Idee dahinter war eigentlich nur, für mich herauszufinden, welche Codes minimalistisch ersetzt werden müssten, damit es nicht kracht.

                                  Die einfache Variante des Einbettens von JSON in HTML habe ich in https://forum.selfhtml.org/?t=217757&m=1496841 gezeigt.

                                  In diesem Teilthread diskutieren wir ein Spezialproblem, das Einbetten von JSON in script-Elemente. Das ist knifflig, weil für script spezielle Parserregeln gelten und htmlspecialchars nicht weiterhilft.

                                  Mit Zahlenwerten funktioniert das doch auch. Oder habe ich da einen Spezialfall erwischt?
                                  Ich habe mir dazu das Beispiel aus http://de.selfhtml.org/javascript/sprache/variablen.htm umgebaut und alle numerischen Werte auch in "" verpackt.

                                  Warum sollte man das tun?

                                  Oder arbeiten die Browser beim Parsen schon mit Multithreading?

                                  Ja, selbstverständlich. Beim Parsen passieren tausende Dinge gleichzeitig. Viele Ressourcen werden parallel geladen, Bilder werden dekodiert und gerendert, Stylesheets geparst und angewendet usw.

                                  Dann müsste man Prioritäten festlegen können! Sonst könnt es Deadlocks geben.

                                  Quatsch. Das übernimmt der Browser für einen.

                                  Mathias

                  2. Hello Tami,

                    http://php.net/manual/en/function.json-encode.php.

                    Ggfs. auch: http://stackoverflow.com/questions/12062146/is-json-encode-sufficient-xss-protection.

                    Und http://framework.zend.com/manual/2.1/en/modules/zend.escaper.escaping-javascript.html

                    Eas taugt denn wohl diese Seite hier?

                    http://www.the-art-of-web.com/javascript/escape/

                    Alles bekommt man da ja so auf normalem Weg, also über das Browserinterface-UI, auch nicht rein...
                    Beim Lesen von Dateien oder sonstiger Herkunft kann ja viel mehr passieren.

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    Die ultimative Seite für Selbermacher