Entwickler-Ecke

Basistechnologien - String.Format() attack, was ist zu tun ?


giacosurf - Sa 08.05.10 09:22
Titel: String.Format() attack, was ist zu tun ?
Hallo,

ich habe eine Applikation in C#.NET entwickelt und sie an Kollegen verschickt. Nun bekam ich eine Rückmeldung von einem, der die Korrektheit einer Berechnung bezweifelte. Nach kleiner Recherche stellte sich heraus das der Wert 124,12345 bei meinem Kollegen als 12412345,00 angezeigt wird. Schuld hierfür ist die verwendete Funktion String.Format("{0:0.0}", dValue). Seit 1999 ist dieses Problem, was hin und wieder mal auftreten kann bekannt.

http://en.wikipedia.org/wiki/Format_string_attack

Ist ja alles schön und recht aber meine Frage nun ist wie ich das Problem lösen kann? Sicherlich gibt es andere Funktionen mit denen man die String.Format() ersetzten könnte, bsp. mit Regex oder so, was mich aber eigentlich interessiert ist wieso die Windowswelt dieses Problem (das seit 10 Jahren besteht) nicht in Griff bekommt? Was ist schuld dafür? Ein Virus, Wurm, etc.? Gibt es eine Freeware welche ggf. dies detektieren und löschen könnte?

Hat jemand Erfahrung damit und weiß Abhilfe?


Vielen Dank schon einmal im voraus.

Gruß

Jo


Moderiert von user profile iconChristian S.: Topic aus Programmierwerkzeuge verschoben am Do 13.05.2010 um 20:38


jaenicke - Sa 08.05.10 09:38

Hallo und :welcome:

Ich sehe keinen Zusammenhang zwischen dem Wikipedia-Artikel und dem Problem. :nixweiss:

In dem Wikipedia-Artikel geht es darum, dass Benutzereingaben direkt an Format übergeben werden und dadurch eine Sicherheitslücke auftritt. Das ist hier aber doch gar nicht der Fall und nicht das Problem.

Für die Ausgabe der Zahl reicht schlicht auch ToString, wenn da kein besonderes Format angegeben werden soll. Was genau soll denn das 0:0.0 in dem Format-String bedeuten? Der Doppelpunkt sagt mir jetzt erstmal nix.


JüTho - Sa 08.05.10 10:41

Hallo und ebenfalls :welcome:

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Für die Ausgabe der Zahl reicht schlicht auch ToString, wenn da kein besonderes Format angegeben werden soll.

So ist es. Ich habe auch eher den Verdacht, dass du und dein Kollege mit unterschiedlichen Installationen von Windows und/oder .NET arbeitet, dadurch die falsche CultureInfo als CurrentCulture zur Verfügung steht und deshalb Dezimal- und Tausendertrenner falsch interpretiert werden.

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Was genau soll denn das 0:0.0 in dem Format-String bedeuten? Der Doppelpunkt sagt mir jetzt erstmal nix.

Das ist wohl nur der Hinweis auf das 0-te Element in der Liste der Argumente.

Gruß Jürgen


Kha - Sa 08.05.10 12:27

Um es noch einmal klar zu machen: Das Problem entsteht sicherlich nicht durch Format.

C#-Quelltext
1:
2:
3:
4:
124.12345.ToString("0.0");;
val it : string = "124,1"
124.12345.ToString("0.0", CultureInfo.InvariantCulture);;
val it : string = "124.1"

Es kann nur dadurch erzeugt werden, dass beim Einlesen eine falsche CI angegeben wurde. Als Faustregel muss bei direkten Eingaben vom User CurrentCulture, bei nicht-lokalen Daten, die also zwischen verschiedenen Computern ausgetauscht werden können, dagegen InvariantCulture benutzt werden. Gleiches gilt dann natürlich für die Ausgabe.



user profile icongiacosurf hat folgendes geschrieben Zum zitierten Posting springen:
was mich aber eigentlich interessiert ist wieso die Windowswelt dieses Problem (das seit 10 Jahren besteht) nicht in Griff bekommt?
Warum sollte sich dieses Problem, das bei einem managed Programm gar nicht auftreten kann, auf Windows beschränken?


giacosurf - Mo 10.05.10 21:39

Hallo erstmals danke für die schnellen Antworten. Das Problem is nur das durch das einfügen von "CultureInfo.InvariantCulture" jetzt meine ganzen Berechnungen nicht mehr stimmen.

hier ein Beispiel meiner WindowsForm Anwendung:


C#-Quelltext
1:
2:
3:
4:
5:
6:
tb_Feld3.Text = String.Format(CultureInfo.InvariantCulture,"{0:0.0}",(Convert.ToDouble(tb_Feld1.Text)           /Convert.ToDouble(tb_Feld2.Text))*100.0);
 
if (Convert.ToDouble(tb_Feld1.Text) > Convert.ToDouble(tb_Feld2.Text))
{
      // hier Feld1 63, Feld2 40.23 <- Punkt wird nicht gelesen somit 4023 :)
}


