Home  Services  Contact  Projects  Whitepapers  Tools  Partners 

************************
Web-Application SECURITY
************************


************************
I. GENERELL
************************


Dieses Dokument behandelt allgemeine Gefahrenquellen bei der Erstellung von Web-Applikationen.

Folgende Anmerkungen sind natuerlich keinesfalls vollstaendig und befassen sich nur mit
den HAUPTURSACHEN fuer Security-Schwaechen in Web-Applikationen allgemein.


1) ALLGEMEIN
************

Web-Programme unterscheidet sich in vielen Punkten von anderen Programmen.
So ergeben sich einige neue "Bedrohungen", die in traditioneller Umgebung nicht zu finden sind.

Web-Programmierer muessen zusaetzlich zu ihren Entwicklungssystem(en) wissen, wie
Browser mit Servern bzw. Server mit anderen Servern interagieren etc etc etc.

Einige Zeit lang galt die Meinung, dass Firewalls Server sicher machen.
Jede "loechrige" Web-Applikagtion macht die(meisten) davor stehende Firewalls KOMPLETT nutzlos.

Mom. liegen sogenannte IDS Systeme voll im Trend. Diese lassen sich mit primitiven Mitteln
jedoch leicht umgehen und koennen im besten Fall den(einen) Systemadministrator davon
in Kenntnis setzen, dass sein System bereits kompromitiert wurde.

Da diese Systeme von "bekannten" Sicherheitsloechern ausgehen, wird ihnen eine
Individuelle Attacke in den meisten Faellen gar nicht auffallen!



2) BROWSER INPUT und FOLGEN
***************************

Der ABSOLUT WICHTIGSTE Punkt bei der Erstellung von Web-Applikatioenn.

UEBERPRUEFE jeden nur denkbaren Browser-Input!

das beinhaltet in erster Linie

*** HTML-Formular Variablen
*** Cookies

aber nicht zu vergessen

Alle HTTP-Request Header-Informationen :

wie zb.:

*** User-Agent
*** Http-Referer (wurde frueher oft fur Auth. benutzt)
*** path-info
*** remote-user

uvam. (siehe HTTP-Spezifikation)

Dabei ist im Besonderen zu beachten, dass die Eingabeueberpruefung AM SERVER und nicht
"Client-Seitig" (mittels JS o. J-Applet) erfolgt!


Anmerkung: "hidden" :

ein "Hidden-Field" ist NICHT hidden!


Anmerkung: Formular-Methoden POST vs. GET:

Da sich verschiedene (nichtdruckbare) Zeichen mittels POST nicht uebermitteln lassen,
und POST Variable "weniger" sichtbar sind, ist POST (in den meisten Faellen) GET vorzuziehen!

Ausserdem scheinen URL s (also auch GET-Requests mit allen ihren Parametern) in Browser-,
Proxy- u. Serverlogs auf!


a) GEFAEHRLICHER INPUT - SPECIAL(Meta) CHARS

([|!&;'`:\] uvam.) haben auf den verschiedenen Betriebssystemen verschiedenste Bedeutung!


b) UNSICHTBARE CHARS

Im Speziellen des beruehmte NULL-Byte(0x00) ist fuer viele WebSysteme gefaehrlich.
(Egal ob in C,Perl,PHP(teilweise) oder Java programmiert!)

Aber auch andere "Steuerzeichen" wie zb.: 0x0a (Newline) duerfen in diesem Zusammenhang
nicht unerwaehnt bleiben (phf :-)


c) SICHERN VON BROWSER INPUT AM SERVER

.. kann HTML-Tags, JS-TAgs, PHP, SSI, JSP uvam. beinhalten.
Die damit produzierten "Files" sind die klassische Vorbereitung fuer die nachste Stufe
der Attacke(das Ausfuehren von Systemkommandos zb.)

Dieses Problem tritt sehr oft bei Gaestebuechern und Diskussionsforen auf.
Natuerlich sind auch temporaere Dateien davon betroffen.

(Eine dementsprechende Attacke uerde sich dann WebServer-Race-Condition nennen :-)

In diesem Zusammenhang ist im besonderen auf Server-Side-Includes hinzuweisen.
Sie werden (meistens) per Default von (fast) allen Web-Servern zur Verfuegung gestellt!

