Sicherheit Escapen, Get und Post

Joe

Erfahrenes Mitglied
Hallo Comunity

Als Anfänger ist man sich der Sicherheitslücken zuallermeist überhaupt nicht bewusst. Es gibt dazu zwar zuhauf Artikel im Inet zu finden aber welcher Anfänger versteht das schon wenn er sich das erste mal damit beschäftigt. Also schiebt man es erstmal ein Stück nach hinten.

Als mir bewusst wurde wie einfach die Übergabeparameter $Get in der URL manipulierbar sind, habe ich mir strikt angewöhnt solche nicht zu nutzen.
Oft kann man dann lesen nutze einfach $Post das wäre sicherer. Ein Trugschluss wie mir die Tage auffiel. Ein einfaches Addon für Firefox und schon kann man alle Formfelder manipulieren. Dies zwingt mich nun nochmals mein Code entsprechend abzuändern.

Die Sicherheitslücke liegt dabei nicht nur bei SQL-Injection sondern auch bei Manipulieren der Werte selbst. ZB könnte der Angreifer den Preis verändern (auch wenn dies ein Hidden-Field ist). Man sollte also nur Daten schicken welche bei einer Manipulation nix bringen würden, solche wie eine ID.
Sensible Daten wie Preis etc. müssen also per Datenbankabfrage auf der Seite wo sie hin gepostet werden nochmals geholt werden. Sie einfach nur mit mysql_real_escape_string() von Injections zu filtern und direckt weiter zu verarbeiten genügt nicht.

Dennoch bleiben da noch ein paar Fragen offen.
1. Genügt es die Daten mit der Funktion mysql_real_escape_string() zu filtern oder sollte man noch andere Funktionen zum filtern nutzen?

2. Relativ umständlich finde ich die doppelten Datenbankabfrage die aus obrigen Szenario resultieren. Sind Sessions da sicherer oder sollte man darauf wenn möglich doch lieber verzichten?

3. Was muss man bei normalen Cookies bedenken?

4. Und welche oft genutzten Sicherheitslücken gilt es noch zu beachten?
 
1. Filtern könnte man zusätzlich noch Zeichen, die für XSS benutzt werden könnten. Also alles, was irgendwie nach HTML oder JavaScript (oder sonstigen Browser-Sprachen) riecht. mysql_real_escape_string() sorgt ja nur dafür, das eine SQL-Injection ins Leere führt.

2. Das wiederum würde ich auch nicht tun, also die Preis-Daten in der Session ablegen. Wenn dann eher sinnvolle Objekt-Caches für Datenbank-Ergebnisse. Im Zweifelsfall ist der zweifache DB-Zugriff die bessere Alternative.

3. Das man sie nur dort einsetzt, wo es nicht anders möglich ist. Z.B. wenn man transparente Sessions verwendet. Ansonsten sind Cookies für keinen sinnvollen Einsatz notwendig - wenn man von so nem Quatsch wie Login-Merken (zugegeben, ich benutz es auch) absieht, denn das ist eine Sicherheitslücke (Cookie-Diebstahl).

4. Wie schon erwähnt, gibt es da noch XSS, was sehr häufig anzutreffen ist im WWW. Auch so Dinge wie browser-seitige Validieren ohne server-seitige kommen recht häufig vor, sobald man JS ausgeschaltet hat, darf man alles an den Server senden und der verarbeits auch brav ;-) Ein weiterer Fehler ist es, vom Guten im Menschen auszugehen. Misstraue allem und jedem, was Webentwicklung angeht, ist damit jede Datenquelle gemeint, die variabel ist (Browser, Sockets, Webservices, DB, Files, etc...), insofern wärst du als Entwickler die Sicherheitslücke, wenn du es nicht tätest :-)


Im Übrigen: Danke! Endlich mal die richtigen Fragen!
 
  • Gefällt mir
Reaktionen: Joe
Hallo Joe,

Oft kann man dann lesen nutze einfach $Post das wäre sicherer. Ein Trugschluss wie mir die Tage auffiel. Ein einfaches Addon für Firefox und schon kann man alle Formfelder manipulieren. Dies zwingt mich nun nochmals mein Code entsprechend abzuändern.
Ich würde sagen, man sollte POST nur nutzen, wenn die Daten nicht erneut geschickt werden sollten oder z.B. auch eine Datei geschickt wird.

Wenn man das Protokoll (hier die Art & Weise, wie JS die Daten sendet) kennt, kann man als Angreifer jede Anfrage simulieren.
Also kann man auch Formulare senden lassen. Von daher muss man alle Daten kontrollieren, wie du sagtest auch die hidden-Felder.
Da hat man es mit CakePHP einfach, da wird sowas automatisch überprüft, indem der Wert vorher in die Session geschrieben wird.

