Punkt 1: 'Input'-Daten auf Gültigkeit überprüfen.
• Daten auf formale Richtigkeit prüfen.
• Daten die an externe Programme/die Shell/ oder kritische Funktionen ('eval();') gehen auf ungültige Zeichenfolgen prüfen. (z.B. '|' bei Daten an Sendmail) Bzw. prüfen das nur gültige Zeichenfolgen vorkommen.
• Wenn es sich um Pfadangaben zu Dateien/Verzeichnissen handelt prüfen ob nicht unerlaubterweise versucht wird den Dateipfad zu wechseln. Bsp. '../../../etc' o.ä.
FARGE: In wieweit macht es Sinn das oben gesagte auch auf eventuell vorhandene eignen (Text-) Konfigurationsdateien anzuwenden? Man weis ja nie... Oder gilt eher, wenn die erst manipuliert wurden ist es es schon zu spät?
Ich denke, solange die Serversicherheit gewährleistet ist, kannst du davon ausgehen, daß deine eigenen Daten in Ordnung sind. Es ist wesentlich einfacher, wenn User gefährliche Daten übergeben, als daß sie Dateien auf dem Server verändern. Wenn sie das können, müssen sie sich ja nicht auf die Konfigurationsdateien beschränken, sondern es können gleich viel bösartigere Dinge in die PHP-Dateien geschrieben werden.
Punkt 2: 'Environment'-Variablen prüfen.
• Konkret habe ich am Fall von PATH gelesen das man diese, wenn möglich, in seinen Script 'per Hand' setzen sollte wegen möglicher Manipulation.
FRAGE: Gehe ich also richtig davon aus, das den meisten anderen Environment-Variablen genau so wenig zu trauen ist und ich ähnlich gelagerte Evs grundsätzlich besser 'selber setzte'?
Die Sache mit PATH hat den Hintergrund, daß so verhindert wird, irgendwelche beliebigen Programme, die zufällig im PATH drinsind, auszuführen, ohne daß man weiß, wo sie sich befinden.
Das Environment enthält ja z.B. Infos über den Browser, der gerade eine Datei anfordert - diese Information kannst du nicht künstlich selbst erzeugen. Du solltest allerdings von der Programmlogik her dich nicht auf diese Informationen verlassen. Referer kann man fälschen, User-Agents kann man fälschen, alles kann man fälschen.
Punkt 3: Dateien/Dateihandling.
Das überspringe ich mal. ;)
Punkt 4: Datei-Upload.
• Überprüfen ob korrektes Dateiformat. Z.B. über die MimeType-Angabe.
• Auf Dateigröße überprüfen. (Beschränkungen der Dateigröße ins Programm fest verdrahten und sich nicht auf 'Hidden-Formular-Fields' mit der gespeicherten Größe verlassen.)
• Alles unter Punkt 3 aufgeführtes.
FRAGE: Die MimeType-Angabe ist doch bestimmt auch nicht gerade die sicherste Methode das Dateiformat zu prüfen, oder? Die wird doch vom Browser mit übergeben, weshalb da im Prinzip doch beliebiges drin auftauchen könnte. Wäre also eine Überprüfung auf Dateiendungen nicht sinnvoller?
Der Mime-Typ wird vom Browser meist garnicht gesendet. Jedenfalls nicht unbedingt einer, der den Inhalt der eindeutig und korrekt beschreibt. Den benutzt du besser nicht.
Die Prüfung der Dateiendung ist aber genauso anfällig, denn das sind ja auch User-beeinflußbare Informationen. Es ist ohne Probleme möglich, einen Virus in "bild.jpg" umzubenennen. Wenn man den dann irgendwie zur Ausführung bringen kann (zurückbenennen, starten)...
Sicherheit ist nur dann gegeben, wenn du das Datei*format* explizit prüfst. Oder die übergebenen Dateien wirklich nur auf ungefährliche Weise verwendest, also z.B. immer nur als Bild referenzierst.
Die Dateigröße wird in der PHP.INI begrenzt: Default 2MB. PHP selbst hat die korrekte Information, wie groß die Datei wirklich ist, also kannst du dich darauf beziehen und mußt keine Formularfelder einbeziehen.
Punkt 5: Sonstiges.
• Auf Buffer-Overflow achten.
FRAGE: In wieweit Betrifft das noch Scriptsprachen? In PHP z.B. kann man eh keine explizite Größe von Variablen festlegen und zweitens scheinen ihn übergroße Werte nicht zu sonderlich zu stören (Quick-Test von eben) sondern er begrenzt diese Werte automatisch.
Buffer-Overflow ist für die Programmierer von Webservern und PHP ein Thema, nicht für die Programmierer, die PHP als Sprache benutzen - würde ich mal ganz unvorsichtig sagen. Als Serveradmin sollte man natürlich immer entsprechende Patches installieren.
FRAGE: Andere Frage, ähnliches Thema. Was ist, wenn ich den Script übergroße Mengen an Daten (z.B. per GET) zuschicke? Glaube irgendwo einmal gelesen zu haben das man damit die Programme wunderbar abschießen können soll. Wenn ja, was kann man dagegen machen? Ist das Script nicht schon gecrasht bevor ich überhaupt dazu gekommen bin eventuelle Prüfungen auf Buffer-Overflows durchzuführen?
Ist ein Problem des Webservers, nicht eines von PHP.
• Wichtige (Konfigurations-) Daten (z.B. Paßworte) immer verschlüsseln.
FRAGE: [Nur PHP?] Sollten wichtige (Konfigurations-) Daten nicht in 'ausführbare Dateien' abgelegt werden? Die Nachfrage bezieht sich auf ein (Forums-) Script (in PHP geschrieben) das ich vor einiger Zeit gefunden hatte. Dort hatte der Autor seine ganzen Konfigurationsdaten in einer *.inc Datei als normale Variablen in der Form „$var = wert;" deklariert. (So übrigens auch beim unverschlüsselten Paßwort) Nun soll es aber mit PHP laut Handbuch per 'Include' auch erlaubt sein Dateien auf fremden Servern in seine Scripte einzubinden. Würde das nicht bedeuten das ich mir in aller Seelenruhe diese Datei in mein eigenes Miniscript linken kann, um mir dann alle Werte ausgeben zu lassen? Oder habe ich da im PHP-Handbuch etwas falsch verstanden?
Man kann den Webserver so konfigurieren, daß er Zugriffe auf *.inc-Dateien generell verbietet. Das macht die Daten schon mal wesentlich sicherer, weil dann keiner ran kann außer über den FTP-Zugang oder das Ausführen eigener Skripte (was einen erfolgreichen Angriff voraussetzt, der dann ohnehin jede Tür geöffnet hat).
Das mit dem Include über Servergrenzen hinweg hab ich auch gerade gelesen (dachte eigentlich, daß es nicht geht - man lernt immer dazu), aber wenn der Server den Zugriff (und Directory-Listing) nicht erlaubt, ist das auch kein Thema. Man könnte ja auch den Browser nehmen und die inc-Datei als URL angeben.
Soweit bis hierhin. Sicher kriege ich wegen meiner unqualifizierten Bemerkungen noch Schläge, aber das bin ich schon gewöhnt - so ist das hier.
- Sven Rautenberg