In diesem Zusammenhang ist unbedingt auf die Gefahr von "JavaScript" aufmerksam zu machen!
JavaScript kann zb. mittels "file://" dazu benutzt werden "client-seitige"
Dokument zu lesen und anschliessend per Mail an den Angreifer zu schicken!

dh.: Dokumente,Daten,Logfiles uAe. immer in einem sogenannten "Daten-Verzeichniss" speichern.
Dieses Verzeichnis sollte dabei unbedingt ausserhalb des "htdocs" Directory liegen.


d) NAMENSGEBUNG VON DATENFILES

.. darf niemals per User-Input bestimmt werden.
Wenn das unbedingt notwendig ist, folgende Vorgehensweise:

VARNAME = <Pfad hardcoded> <User-Input(sanitized = desinfiziert:-)> <Extension hardcoded>

Obiges gilt natuerlich auch fuer ALLE File-Uploads.


e) OEFFNEN VON DATENFILES

.. User-Input nur wenn unbedingt notwendig integrieren.
Funktionalitaeten sehr stark vom Programmiersystem abhaengig:

*** open, fopen, popen, file, fpassthru, File, FileInputStream uvam.

Anm. zu Perl:

"open" NIEMALS ohne "Modus" verwenden: "pipes" im Filenamen fuehren zur Shell !!!

Anm. zu PHP:

"fopen" oeffnet nicht nur locale Dateien, sondern auch sog. Remote-Files [http|ftp] !!!


f) NUTZUNG VON OS-Funktionen

.. ist Programmiersystem abhaengig:

*** "backticks", exec, system, popen ,Runtime uvam. (je nach Sprache)

Solche Funktionalitaet sollte soweit als moeglich vermieden werden.


g) DEBUG INFORMATIONEN

.. werden gerne und oft benutzt. Spaetestens im Produktionsbetrieb sind solche Funktionen
komplett aus den Programmen bzw. Scripten zu entfernen.

(der Parameter debug,info,help=1 haben schon viele WebApplikationen zu Fall gebracht!)


h) SONSTIGES

In letzter Zeit treten mit grosser Haeufigkeit sog. "character-encoding" bugs auf.
Die Verschiedenen Layer beginnend bei der Server-Software bis zur endgueltigen Web-Applikation
sind zur Verarbeitung verschiedenster "Zeichensaetze" geeignet oder auch nicht.

Die meisten dieser Bugs treten Server-seitig auf. Es ist jedoch nicht auszuschliessen, dass
diese Methoden in naechster Zukunft auf direkten Einfluss auf Web-Applikationen nehmen werden
(Ich denke dabei im Speziellen an Java-Servlets und JSP)


i) LOGISCHE FEHLER

.. koennen je nach Funktionalitaet auch boese Folgen haben.
Ein klassisches Beispiel fuer diesen Fall ist ein gefuellte Warenkorb ohne Endsumme.
(Auf Grund der fehlenden Warengruppe fuer Produkte in Aktion konnte der SQL-Query leider
keinen Eintrag in der Preistabelle finden).

Diese Art Fehler sollte spaetestens beim Testen erkannt und eliminiert werden.




************************************
II. PROGRAMMIERSPRACHEN-SPEZIFISCHES
************************************

Ich habe mich hier in erster Linie um PHP gekuemmert.
Die Shell,Perl,Java,Phyton und C werden nur kurz angerissen.


******************
A) PHP - Scripting
******************

Dieser Absatz behandelt die technischen Gefahrenquellen bei der erstellung von PHP-Scripten.
Logische Fehler sind diesbezueglich natuerlich immer denkbar, werden hier aber nicht beruecksichtigt.

Folgende Anmerkungen sind natuerlich keinesfalls vollstaendig und befassen sich mit
den HAUPTURSACHEN fuer Security-Schwaechen in PHP-Scripts.



1) Globale Variablen
********************

Diverses:

- Variablen muessen nicht deklariert werden.
- einzige Ausnahme sind Funktionen wo sie mittels "global" includiert werden muessen(koenntn)

Problematik:

- Angreifer kann Variablen nach belieben erzeugen und "veraendern"