Vielleicht findest du noch ein paar mehr Informationen in meinem Tutorial: Sicherheit in PHP-Codes schaffen
 
  • Gefällt mir
Reaktionen: Joe
@ComFreek
Ich würde sagen, man sollte POST nur nutzen, wenn die Daten nicht erneut geschickt werden sollten oder z.B. auch eine Datei geschickt wird.
Hab bissel Mühe den Satz zu verstehen.
In meinen Formularen habe ich meist alle Daten welche zur Ausgabe/Anzeige aus meiner DB gelesen. Um dann die DB-Abfrage zu sparen wurde dies kompakt in hidden-fields per Post gesendet. Bsp: mehrere Artikel -> einen in den Einkaufswagen legen -> Post auswerten usw.
Der Fehler war also alle Daten zu schicken , weil diese manipuliert werden können (zb Preis).

Einmal muss ich es schicken um zb. den richtigen Artikel dann weiterzuverarbeiten. Allerdings reicht die ID völlig und die Daten zur ID müssten eben nochmals auf der Zielseite geholt werden.

Da hat man es mit CakePHP einfach, da wird sowas automatisch überprüft, indem der Wert vorher in die Session geschrieben wird.
Ja Frameworks und CMS haben etliche Vorteile aber ich wage zu behaupten das die wenigsten Anfänger damit was anfangen können.



@saftmeister
zu 1. dachte ich mir die Daten zusätzlich mit addcslashes($Var,“\x00\r\n\x1a\x25”) abzusichern.
flow%20a%20-%20rep%20func.gif

Dann gibt es wohl noch striptags() wie und was dort passiert ist mir im Moment grad nicht klar.

zu2. Obwohl Performancelastiger werde ich wohl mit der 2.en DB-abfrage machen. scheint mir einfach sicherer.

zu4. XSS hmm das ist davon abhängig wie ich templates einbinde oder? Ich hab mein System nach dem TUT von Quakenet aufgebaut (kennt man sicher). mit dieser Art Sicherheitslücke muss ich mich nochmal itensiver beschäftigen.

Auch so Dinge wie browser-seitige Validieren ohne server-seitige kommen recht häufig vor, sobald man JS ausgeschaltet hat, darf man alles an den Server senden und der verarbeits auch brav
Hmm validieren? kannst du das nochmal etwas erklären, im Moment steh ich etwas auf dem Schlauch.



Vielen Dank für eure Antworten.
 
Zum Preis etc: Ja, das ist ein prinzipieller Fehler.
Indem du den Preis zum Client schickst und dieser ihn wieder zurückgibt
gibt dir der Client praktisch den Preis vor.
Jeder, der sich einigermaßen auskennt könnte die Zahl auf seinem Rechner manipulieren.
Verlass dich bei Preisen etc. nur auf die DB, keine Client-Inputs.

striptags: Das entfernt html-Tags.
Also aus
HTML:
<span style="color:#123456">Hallo</span>
macht es
HTML:
Hallo
Bei diesen und ähnlichen Beispielen verhinderst du so,
dass dir wer das Design der Seite durcheinanderbringt.
Außerdem kommt auch das <script>-Tag weg und verhindert so das Einbinden von JS
(das bei allen, die es anschauen, ausgeführt würde und noch viel mehr Blödsinn anstellen kann).

XSS: Hmm, was hat das jetzt speziell mit Templates zu tun?
SQL-Injection ist dafür, um zB. bei einer DB-mäßigen Kennwortüberprüfung die Abfrage durch eine bestimmte Kennworteingabe so zu manipulieren, dass das Kennwort immer als Richtig erkannt wird, und soohne richtigem Kennwort Zugriff auf die Daten dahinter zu erhalten. Nur als Beispiel. Verhidnern kann man das mit dem angesprochenen mysql_real_escape_string(), das auf jede SQL-relevanten Werte angewendet wird.

XSS dagegen hat mit der DB gar nichts zu tun, sondern ist (wie im striptags-Beispiel)
das Reinschmuggeln von JS, Java-Applets usw., was da in den seltensten Fällen rein darf.

Wenn das Forum hier nicht dagegen abgesichert wäre, könnte ich zB. ein ordentlich signiertes Java-Applet machen, das irgendwelche Dateien vom Client an mich sendet, und das Applet in meinen Beitrag hier einbinden. In Folge erhalte ich von jedem, der meinen Beitrag (bzw. das Thema hier) anschaut, diese Dateien. Und bis die Signierungsstelle draufkommt hab ich schon hunderte Computer "ausgeraubt".
 
  • Gefällt mir
Reaktionen: Joe
Unterschied zwischen Filtern und Validieren:

