dobra: serialize-String für mySQL codieren

Hallo,

ich erstelle mit Perl dynamische serialize-Strings (hoffe, das ist der richtige Ausdruck dafür?) die dann über ein hidden input in die DB geschrieben werden.
im Quelltext schaut das dann z.B. so aus:
<input type="hidden" name="ORDERDATA" value="a:10:{s:4:'zone';s:14:'AT';s:6:'anzahl';i:3;s:12:'krabatt_text';s:9:'undefined';s:13:'zahlartrabatt';d:-0.957;s:5:'total';d:35.843;s:13:'krabatt_summe';i:0;s:9:'warenwert';d:31.9;s:13:'zwischensumme';d:36.8;s:7:'versand';d:4.9;s:7:'zahlart';s:23:'Vorauskassa';}">

Das Problem ist jetzt, dass keine "{" und "}" in das Faeld geschrieben werden.
d.h. ich bekomme den String so zurück:
(mit $data =~ s/'/"/g;)
a:10:s:4:"zone";s:14:".....";d:4.9;s:7:"zahlart";s:26:"Rechnung";

und so kann ich ihn natürlich dann nicht unserilisieren.

Habe jetzt schon ne ganze Weile gesucht, aber keine wirklich brauchbare Lösung gefunden.

Meine "Notlösung" schaut so aus:

	$data =~ s/a:10:/a:10:\{/g;  
	$data = $data ."}";  

damit kann ich die Werte dann mit
    my $tmp = serialize::unserialize($data);
    %daten = %$tmp;

my $warenwert = $daten{warenwert};  

....

normal auslesen, aber was mache ich, wenn der String mal nicht mit a:10: anfängt?

Da gibt es doch bestimmt eine bessere Lösung?

lg
dobra

  1. Hallo,

    ich erstelle mit Perl dynamische serialize-Strings (hoffe, das ist der richtige Ausdruck dafür?) die dann über ein hidden input in die DB geschrieben werden.
    im Quelltext schaut das dann z.B. so aus:
    <input type="hidden" name="ORDERDATA" value="a:10:{s:4:'zone';s:14:'AT';s:6:'anzahl';i:3;s:12:'krabatt_text';s:9:'undefined';s:13:'zahlartrabatt';d:-0.957;s:5:'total';d:35.843;s:13:'krabatt_summe';i:0;s:9:'warenwert';d:31.9;s:13:'zwischensumme';d:36.8;s:7:'versand';d:4.9;s:7:'zahlart';s:23:'Vorauskassa';}">

    nicht elegant aber Idiotensicher: nach serialize() nochmal binhex()
    über den String laufen lassen. Dann gibts garantiert keine Problem
    mit Hochkommata etc. ....

    1. Hallo,

      ich erstelle mit Perl dynamische serialize-Strings (hoffe, das ist der richtige Ausdruck dafür?) die dann über ein hidden input in die DB geschrieben werden.
      im Quelltext schaut das dann z.B. so aus:
      <input type="hidden" name="ORDERDATA" value="a:10:{s:4:'zone';s:14:'AT';s:6:'anzahl';i:3;s:12:'krabatt_text';s:9:'undefined';s:13:'zahlartrabatt';d:-0.957;s:5:'total';d:35.843;s:13:'krabatt_summe';i:0;s:9:'warenwert';d:31.9;s:13:'zwischensumme';d:36.8;s:7:'versand';d:4.9;s:7:'zahlart';s:23:'Vorauskassa';}">

      nicht elegant aber Idiotensicher: nach serialize() nochmal binhex()
      über den String laufen lassen. Dann gibts garantiert keine Problem
      mit Hochkommata etc. ....

      Sorry, ich meinte  base64_encode()/base64_decode() oder was anderes
      in der Art ...

      1. Sorry, ich meinte  base64_encode()/base64_decode() oder was anderes
        in der Art ...

        hmmm, ich bin da leider ziemlich doof :(

        hab's mal so versucht:

        use MIME::Base64;
        ...
        my $xprint = serialize::serialize(%SETTINGS);
        $xprint = base64_encode($xprint);
        main::mprint qq|<input type="hidden" name="ORDERDATA" value="$xprint">|;

        aber da hab ich wohl was falsch gemacht (oder ich hab' das Modul nicht zur Verfügung) ?

        im Quelltext ist das hidden input und alles danach verschwunden
        lokal kommt noch die Meldung:
        Undefined subroutine &test::base64_encode called at (eval 96) line 35.

        Kannst Du mir bitte mal ein für Dummys verständliches Beispiel geben, WIE ich das richtig machen kann?

        dobra

        1. Hallo dobra

          Sorry, ich meinte  base64_encode()/base64_decode() oder was anderes
          in der Art ...

          hmmm, ich bin da leider ziemlich doof :(

          Nein, nein - ganz meinerseits :-)

          Erstmal vorweg: ich habe von Perl wenig Ahnung. Eigentlich
          habe ich bisher nicht viel mehr als das Module Base64 eingebunden
          und die Funktionen base64_encode() und base64_decode() benutzt
          (und mich in meinen vorherigen Beitrag noch verschieben weil ich
          die Namen der PHP Funktionen genommen habe - PHP kann ich allerdings
          recht gut).

          Um dein Problem auf den Punkt zu bringen. Irgenwas stört sich
          an den Zeichen in deinem String (du vermutest ja die Klammern).
          Entweder werden irgenwelch Zeichen gefiltert oder, noch schlimmer,
          die Zeichen werden irgenwo interpretiert.

          Gewöhnlich umgeht man solche Problem durch Maskierung von Zeichen.
          In vielen Sprachen wird ein Slash vor das zu maskierende Zeichen
          gesetzt.

          Meine Idee war einfach - anstatt nach den störenden Zeichen zu
          suchen und sie zu maskieren nimmt man einfach den ganzen String
          und wandelt alle Zeichen in etwas um, das nur aus "harmlosen"
          Zeichen besteht ... das meinte ich mit Idiotensicher ...

          Nun, ich habe Zeile für Zeile deinen Perl Code gelesen und
          sehe auch als einzige Erklärung nur, dass das Base64 Mod. nicht
          geladen wurde (aber nochmal - ich bin kein Perl Experte!!!).

          Mehr, als die Idee, einen String gnadenlos in etwas "harmlose"
          zu wandeln und bei bedarf zurück zu wandeln, kann ich dir leider
          nicht bieten - sorry, wenn ich mehr Hoffnung geweckt habe!!!

          Ich hoffe nach mir kommt noch jemand mir Ahung hier vorbei - Sakkkkarre

  2. hi,

    Das Problem ist jetzt, dass keine "{" und "}" in das Faeld geschrieben werden.

    In welches Feld? Also von wo nach wo gibts das Problem und wie überträgst Du die Daten (GET oder POST aus der Sicht des Browsers).

    Da finden wir eine Lösung, totsicher ;-)

    Hotti

    1. In welches Feld?

      Feldname: ORDERDATA
      Typ: LONGTEXT
      Kollation: latin1_swedish_ci
      Null: null
      Standard: NULL
      Attribute und Extra ist leer
      (das hab ich so mal abgeschrieben aus phpMyAdmin)

      Also von wo nach wo gibts das Problem

      also in dem Original-String habe ich "{" und "}" die aber nicht in die DB geschrieben werden

      und wie überträgst Du die Daten (GET oder POST aus der Sicht des Browsers).

      ?? ich schreibe den String in ein hidden input und bei Absenden des Formulars wird der "value" - Wert in die BD geschrieben
      (name ="mein DB-Feldname" value="das was reingeschrieben wird" -> aber eben ohne die { } )

      das macht meine Shop-Software - sorra, aber "keine Ahnung" ob GET oder POST

      dobra (schon sehr verzweifelt)

      1. Hi,

        Also von wo nach wo gibts das Problem
        also in dem Original-String habe ich "{" und "}" die aber nicht in die DB geschrieben werden

        Ja, das war soweit klar.

        Aber die Frage, (ab) wo das Problem auftritt, ist damit immer noch nicht beantwortet.
        Du benutzt ein hidden field, um die Daten zu übergeben. Steht in dessen value-Attribut noch der korrekte Wert drin?

        und wie überträgst Du die Daten (GET oder POST aus der Sicht des Browsers).

        das macht meine Shop-Software - sorra, aber "keine Ahnung" ob GET oder POST

        Dann finde es heraus!

        MfG ChrisB

        --
        “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
      2. hi,

        also in dem Original-String habe ich "{" und "}" die aber nicht in die DB geschrieben werden

        Da solltest Du ansetzen. Nur mal so nebenbei:

        mysql> select * from talk;
        +------------+----------------------------+-----+
        | ts         | nickid                     | msg |
        +------------+----------------------------+-----+
        | 1264879526 | 4l3aqeb52qephs5keinhasl3f1 | {   |

        Du siehst da oben, dass es überhaupt kein Problem ist, Schweifies in eine MySQL Tabelle zu schreiben. Prüfe mal _Deine_ Werkzeuge, die _Du_ hast, um in die Tabelle zu gucken, was da wirklich los ist.

        Hotti

      3. Moin!

        und wie überträgst Du die Daten (GET oder POST aus der Sicht des Browsers).
        ?? ich schreibe den String in ein hidden input und bei Absenden des Formulars wird der "value" - Wert in die BD geschrieben
        (name ="mein DB-Feldname" value="das was reingeschrieben wird" -> aber eben ohne die { } )

        das macht meine Shop-Software - sorra, aber "keine Ahnung" ob GET oder POST

        Das bedeutet also, dass man bei genügender Manipulation der Hidden-Felder in jede beliebige Tabelle jeden beliebigen Eintrag vornehmen kann.

        Wow, mir sind lange schon keine so schlechten Sicherheitskonzepte mehr untergekommen - deine Idee ist wirklich haarsträubend, und du kannst von Glück reden, dass du auf Probleme gestoßen bist und hier auf deine Sicherheitslücken hingewiesen wirst.

        - Sven Rautenberg

  3. Hallo dobra,

    Das Problem ist jetzt, dass keine "{" und "}" in das Faeld geschrieben werden.

    da für MySQL diese Zeichen keine besondere Bedeutung haben, hat MySQL auch kein Problem damit. Es speichert sie erwartungsgemäß und liefert sie erwartungsgemäß zurück:

    Nehmen wir an, wir haben eine Tabelle "example" mit der Spalte "content", VARCHAR, genügend groß dimensioniert. Dann erhalte ich im Kommandozeilenclient von MySQL nach Absetzen folgender SQL-Anweisung

    INSERT INTO  
        example  
    (content)  
    VALUES  
    ('{}'),  
    ('s{Test}xyz');
    

    die Rückmeldung

    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0

    Ein anschließendes

      
    SELECT  
        content  
    FROM  
        example
    

    liefert das Ergebnis

    content
    ------------
    {}
    s{Test}xyz

    Alles völlig normal und erwartet. Wenn Dir Klammern abhanden kommen, dann kann dies zum einen bei der Datenübertragung vom Browser zu Deinem Perl-Script passieren - aber wozu gibt es das CGI-Modul?

    Falls dort die Daten noch erwartungsgemäß ankommen, könnte die weitere Verarbeitung in Perl vor dem Abspeichern in der Datenbank schuld daran sein. Es könnte sein, dass die Daten wie von Dir gewünscht abgespeichert werden, und erst nach dem Auslesen während der Verarbeitung für die Ausgabe verstümmelt werden. Ob die Daten korrekt abgespeichert sind, kannst Du mit dem MySQL-Client Deiner Wahl ermitteln.

    Soweit so gut, aber sowas ...

    im Quelltext schaut das dann z.B. so aus:
    <input type="hidden" name="ORDERDATA" value="a:10:{s:4:'zone';s:14:'AT';s:6:'anzahl';i:3;s:12:'krabatt_text';s:9:'undefined';s:13:'zahlartrabatt';d:-0.957;s:5:'total';d:35.843;s:13:'krabatt_summe';i:0;s:9:'warenwert';d:31.9;s:13:'zwischensumme';d:36.8;s:7:'versand';d:4.9;s:7:'zahlart';s:23:'Vorauskassa';}">

    sowas ist Leichtsinn pur und die Vergewaltigung einer Datenbank.
    Daten, die vom Browser kommen, müssen sorgsam geprüft werden - und vergiß nicht: im Prinzip kann jeder die Daten in den Hidden-Input-Feldern mit Werkzeugen wie Firebug bequem manipulieren.

    Hidden Inputs sind in aller Regel keine besonders gute Idee.

    Und noch viel schlechter ist die Idee, diese serialisierten Daten unstrukturiert in einem Datenbankfeld abzuspeichern. Die DB verkommt zur sequentiellen Datei (mit dem einzigen Vorteil, dass Du Dich ums Sperren nicht zu kümmern brauchst). Deine Daten sehen jedoch nach strukturierten Daten aus, die man wunderbar in unterschiedlichen Spalten (wenn nicht sogar Tabellen) speichern sollte, könnte, müsste.

    Du könntest Dir Dein Konzept noch einmal durch den Kopf gehen lassen. Du kannst es mit Sicherheit sicherer und besser machen.

    Freundliche Grüße

    Vinzenz

    1. Hallo Vinzenz,

      sowas ist Leichtsinn pur und die Vergewaltigung einer Datenbank.
      Daten, die vom Browser kommen, müssen sorgsam geprüft werden - und vergiß nicht: im Prinzip kann jeder die Daten in den Hidden-Input-Feldern mit Werkzeugen wie Firebug bequem manipulieren.

      hmmm, das hatte ich nicht bedacht :(
      DANKE für den Hinweis!

      Du könntest Dir Dein Konzept noch einmal durch den Kopf gehen lassen. Du kannst es mit Sicherheit sicherer und besser machen.

      werde ich - ja, ich finde mit ein bißchen Überlegung sicher auch einen anderen Weg

      lg
      dobra

  4. Neustart,

    ich weiss ja micht, wieviel Zeit du bisher schon in das Erlernen von Perl gestekct hast. Und ich weiss nicht, ob der rat wirklich gut ist. Aber es könnte vieleicht besser sein, wenn du von Perl auf PHP umstellst. Ich bin nur im letzeren fitt. Glaube aber, das PHP viele vorzöge hat (allein die Erlernbarkeit).

    Hoffe das Frustet dich nich noch mehr ...