Demo-Code:

<?php

if($passwort == "trallala")
$admin = 1;

?>

Fazit:

Traue keiner Variable, die nicht explizit von dir "declariert" bzw. gesetzt wurde.
Verwende nur Eintraege der "HTTP_"-Arrays als zulaessigen Benutzerinput.



2) Externe Dateien
******************

Diverses:

Saemtliche "file-operationen" sind per Default sehr flexibel.

Problematik:

PHP unterscheidet hiebei(meistens) nicht zwischen "localen" und "entfernten" Dateien.
Mittels "fopen" zb. laesst sich sowohl:

"/dir/filename.ext"

als auch:

"[ftp|http]://servername/dir/filename.ext"

oeffnen!

Dieses Problem wird leider auch an die funktionen (indluce,inlude_once,require,require_once)
vererbt.


Demo-Code:

<?php
include ($include_verzeichnis."wasauchimmer.php");

?>


Fazit:

Variablen die fuer obige Funktionen verwendet werden immer declarieren, hardcoden
oder Environment-Variablen dafuer verwenden!



3) Datei Uploads
****************

Diverses:

PHP unterstuetzt RFC 1867 basierenden Dateiupload.

Noch bevor der Interpreter zum Einsatz kommt, wird bereits die Datei in
ein temporaeres Verzeichnis(normalerweise "/tmp/randomname") am Server abgelegt.

Bei Web-basierenden Uploads werden automatisch 4 globale Variablen verwendet:

$name (name local)
$name_size (dateigroesse)
$name_name (originalname)
$name_type (mime-type)

Problematik:

alle 4 Variablen koennen wiederum durch den Angreifer gesetzt werden.
Obwohl das File "trallala.txt" upgeloedet werde, wird das Script die Datei
"$name" verarbeiten!

Demo-request:

---cut here---

http://servername/upload.php?$fn=/etc/hosts&$fn_size=20000&$fn_name=/tmp/xx.txt&$fn_type=text/plain

---cut here---


Fazit:

Uploads immer mittels dem "HTTP_POST_FILES[]"-Array gegenchecken.
Keine alten Methoden bzw. Funktionen diesbezueglich verwenden!


4) Libraries
************

Diverses:

Oft werden Libraries innerhalb des "document-root Verzeichnisses" verwendet.
Programmierer neigen dazu Libraries mit ".cfg", ".inc" oA. Extensions zu benennen.

Problematik:

Libraries, die keine ".php"(oAe.) Extension haben, werden von PHP (im Normalfall) nicht interpretiert.

Demo-Library (mit absoluten pfad: /var/www/htdocs/lib/db.inc):

<?php
include("dbsuper.inc");
$db=db_connect("fridolin","PasswordIs!Unsafe","www.dbhost.com","kunden");

?>


Fazit:

Keine Libraries unter "htdocs".
Wenn doch(aus versch. Gruenden denkbar), nur "interpretierbare" Extensions verwenden bzw.
bei der Server-Konfiguration beruecksichtigen.

Demo-Apache-Config:

---cut here---

<Files ~ "\.phpincludes">
Order allow,deny
Deny from all
</Files>

---cut here---



5) Sonstiges, Anmerkungen
*************************

a) Sessions

- Bei Sessions den "php build-in session support" verwenden.

b) Cookies

- Keine sensitiven Informationen in Cookies speichern.
- Bei Authentifizierung mittels Cookies den Cookie immer bestmoeglich Verschluesseln.
- Keine Template-Informationen (Sprachcodes) in Cookies verwenden.

c) Arrays

- Arrays werden "global" wie alle andere Variablen behandelt und koenne natuerlich
genau wie "normale" Variablen vom Angreifer gesetzt und veraendert werden.


6) Zusammenfassung gefaehrlicher Funktionen
*******************************************

a) im Zusammenhang mit dem Ausfuehren von Code:

*** require()
*** include()
*** eval()
*** preg_replace() (mit "/e" Modifier)
*** exec()
*** passthru()
*** `` (backticks)
*** system()
*** popen()

b) im Zusammenhang mit Files:

*** fopen()
*** fpassthru()
*** readfile()
*** file()