- Filtern sorgt dafür, das keine nicht gewollten Daten (Characters) von der Anwendung verarbeitet werden. Es gibt aber keine Garantie dafür, das die eingegebenen Daten Korrekt sind. Du kannst bspw. dafür sorgen, das man bei der Angabe des Geburstdatums nur Zahlen eingibt. Aber damit kannst du nicht verhindert, das dort jemand 34.17.3024 eingibt.
- Validieren funktioniert ähnlich dem Filtern nur ist es etwas feinkörniger und kümmert sich eher um den Aspekt der logischen Korrektheit von Daten. Damit wird z.B. geprüft, ob eine Email-Adresse eine solche ist oder ein Datum das korrekte Format hat.
 
  • Gefällt mir
Reaktionen: Joe
Ahja verstehe mit striptags verhindere ich also XSS das eingeben von Schadcode (Javascript).
Habe das verwechselt mit einer anderen Angriffsart, bei der wenn ich mich recht entsinne über die templates ganze Seiten Schadcode von andren adrressen eingebunden werden können.

@saftmeister
Danke nun ist mir klar wie du das meinst. Die Validierung des Codes und die dahintersteckende Logik des Codes, das Überprüfen der Daten die man erwartet.

Zum XSS nochmal, es ist also ohne Schutzmassnahmen möglich einfache Formulare mit Schadcode abzuschicken? Oder ist hier eher sowas wie Gästebuch usw gemeint?

Noch eine Frage ich meine irgendwo mal was von Speichermanipulation gelesen zu haben. Was gibt es darüber zu sagen? Irgendwie klingt das nach einem Problem welches man nicht ohne weiteres umgehen kann oder?
 
XSS: Betrifft "nur" die Sachen, die
1) von einem Benutzer an den Server geschickt weren UND
2) anderen Benutzern angezeigt werden.

Wenn es um zB. ein Passwort geht, besteht zwar das Risiko SQL-Injection, aber nicht XSS.
Wenn er JavaScript-Code als Passwort nimmt, kann er das ruhig machen, weil sein Passwort ja nicht öffentlich auf der Website sichtbar ist. Der Server stört sich an JS überhaupt nicht.

Problematisch wird es eben dann, wenn die Daten auf der Website sichtbar werden.
Wenn da JS mit zum Browser geschickt wird, wird es auch gestartet
und kann irgendwas anstellen.

Das Ganze ist, wie schon gesagt, nicht nur beschränkt auf JS, auch Java etc. ist dabei.
Aber auch für Java auf Webseiten braucht man <...>-Tags, striptags hilft also auch hier.

Speichermanipulation: Kann hier keinen Schaden anrichten.
Gemeint ist, mit C-Programmen die Variablen von anderen Programmen im Arbeitsspeicher auszulesen bzw. zu verändern und so an Passwörter zu kommen oder das andere Programm irgendwie zu manipulieren.

Kann deswegen nichts ausrichten, weil es am Server gestartet werden muss.
Ein HTML-Formular kann sowas nicht, egal wie schädlich die eingegebenen Daten sind.
Wenn der Angreifer das bei sich startet hackt er nur seinen eigenen Computer.

Wenn sowas am Server läuft gibt es dagegen keine Schutzmöglichkeit.
Aber wie gesagt: Nicht über HTTP machbar.
 
  • Gefällt mir
Reaktionen: Joe
Ich danke euch für die wirklich umfangreichen und informativen Antworten. Im grossen und ganzen habe ich nun verstanden wie die genannten Sicherheitslücken auftreten und wie ich diese verhindern kann.

Zwar gibt es sicher noch viel mehr zu an Sicherheit zu besprechen wie zb LFI oder RFI aber den gängigsten Teil an Angriffen kann ich nun verhindern.

Danke euch!
 
Ich würde sagen, man sollte POST nur nutzen, wenn die Daten nicht erneut geschickt werden sollten oder z.B. auch eine Datei geschickt wird.
@ComFreek
Hab bissel Mühe den Satz zu verstehen.
Ein paar Beispiele:
  • Login-Form: Dafür wählt man eindeutig POST. Denn sonst werden die Daten per URL (GET) geschickt und diese wird im Verlauf gespeichert!
  • Text-Formular: Für ein Formular mit Text (auch wenn nur wenig), sollte man auch POST nehmen. Denn sonst wird der Text per URL (GET) geschickt und man will ja nicht zweimal die Daten verarbeiten.
  • Suche: GET ist dafür meiner Meinung nach schon geeignet, da man den Link vielleicht auch verschicken möchte, etc.

Ja Frameworks und CMS haben etliche Vorteile aber ich wage zu behaupten das die wenigsten Anfänger damit was anfangen können.
Ja, da stimme ich dir zu! Als Anfänger, sogar fortgeschrittener Anfänger würde ich nicht gleich zu einem Framework raten. Allerdings können diese später sehr nützlich sein, das hängt aber auch immer von der Situation ab.
 
  • Gefällt mir
Reaktionen: Joe
Zurück