Wie bekomm ich das in Griff ?


Des Weiteren rufe noch daten von einer Access-Datenbank z.B. "123,11" aus, muss man da auch was beachten?

Moderiert von user profile iconKha: C#-Tags hinzugefügt


Kha - Mo 10.05.10 21:46

Lies dir meinen Post noch einmal durch, bei der Ausgabe in die GUI ist InvariantCulture falsch. Und falls doch, dann bitte auch konsequent: Du benutzt es nur beim Ausgeben, nicht beim Einlesen, deshalb das falsche Ergebnis.

user profile icongiacosurf hat folgendes geschrieben Zum zitierten Posting springen:
Des Weiteren rufe noch daten von einer Access-Datenbank z.B. "123,11" aus, muss man da auch was beachten?
Solange sie dort nicht als Strings stehen, sollte das kein Problem darstellen :) .


giacosurf - Fr 14.05.10 17:38

Hallo Sebastian,

danke für den Hinweis. Ich habe jetzt das problem wie folgt gelöst.


C#-Quelltext
1:
2:
3:
4:
5:
6:
tb_Feld3.Text = String.Format(CultureInfo.InvariantCulture,"{0:0.0}",(Convert.ToDouble(tb_Feld1.Text, CultureInfo.InvariantCulture) / Convert.ToDouble(tb_Feld2.Text,CultureInfo.InvariantCulture))*100.0);
 
if (Convert.ToDouble(tb_Feld1.Text, CultureInfo.InvariantCulture) > Convert.ToDouble(tb_Feld2.Text, CultureInfo.InvariantCulture))
{

}


Das habe ich konsequent beim ganzen Code so gemacht und meinen Kollegen eine neue Version zukommen lassen. Leider hat er immer noch das selbe Problem.

Mmh, jemand doch ne Idee woran es sonst liegen könnte, bzw. was Ihr als nächstes tun würdet.

Gruß
Jo

Moderiert von user profile iconKha: C#-Tags hinzugefügt


Kha - Fr 14.05.10 17:51

Was genau ist nun das Problem? Bei Eingabe von "63" und "40.23" wird der if-Block nicht betreten?


giacosurf - So 16.05.10 18:43

Hallo,

mein Programm funktioniert soweit. Das Problem ist nun nach wie vor dass mein Kollege den falschen Wert bekommt da in den UK . und , vertauscht sind. z.B. 1,000.00 anstatt 1.000,00 . Also wenn mein Kolleg im Windows . und , vertauscht funktioniert es auch bei Ihm.

Ich verwende das VS 2008 Englische Version und wollte Fragen was ich tun kann, dass mit einer Version sich diese Problematik beheben lässt.

Danke im voraus...


Kha - So 16.05.10 20:36

Ja, so weit waren wir denke ich schon nach dem ersten Beitrag :) . Ich wollte wissen, wo genau in deinem Code sich nun bei deinem Kollegen ein Fehlverhalten zeigt, sonst können wir dir schlecht helfen.


giacosurf - Di 18.05.10 16:47

Hey,

Ja wenn mein Kollege ein VS hätte und sich auskennen würde, hätten wir es auch ohne Eure Hilfe hinbekommen. Wie es so häufig ist lag das Problem auf der Hand :).

Das Program ließt die Daten aus einer Access Datenbank 2003 aus. Dort wurden alle Werte in der Kommaschreibweise durch export aus excel eingefügt. Da lag das Problem, da die englische Version das , nicht erkannt hat und alle Werte folglich zu groß waren. Es kann so einfach sein.
Die Punktschreibweise funktioniert jetzt beidseitig.

P.s Danke an alle...


danielf - Di 18.05.10 16:51

Hättest du dein Problem annähernd genau beschrieben wären wir wohl sofort auf die Ursache gestoßen. Dieser Thread hat unnötig Zeit verschwendet. Und Kommentare wie
Zitat:
Ich sehe keinen Zusammenhang zwischen dem Wikipedia-Artikel und dem Problem. :nixweiss:
hast du ja knallhart ignoriert.


Kha - Di 18.05.10 17:36

Da kann ich Daniel nur recht geben; schließlich ist es mehr als eine Woche her, dass ich folgendes geschrieben habe:
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
user profile icongiacosurf hat folgendes geschrieben Zum zitierten Posting springen:
Des Weiteren rufe noch daten von einer Access-Datenbank z.B. "123,11" aus, muss man da auch was beachten?
Solange sie dort nicht als Strings stehen, sollte das kein Problem darstellen :) .


giacosurf - Do 20.05.10 20:42

@danielelf - ich habe es überhaupt nicht ignoiert sondern recht schnell eingesehen, dass du recht hattest. Entschuldigung dass ich es nicht explizit erwähnt habe und deshalb das Lob ausblieb. DANKE

Das mit dem String leuchtet mir bis jetzt nicht ein. Wenn ich in ein Access - Zeile einen Wert wie "11,6" rein schreibe ist es dann automatisch ein String? beim auslesen erhalte ich ein object das ich dann als double deklarier.