*******************************************************************************
Alle weiteren Sprachen werden aus Gruenden der Aktualitaet nur kurs angerissen.
*******************************************************************************


**********************
Unix Shell CGI-Scripts
**********************

Sollten NIEMALS fuer Web-Apps verwendet werden.
Environment-Variablen und die meisten Argumente der verschiedensten
Shells (im Besonderen der "Bourne-Shell") sind ausserordentlich unsicher.

Eine Shell-Script Web-Applikation portiert von System A nach System B ist def. unsicher !!

Stichworte IFS u. BASH_ENV ...



**********************
Perl CGI Scripts
**********************

Abgesehen von den bereits unter (1 ALLGEMEIN) erwaehnt wurden gelten fuer Perl
im speziellen folgendes:


a) File OPEN
************

.. es gelten die gleichen Gesetzmaessigkeiten wie bei anderen Systemen ausser:

Das NULL-Byte ist in Perl EXTREM gefaehrlich und funktioniert(wenn nicht gefiltert) IMMER!

Demo-Code:

---cut here---

$database="$user_input.db";
open(FILE "<$database");

---cut here---

wird in diesem Fall $user_input nicht auf 0x00 gefiltert und auch sonst nicht besonders
geprueft ist es ein leichtes "../../../../etc/hosts\0" zu uebermitteln.

Obwohl die Perl-Variable "$database" den String "../../../../etc/hosts\0.db" enthaelt,
sieht das darunterliegende System (das nat. in C programmiert wurde) das NUL als String-Delimiter an!

*** Anm.: sysopen() verwenden.



b) OPEN OHNE MODUS
******************

Das Perl "open" Kommando kann in den verschiedensten Modi verwendet werden.
Leider wird es sehr oft ohne Modus verwendet!

Wird ungefilterter User-Input in ein solches "open" mit einbezogen ist ein Angreifer ohne
groesseren Aufwand in der Lage OS-Systembefehle auszufuehren.

Demo-Code:

---cut here---

$file_name = "/dira/".$user_input."/logfile.txt";
open(LOGFILE "$file_name");

---cut here---

"/bin/ls -alsi|" als $user_input wird eben dieses Kommando ausfuehren.


*** Anm.: sysopen() verwenden.



c) ANDERE BEFEHLE
*****************


*** glob

*** system (immer alle Argumente als Befehlsparameter angeben!)

bsp.: system("$befehl $arg $arg1"); ist FALSCH
system("$befehl", $arg, $arg1); ist hingegen RICHTIG

*** `` (backticks sind aufgrund der direkten shell gefaehrlicher als "system")

bsp.: "s/\.\.//g;" wird oft genutzt um Directory-Traversal Attacken zu vermeiden.
bei der Verwendung von Backticks kann diese Regex ganz eifach durch:
"/usr/tmp/.\\./.\\./etc/passwd" umgangen werden!

*** eval (wird oft fuer template-systeme missbraucht - sehr gefaehrlich)



***********************
Java Servlets u. JSPs
***********************

Java Servlets bzw. JSP s sind noch relativ jung. Abgesehen davon gelten allerdings
die gleichen Methoden und Fehlerquellen wie bei allen anderen Systemen.


Interessant sind folgende Aspekte:

a) NULL BYTES (in Verbindung mit Dateien)
*****************************************

Das allseits bekannte Null-Byte (\000 | %00) kann fuer klassische
Traversal-Attacken (siehe Perl) benutzt werden.

Jede Java-Klasse die die "File","RandomAccessFile" oder aehnliche Klassen benutzt
ist diesbezueglich gefaerdet!


b) SYSTEMBEFEHLE
****************

Natuerlich kann boesartiger User-Input im Zusammenhang mit System.Runtime Funktionalitaet
verwendet, und muss daher, vermieden werden.


c) CHARACTER ENCODING
*********************

Da Java Unicode (UTF-*) unterstuetzt ist es denkbar, dass Servlets fuer Attacken ala
IIS - Unicode anfaellig sind.
(Mom. gibt es diesbezueglich aber noch keine gefundenen Fehler)

Anm.: dazu: 0x00 (single-octet sequence) fuer "NULL"
0xC0 80 (ist auch NULL !!!)


Java-Fazit:

Mit einem gut konfigurierten "Security-Manager" kann EXTREM VIEL Last von den Schultern
des Programmierers genommen werden!

Konfiguriert werden koennen:

* Security Permissions
* Runtime Permissions (System exec,fork ...)
* File Permissions (Lesen und Schreiben von Datein und Verzeichnissen)
* Socket u. Net Permissions (Netzwerkverbindungen in, out / host:port etc)

Wird eine dieser "Policies" verletzt erfolgt eine SecurityException.
Das Servlet bzw. JSP hat keine Moeglichkeit sich ueber die Security Policies
hinwegzusetzen.


*** Anmerkung zu Java-Applets:

Java-Applets koennen hervorragend zur Erweiterung der "miserablen" Browser-Funktionalitaet
verwendet werden.

ABER

Applets sollten NIE fuer sicherheitsrelevante Aufgaben herangezogen werden!.
Es ist ein leichtes eine Applet-Klasse downzuloaden und anschliessend zu decompilieren.

HTTP-Requests des Applets and den Server lassen sich so hervorragend analysieren und
missbrauchen!



***********************
C u. C++ CGI Programme
***********************

Nicht bes. relevant, deswegen in Stichworten:

Zusaetzlich zur allgemeinen Eingabeueberpruefung muss in C bzw. C++ ganz besonders auf
die Laenge der jeweiligen Parameter geprueft werden.

"Bounds Checking"

Funktionen die soweit als moeglich zu meiden sind:

strcpy
strcat
sprintf
vsprintf
gets

strlen (ausser wenn NIL char)

scanf()
fscanf
sscanf
vscanf
vsscanf
vfscanf

realpath
getopt
getpass
streadd
strecpy
strtrns

getwd (buffer mind PATH_MAX bytes laenge)

Bufferueberlauf-Exploits sind in der Erstellung zwar etwas langwierig,
richten aber in den meisten Faellen groesseren Schaden als Script-Fehler an!
(Das Ausfuehren von Systembefehlen ist Standard fuer dei Meisten Fehler dieser Art)

Das Einrichten bzw. Nutzen einen "nicht ausfuehrbaren Stacks" ist in diesem Zusammenhang
eine sinnvolle Schutzmassnahme (bedingt in Bezug auf Heap- uA. -basierende Ueberlaufe!)


********************************
Phyton CGI-Scripts
********************************

Nur in Stichworten (gefaehrliche Befehle):

*** exec()
*** eval()
*** execfile()
*** compile()
*** input()



********************************
ANHANG Datenbanken SQL INJECTION
********************************


Fast alle Web-Applikationen verwenden Datenbanken.

Mittels verschiedenster

Libraries(PHP),
Module(Perl/DBI)
und Klassen(Java/JDBC)

lassen sich Datenbanksysteme bequem ansprechen, editieren und verwalten.

Eine Web-App-Datenbankabfrage geht normalerweise folgendermassen vonstatten:

1) Das Programm/Script verbindet sich mittels Uid/Pwd/Host/etc mit der DB.
2) Ein SQL-Query wird an die DB geliefert (und committed, wenn notwendig)
3) Die DB liefert ein Result-Set (inkl. verschied. Retourcodes)

Natuerlich wird in vielen Faellen User-Input an den DB-Query uebergeben.

Wird dabei die Eingabeueberpruefung vernachlaessigt, hat ein Angreifer die Moeglichkeit
unseren DB-Query zu veraendern bzw. zu Erweitern.

Dabei gilt IMMER:

Wenn ich nicht 100% sicher bin, dass der User-Input gecheckt und "sanitized" wurde,
muss das jeweilige(uebergebene) "Feld" "gequotet" werden!

Die meisten DB-Libs. bzw. Module bieten fertige Funktionen dafuer an. Diese sollten
dann auch verwendet werden.

Wird auf diesen "wichtigsten" Arbeitsschritt im Zusammenhang mit DB-Zugriffen von Web-
Applikationen vergessen, kann das in Abhaengigkeit des verwendeten DB-Systems u. Interfaces
zu grossen Sicherheitsproblemen fuehren.


Beispiel fuer schlechten PHP-Code dazu:

<?php
// logi.php
//
// rhabarber ...

phpconnect();

$query = "SELECT uid,pwd FROM USER WHERE uid='$uid' AND pwd='$pwd'";
do_query($query);

// do something if found :-/
// usw.
?>

Ein Request wie der folgende:

"http://server/logi.php?uid=admin';--"

authentifiziert uns sofort!


Obiges Beispiel ist nicht besonders komplex und laesst sich je nach Situation
in die verschiedensten Richtungen erweitern.

Es ist nur ein kleiner Einstieg in dieses ausserordentlich umfangreiche Thema.

Im Normalfall benutzt der Angreifer die Fehlermeldungen des jeweiligen DB-Interfaces
zu "disassemblieren" der Datenbank und Teilen der Web-Applikation.

zbsp:

"http://server/logi.php?uid=admin'+group+by+(uid);"

.. wird in den meisten faellen (ausg. MySql) die Fehlermeldung:
"'schema.fieldxyz' is invalid in the select list ... bla bla group by .. aggregate function .. bla "

zeigt dem Angreifer, dass es auch 'schema.fieldxyz' in der DB gibt.

der naechste Query dann:

"http://server/logi.php?uid=admin'+group+by+(fieldxyz,uid);"

.. wird in den meisten faellen (ausg. MySql) die Fehlermeldung:
"'schema.datxxx' is invalid in the select list ... bla bla group by .. aggtregate function .. bla "

.. so tastet sich der Angreifer durch die komplette Datenbankstruktur (abgesehen davon, dass
das ganze meistens ueber die SYSTEM-Tabellen auch leichter geht)


Abhaengig von Datenbanksystem und SQL Sprachschatz laesst sich mit einem gut
modifizierten SQL-Statement fast alles, bis hin zu Systembefehlen, erreichen.

Zusammenfassend die wichtigsten "Schwaechen" der einzelnen Datenbanken:


MYSQL
*****

.. unterstuetzt die Syntax:

- "INTO OUTFILE 'filename'". (extrem gefaehrlich)

.. und

- ist leider sehr oft unter user "root" gestartet.

+ Die meisten Module und Libraries unterstuetzen keine Multiple-Statements.

Anm.: "INTO OUTFILE" in Verbindung mit "root" laesst uns (beliebige) Files als User-"root"
erzeugen. !!!

In Bezug auf Sicherheit von Web-Applikationen ist das fehlende "UNION"
und die fehlenden "SUBSELECTS" (leider) als positiv zu bewerten ?!



ORACLE
******

.. unterstuetzt je nach verwendeten Interface:

- "HOST" (@fuer systemcmds)
- subselects
- UNION
- STORED PROCEDURES
- typecasting

+ Die meisten Module und Libraries unterstuetzen keine Multiple-Statements.


DB2
***

.. unterstuetzt je nach Interface:

- "IMPORT, EXPORT" (File Import u. Export)
- subselects
- UNION
- STORED PROCEDURES
- typecasting

+ Die meisten Module und Libraries unterstuetzen keine Multiple-Statements.



POSTGRESQL
**********

.. unterstuetzt je nach Interface:


- "COPY" (File Export u Import)
- subselects
- UNION
- STORED PROCEDURES
- typecasting

- leider unterstuetzen sehr viele Module und Libraries Multiple-Statements.

Anm.: Multiple-Statements in Verbindung mit "COPY" ist eine EXTREM gefaehrliche Mischung!


MSSQL
*****

.. unterstuetzt je nach Interface:

- subselects
- UNION
- STORED PROCEDURES
- typecasting

- leider unterstuetzen fast alle Module und Libraries Multiple-Statements.

Anm.: Multiple-Statements in Verbindung mit den "default-stored-prcedures" von MSSQL ist sehr gefaehrlich!

Leider wird MSSQL mit extrem vielen "STProcedures" ausgeliefert. Mit Hilfe dieser Funktionen lassen
sich ohne grossen Aufwand .. zb.:

neue User anlegen (sp_adduser)
oder System-CMDs ausfuehren (xp_cmdshell)

uvam.



*********

deswegen auch: soweit als Security-relevante Informationen NICHT Plain-Text in der Datenbank speichern.











Home  Services  Contact  Projects  Whitepapers  Tools  Partners