Maßnahmen für sichere Webseiten

erstellt am: 15.05.2010 in Kategorie(n): Websicherheit

Nachdem ich bereits einige bekannte Angriffsfahren und die aktuelle Sicherheitslage aus dem Jahr 2009 betrachtet habe, möchte ich in diesem Artikel nun versuchen zu erklären, was man gegen solche Sicherheitslücken tun kann und wie man vor allem als Programmierer von Webseiten seinen Code so erstellt, dass Sicherheitslücken gar nicht erst auftreten. Für die von euch, die Zugriff auf die Konfiguration des Webservers und des Datenbanksevers haben, sage ich auch noch kurz etwas zur sicheren Konfiguration zum Vermeiden von Sicherheitslücken. Dieser Bericht ist Teil einer meiner Arbeiten im Studium und auch im Wiki der FH veröffentlicht worden. Ich möchte ihn nun auch auf meinem Blog zur Verfügung stellen.

Validierung der Eingaben

Da die meisten Angriffe auf Eingaben basieren, ist eine Validierung der Daten enorm wichtig für die Sicherheit einer Webanwendung. Die Daten sollten nie unkontrolliert zur Verarbeitung weitergegeben werden. Die Eingabenvalidierung ist min. serverseitig durchzuführen. Eine einfache Validierung der Eingaben verhindert schon eine Menge an Angriffsmöglichkeiten. Es gibt verschiedene Arten eine Validierung durchzuführen. Einfach aber trotzdem effektiv sind die Dekodierung und die Typüberprüfung von Eingabedaten. Auch durch die Maskierung von Eingaben lassen sich Sicherheitslücken erfolgreich schließen. Die Filterung ist mit einer der effektivesten Validierungsform. Auch die Ausgaben vom Server zum Client sollten validiert werden. Die folgenden Punkte erläutern die Arten der Eingabevalidierung.

Dekodierung

Da die Daten bei der Übertragung der Request-Parameter oft in unterschiedlichen Varianten enkodiert sind, sollte man diese stets vor der Weiterverarbeitung dekodieren. In einigen Sprachen passiert diese Dekodierung automatisch.

PHP

urldecode()

Diese Funktion kann verwendet werden, um die Übergabeparameter zu dekodieren. Aber Vorsicht bei PHP sind die Supergoals $_GET und $_REQUEST bereits dekodiert. Eine weitere Dekodierung kann Auswirkung auf den Programmablauf haben.

$var=urldecode($_POST['name']);

Java

Java bietet eine Klasse names URLDecoder im Package java.net. Diese Klasse enthält eine Methode decode(), mit der die Parameter dekodiert werden können.

name = request.getParamter("seachName");
name = URLDecoder.decode(name,"UTF-8");

ASP.NET

Bei Webframework ASP von Microsoft für .NET werden die Parameter automatisch dekodiert, wenn man folgenden Aufruf tätigt.

<%= Request.QueryString("name") %>

Typüberprüfung

Die Überprüfung des Datentyps ist eine einfache, aber wirkungsvolle Methode. Dabei werden die Übergabeparameter, durch CAST-Operatoren umgewandelt. Beispielsweise ist eine ID meist vom Typ Integer. Ein Cast sollte also problemlos möglich sein. Ist die ID manipuliert und enthält beispielsweise Zeichen vom Typ Charakter, wird das Casten einen Fehler erzeugen. Diese Fehler sind gewollt, da damit die Eingabe verworfen wird und Angriffe somit nicht mehr möglich sind. Diese Methode funktioniert aber nicht bei allen Übergaben. Oft werden IDs in Form von Hashwerten angegeben. Diese Werte lassen sich nicht in den Typ Integer casten.

Maskierung

Bei der Maskierung werden vor allem Funktionszeichen in den Übergabe-Parametern maskiert. Funktionszeichen können beispielsweise ein Slash (/ oder \), Anführungszeichen (“), Hochkommas (‘) oder auch Semikolons (;) sein. Kommen diese Zeichen in einer Zeichenkette vor, werden sie mit einem Backslash (\) maskiert. Dieser Backslash wird vor dem Funktionszeichen angefügt und somit als Text gekennzeichnet. Diese Zeichen verlieren ihre Bedeutung und das Kommando ist nicht mehr ausführbar. Die sogenannten Escape-Funktionen sind in den meisten Programmiersprachen vorhanden. In einigen wird eine Maskierung sogar automatisiert vorgenommen. In PHP gibt es die Möglichkeit in der Konfiguration den Flag magic_quotes_gpc zu setzten. Ist dieser aktiviert, übernimmt PHP automatisch die Maskierung von Übergabeparametern. Mehr dazu in Punkt Serverkonfiguration. In einigen Fällen lässt sich die Maskierung umgehen. Beispielsweise gibt es einige Kommandos, die sich auch ohne Anführungszeichen oder Hochkommas ausführen lassen. In JavaScript gibt es eine Alternativschreibweise für Strings.

var str=/dies ist ein String/.source

Auch bei SQL-Statements können die Anführungszeichen umgangen werden, indem man den String als Hexadezimalwert angibt.

SELECT * FROM user WHERE username=0x61646D696E

Es gibt unterschiedliche Funktionen in den Programmiersprachen, die es ermöglichen spezialisiert zu maskieren. Zu den Referenzsprachen sollen die jeweiligen Maskierungsfunktionen im folgenden nur genannt werden.

PHP

addslashes();
quote_meta();
mysql_real_escape_string();
strip_tags();
htmlentities();
utf8_decode();

Java

class java.sql.PreparedStatement;
java.net.URLEncoder.encode();

ASP.NET

Request.Form()
Request.QueryString()
Request.Cookies()
RangeValidator()
RegularExpressionValidator()
Server.HTMLEncode()
Server.URLEncode()

Filterung

Eine Filterung der Datenströme ist sinnvoll, wenn bestimmte Sonderzeichen erlaubt werden müssen, um die Funktion der Seite nicht zu beeinträchtigen. Zum Beispiel, wenn einige HTML-Tags zum Formatieren zur Verfügung stehen sollen. Was gefiltert wird und wie diese Filterung erfolgt, sollte genau überlegt sein. Zu wenige Einschränkungen lassen weitere Angriffstaktiken zu und zu viele Einschränkungen können zu Fehlern im Ablauf führen.

Eine Filterung kann schon das Prüfen der Größe des Datenstroms sein. Diese Art von Filterung lässt sich gut bei kurzen Strings anwenden, die immer nach einem gleichbleiben Muster generiert werden. Eine Festlegung der maximalen Länge ist eine solche Filterung. Bei Großen Strings ist diese Einschränkung nicht mehr von Nutzen, da in langen Zeichenketten problemlos kurzer Programmcode enthalten sein kann.

Eine andere Filterungsvariante ist die Filterung nach regulären Ausdrücken. Diese Validierungsart ist eine der erfolgreichsten Maßnahmen gegen Angriffe. Dabei werden Muster oder Schablonen erstellt, die eine erlaubte Zeichenkette beschreiben. Diese Zeichenketten können exakt spezifiziert werden. Viele Programmiersprachen bieten bereits vordefinierte Möglichkeiten um solche Filter zu erstellen. Die Filterung kann nach zwei Prinzipien erfolgen. Entweder per Blacklisting oder per Whitelisting.

Blacklisting

Hierbei werden die Zeichen definiert, die herausgefiltert werden sollen. Alle anderen Zeichen werden weiterhin durchgelassen. Potenziell gefährliche Zeichen, wie die schon erwähnten Sonderzeichen ” ‘ < > können so behandelt werden. Das Angeben von expliziten Ausdrücken ist auch eine Möglichkeit beim Blacklisting. Ein Beispiel hierzu ist die Filterung auf SQL-Funktionen wie SELECT, DELETE, DROP etc. Das Problem beim Herausfiltern solcher Zeichen oder Zeichenketten ist, dass sie in einigen Anwendungsfällen teileweise erwünscht sind. In Foren werden oft einige HTML-Tags benötigt. Allerdings gelten die Tag-Begrenzer < und > als potenziell gefährliche Zeichen. Die Lösung dieses Problems ist eine eigene Markup-Sprache, die eigene Tags definiert. Bei der Ausgabe zum Client werden diese Tags in HTML-Tags umgewandelt. Der HTML-Tag könnte zu {bold} umgewandelt werden. Ein weiteres Problem taucht häufig bei englischsprachigen, langen Eingaben auf. Hier sind Zeichenketten wie “select”, “delete” oder “drop” durchaus verwendete Wörter, die keine bösen Absichten haben. Daher sollte man eine andere Form der Validierung vornehmen.

Whitelisting

Dieses Prinzip ist das Gegenteil des Blacklisting. Es werden nur die Zeichen definiert, die erlaubt sind. Alle anderen Zeichen werden nicht durchgelassen. Hierbei sollte man sich genau überlegen welche Ausdrücke benötigt und somit erlaubt werden.

In den meisten Fällen ist das Whitelisting gegenüber den Blacklisting zu bevorzugen. Es stellt sicher, das keine anderen Ausdrücke als die Definierten verwendet werden. Vor allem bei Eingabefeldern ist das Whitelisting eine gute Methode.

Bisher wurden nur die Eingaben betrachtet. Aber auch die Ausgaben zum Client sollten gefiltert werden. Damit wird sichergestellt, dass Codefragmente, die trotzdem zum Server durchgedrungen sind, nicht im Browser des Clients ausgeführt werden. Hierbei reicht es in den meisten Fällen, wenn Sonderzeichen durch deren Name Charackter Referenz ersetzt werden.

<  ==> &lt;
>  ==> &gt;
'  ==> &#39;
"  ==> &quote;
 
<script>  ==> &lt;script&gt;

Das Beispiel des Script-Tag zeigt, wie die Ausgabe beim Client erfolgt. Durch das Ersetzen der Sonderzeichen, wird kein JavaScript innerhakb der Tags ausgeführt. Im Fall des Beispiels, mit der eigenen Markup-Sprache für zulässige HTML-Tags, werden die kompletten Tags in einen HTML-Tag umgewandelt und vom Browser interpretiert und ausgegeben.

{bold}  ==> <bold>

Wichtig hierbei ist, dass der komplette Tag ersetzt wird und nicht nur die umschließenden Quotes.

Maßnahmen gegen Fehler

Es gibt verschieden Arten, wie mit auftretenden Fehlern in der Validierung umgegangen werden kann. Wichtig ist, dass die Fehlerbehandlung benutzerfreundlich erfolgt. Hierbei sollte man allerdings so wenig Information wie möglich freigeben. Prinzipiell ist jede Fehleingabe abzulehen. Allerdings können falsche Eingaben auch von der Anwendung behandelt und korrigiert werden. Der Nutzer sollte bei einer Ablehnung freundlich auf den Fehler hingewiesen werden und Informationen zur korrekten Anwendung bekommen. Bei offensichtlichen Angriffen, ist es sinnvoll, Daten des Angreifers zu protokolieren. Dem Angreifer könnte, nach einer bewussten Fehleingabe, eine Warnung angezeigt werden, die auf das Mitschneiden seiner IP oder anderen Erkennungsmerkmalen hinweist und Maßnahmen anzeigt, die getroffen werden könnten. Eine Alternative ist die Verarbeitung zu blockieren, den Angreifer aber trotzdem einen ordnungsgemäßen Ablauf vorzutäuschen, um ihn das Suchen nach weitern Sicherheitslücken zu erschweren (siehe Information Leackage).

Session Management

Gerade in geschützten Bereichen einer Web-Applikation, sind sichere Sessions besonders notwendig. Um eine Übernahme der Session zu vermeiden, sind vor allem sichere SessionsIDs zu verwenden. Eine solche ID kann über Cookies oder direkt in der URL übertragen werden. Im zweiten Fall sollte ein URL-Rewriting angewandt werden.

Cookies

Cookies sind häufig Träger einer Session ID und sollten für einen sicheren Transport der ID auf einen minimalen Aktionsradius begrenzt und über eine gesicherte Verbindung übertgragen werden. Cookies sind leicht angreifbar. Mit JavaScript lassen sich ungeschützte Cookies auslesen. Bei falscher Behandlung von Sessions, können Informationen zur Session ausgelesen werden und der Angreifer hat die Möglichkeit sich ein eigenes Cookie im Browser zu erzeugen und somit die Session zu übernehmen.

eine gute Definition eines Cookies könnte wie folgt aussehen:

setCookie: SESSIONID = abc123efsd346fgs890twei4e3irweifj243d3ojfg4og4jmfvoe4; 
                       path = /myApplication; secure; httpOnly;

Ein gutes Cookie sollte immer auf die Anwendung beschränkt werden. Damit wird ermöglicht, dass eine Session im Fall einer Übernahme nicht auch für andere Bereiche anwendbar ist. Domain-Cookies, die für die ganze Domain verfügbar sind und an jedem Host geschickt werden, sind zu vermeiden. Mit dem Parameter path kann eine Einschränkung des Cookies durchgeführt werden. Das secure-Flag stellt sicher, dass das Cookie nie über eine ungesicherte Verbindung übertragen wird.

mit dem Flag httpOnly wird das Auslesen des Cookies mit JavaScript verhindert. Diese Funktion wird nicht von allen Browsern unterstützt. Gerade bei älteren Browsern kann es zu Problemen kommen. Im schlechtesten Fall kommt es zu einem Syntaxfehler und die Session wird abgebrochen.

URL-Rewriting

Eine SessionID kann auch über das URL-Rewriting übertragen werden. Hierzu wird die ID in der URL mit angegeben und bei jedem Seitenwechsel mitgegeben. Mit dem URL-Rewriting kann die URL so maskiert werden, das die ID nicht mehr sichtbar ist oder eine andere Form bekommt.

http://www.meinedomain.de/index.php?sid=43t4e9wrgj53g94rgj24ofj3w4gm4fgvwefew4

wird zu:

http://www.meinedomain.de/index.php

oder:

http://www.meinedomain.de/43t4e9wrgj53g94rgj24ofj3w4gm4fgvwefew4


Softwareload - Ihr Download-Shop für Software

Sichere Session

Für eine sichere Session sind vor allem sichere SessionIDs notwendig. Eine SessionID sollte daher so gewählt werden, dass sie an den Benutzer angepasst und nur den Benutzer zugeordnet werden kann. Die folgenden Punkte helfen beim Erstellen einer sicheren SessionID.

  • Eine SessionID sollte niemals aus enkodierten Benutzerdaten bestehen (SID=MaxMustermann01.01.2009).
  • Eine sehr lange SID erschwert das Abschreiben oder erraten (Brute-Forcing).
  • Kodierte, kryptische IDs sind sicherer, da sie keine Rückschlüsse auf ihre Zusammenstellung geben.
    • IP-Adressen in der SessionID identifizieren den Benutzer eindeutig.
    • Probleme gibt es mit dieser Methode bei der Verwendung von Proxys, da die IP im Laufe einer Session wechseln kann. Einige Provider arbeiten mit einem Proxyverbund, was diese Methode als Sicherung einer Session erschwert.
    • Gut geeignet ist die Verwendung von IP-Adressen in der SessionID bei Anwendungen im Intranet
  • Die Verwendung von Browserdaten, wie Version, Spracheinstellungen oder Ähnliches erschweren die Übernahme einer Session.
  • Eine SessionID sollte für jede Session einmalig sein.
    • Die Lebensdauer einer SessionID sollte unbedingt beschränkt werden.
    • Hard-Time-Out: Die Lebensdauer wird beschränkt. Eine Session besteht nur für eine bestimmte Zeit.
    • Soft-Time-Out: Die Session wird bei Inaktivität des Benutzers nach einiger Zeit beendet.
    • Nach Beendigung durch das System, sollte die SessionID zerstört werden.
  • Der Benutzer sollte immer aufgefordert werden ein Logout durchzuführen, um die Session ordnungsgemäß zu beenden.
  • Diese Möglichkeiten sorgen für eine Sichere SessionID. Es existieren allerdings noch weiter Varianten um eine Session zu sichern. Bei einer Kombination von Session-Handling mit Cookies und URL-Rewriting erhöt sich der Schutz vor einer Übernahme der Session durch einen Angreifer. Dabei wird eine weitere zufällig generierte ID (SessionCode) erzeugt, die bei der Erzeugung der Session mit eingefügt wird. Des Weiteren wird der SessionCode, entweder in der URL oder durch ein Hidden-Field in einer Form, bei einem Seitenwechsel als Parameter mitgegeben. Nach jedem Seitenwechsel, wird überprüft ob der übergebene SessionCode noch mit dem Wert der Session übereinstimmt.

    Noch sicherer wird die Variante, wenn Token anstatt eines SessionCodes verwendet werden. Der Unterschied zwischen beiden Varianten besteht darin, dass ein Token bei jeder Aktion dynamisch neu erstellt wird. Ein SessionCode wird hingegen zu Beginn einer Session statisch erzeugt und ändert sich im Verlauf nicht.

    Serverkonfiguration

    Bereits bei der Konfiguration der Server können Maßnahmen zur Sicherheit von Webanwendungen getroffen werden. Bestimmte Einstellungen sollten angepasst werden, um Sicherheitslücken schon beim Einrichten der Umgebung zu schließen.

    Webserver

    Der Webserver bietet einige Möglichkeiten um eine Webanwendung sicherer zu machen. Nach erfolgreicher Installation des Servers sollten alle für den Betrieb nicht relevanten Teile entfernt werden. Hierzu zählen beispielsweise Dokumentationen, Testseiten, Beispiele oder Installationsdateien. Für die sichere Konfiguration eines Webservers, sollten vier wichtige Punkte beachtet werden. Der erste Punkt ist die Einschränkung von Benutzerkennung und Zugriffsrechten. Dabei wird verhindert, dass ein Angreifer im Fall einer Server-Kompromittierung nicht auf weitere Systeme (Betriebssystem) zugreifen kann. Der zweite wichtige Punkt ist, dass so wenig interne Informationen wie möglich veröffentlicht werden. Unnötige Informationen darf der Server nicht veröffentlichen. Auch die Fehlermeldungen dürfen keine Details zur Serverkonfiguration preis geben. Das Trennen von Verzeichnissen für Programme und Daten ist ein weiterer Punkt, der beachtet werden sollte. Skripte der Serverkonfiguration sollten nie im gleichen Verzeichnis liegen wie Daten. Punkt Vier bei der Einrichtung eines Webservers ist das Loggen von Informationen. Angriffe oder Angriffsversuche sollten gut protokolliert werden, damit der Administrator Angriffe nachvollziehen und Sicherheitslücken schnellstmöglich schließen kann. Im weitern Verlauf werden einige Möglichkeiten beschrieben, die einen Webserver sicherer machen. Die Beispiele beziehen sich auf den Apache Webserver.

    Serverinforamtionen

    ServerSignature     Off
    ServerTokens        ProductOnly
    ExtendedStatus      Off

    Die Serversignatur sollte auf Off gestellt werden, da sonst unter Umständen die Versionsnummer und der Servername nach außen dringen können. Die Einstellung ProduktOnly bei den ServerToken gibt ebenfalls Inforamtionen zum Server preis. In diesem Fall wird nur der Name des Servers an den Client weitergegeben (Apache statt Apache/2.0). Der Parameter ExtendedStatus gibt im Fall einer Aktivierung Informationen zum Status von Requests an und sollte daher abgeschaltet werden.

    Verzeichnisse

    ServerRoot        /ServerRoot
    DocumentRoot      /DocumentRoot/htdocs
    ScriptAlias       /cgi-bin/ "/ProgramRoot/"
    <Directory "/ProgramRoot"> 
       Options         None 
       AllowOverride   None 
       Order           allow,deny 
       Allow from      all 
      <LIMIT GET POST> 
        Order          allow,deny 
        Allow from     all 
      </LIMIT> 
      <LIMITExcept GET POST> 
        Order          deny,allow 
        Deny from      all 
      </LIMIT>
    </Directory>

    Wie schon erwähnt, sollten die Verzeichnisse für die Installationsdateien des Servers und die Dokumente getrennt werden. Das sollte bei der Konfiguration des Servers beachtet werden. ServerRoot und DocumentRott sollten nie den gleichen Pfad besitzen. Die weiteren Einstellungen beziehen sich auf die Zugriffsrechte für Skripte.

    Zugriffsrechte für Verzeichnisse

    <Directory /> 
      Options             None 
      AllowOverride       None 
      LimitRequestBody    204800 
      LimitRequestFields  50 
      Order               deny,allow 
      Deny from           all
    </Directory>
    <Directory "/DocumentRoot/htdocs"> 
      Options +FollowSymLinks -ExecCGI -IncludesNOEXEC 
      AllowOverride       None 
      <LIMIT HEAD GET POST> 
        Order             allow,deny 
        Allow from        all 
      </LIMIT> 
      <LIMITExcept HEAD GET POST> 
        Order               deny,allow 
        Deny from           all  
      </LIMIT>
    </Directory>

    In diesem Beispiel werden zunächst alle Zugriffsrechte für DocumentRoot so konfiguriert, dass sie explizit erlaubt werden müssen. Im zweiten Teil werden diese Zugriffsrechte dann für das Verzeichnis zum DocukmentRoot beschrieben. Die Zugriffsmethoden werden hierbei auf HEAD, GET und POST beschränkt.

    Zugriff auf bestimmte Dateien schützen

    AccessFileName .htaccess
    <Files ~ "^\.ht"> 
      Order allow,deny 
      Deny from all 
      Satisfy all
    </Files>
    <FilesMatch "\.(old|bak|tar|tgz|gz|inc|cfg|conf)$"> 
      Order allow,deny 
      Deny from all
    </Files>

    Die Konfigurationsdatei von Apache sollte von außen nicht sichtbar sein. Daher wird der Zugriff auf diese Datei verhindert. Zuerst wird der Dateiname angegeben und im weiteren Verlauf der Zugriff auf die Datei unterbunden. Des Weiteren werden einige weiteren Dateien für den Zugriff gesperrt. Diese Dateien werden anhand der Endung identifiziert.

    Begrenzung von Größen für den File upload

    SetEnvIf Content-Length "[1-9][0-9]{4,}" too_large=1
    <Loction /upload> 
      Order Deny,Allow 
      Deny from env=too_large 
      ErrorDocument 403 /DocumentRoot/htdocs/upload_too_large.html
    </Location>

    Vor allem um Denial of Service Attacken zu vermeiden sind Begrenzung von Dateigrößen sinnvoll. In diesem Beispiel wird die Umgebungsvariable angepasst.

    Datenbankserver

    Ähnlich wie der Webserver sollten auch die Datenbankserver gesichert werden. Dabei sind vor allem die Zugriffs- und Nutzerrechte zu beachten. Eine Datenbank sollte immer einen eigenen Benutzer für die Administration, der nicht dem Systembenutzer entspricht, besitzen. Im Allgemeinen hat jede Datenbank bereits einen eigenen, vordefinierten Administrationsbenutzter (beispielsweise root, administrator oder sa). Dieser Nutzer hat Zugriff auf alle Datenbanken und deren Tabellen. Aus diesem Grund sollte die Nutzerkennung immer ein besonders sicheres Passwort zugeteilt bekommen und nur vom localhost zugreifen können. Dieses Passwort muss vom Betreiber gesetzt werden. Außerdem ist es zu empfehlen den Administratorzugang niemals zum Aufrufen der Datenbank aus der Applikation heraus zu verwenden. Für den Aufruf der Datenbank in der Applikation gibt es die Möglichkeit jeder Datenbank eigene Nutzungs- und Zugriffsrechte zu geben. Um die Sicherheit eines Datenbankservers weiter zu erhöhen, sollte der Zugriff auf Systemtabellen und Systemfunktionen weitestgehend verboten werden, da über diese Tabellen und Funktionen die Datenbankstruktur leicht auslesbar ist.

    Beispiel MySQL

    Bei MySQL ist in der Regel bereits ein eigener Benutzer zur Administration vorhanden. Allerdings sollte das Vorhandensein zur Sicherheit überprüft werden.

    USE mysql;
    SELECT * FROM user WHERE User='root';

    Anschließen bekommt der Benutzer root ein individuelles, sicheres Passwort und den Host, von dem er zugreifen kann, zugewiesen.

    USE mysql;
    UPDATE user SET Host='localhost' WHERE User='root';
    UPDATE user SET Password=password('rootpsw') WHERE User='root';

    Das Anlegen von einzelnen Nutzern lässt sich bei MySQL wie folgt realisieren.

    USE mysql;
    INSERT INTO user SET Host='www.applikation.de',User='appUser',
                                   Password=password('appPsw');
    INSERT INTO db SET Host='www.applikation.de',User='appUser',Db='app';

    Um den Zugriff auf die Systemtabellen und -Funktionen von MySQL zu verhindern, müssen nur die Rechte der Benutzter angepasst werden. Alle Benutzer, die nicht dem Administrator entsprechen bekommen keine Rechte.

    USE mysql;
    UPDATE user SET Select_priv='N' WHERE NOT (User='root');
    UPDATE user SET Insert_priv='N' WHERE NOT (User='root');
    UPDATE user SET Update_priv='N' WHERE NOT (User='root');
    UPDATE user SET Delete_priv='N' WHERE NOT (User='root');
    UPDATE user SET Create_priv='N' WHERE NOT (User='root');
    UPDATE user SET Drop_priv='N' WHERE NOT (User='root');
    UPDATE user SET Reload_priv='N' WHERE NOT (User='root');
    UPDATE user SET Shutdown_priv='N' WHERE NOT (User='root');
    UPDATE user SET Process_priv='N' WHERE NOT (User='root');
    UPDATE user SET File_priv='N' WHERE NOT (User='root');
    UPDATE user SET Grant_priv='N' WHERE NOT (User='root');
    UPDATE user SET Index_priv='N' WHERE NOT (User='root');
    UPDATE user SET Alter_priv='N' WHERE NOT (User='root');


    PHP-Umgebung

    Bei der Konfiguration der PHP-Umgebung lassen sich einige Maßnahmen für eine sichere Webanwendung treffen. Die sichere Konfiguration ist keineswegs leicht zu realisieren, da sie immer vom individuellen Einsatzfall abhängig ist. Es gibt also keine Masterlösung für eine sichere PHP-Umgebung. Grundlegend ist die Basiskonfiguration von PHP immer zugunsten der Benutzerfreundlichkeit eingestellt. Diese Einstellungen lassen sich in der php.ini manuell verändern.

    Wichtige Punkte, die in der PHP-Umgebung angepasst werden sollten, sind die Signatur und die Logdateien.

    expose_php = Off 
    display_errors = Off 
    error_reporting = E_ALL

    Mit diesen Einstellungen lässt sich verhindern, dass PHP einerseits Informationen über die Version preis gibt und anderseits Fehlermeldungen direkt zum Client weiterleitet. Die dritte Einstellung bewirkt das Loggen aller Fehler in einer Log-Datei.

    Der Umgang mit Variablen sollte gesichert werden um Sicherheitslücken zu verhindert. Globale Variablen stellen zum Beispiel ein Risiko dar. Daher sollten folgende Einstellungen vorgenommen werden.

    register_globals = Off 
    variables_order = "EPS"

    Der Wert register_globals war bis zur Version 4.2 standartmäßig auf On gestellt. Seit dieser Version ist er zwar auf Off gesetzt, wird aber häufig umgeändert um ältere Anwendungen weiterhin lauffähig zu halten. Ist dieser Wert aktiviert, lassen sich Übergabe-Parameter als globale Variable auslesen. Eine gute Erklärung ist [hier] zu finden. Die zweite Funktion legt die Reihenfolge der Variablen fest. Gerade wenn die Funktion register_globals aktiviert ist, kann die Reihenfolge relevant sein. Bei gleichnamigen Übergabe-Parametern wird die Variable genutzt, die zu erst angegeben ist. In diesem Fall sollte der Wert EPS verwendet werden. Hierbei steht E für Evironmentvariablen, P für POST und S für SERVER. Voraussetzung für den Sicherheitsaspekt ist eine sichere Konfiguration des Webservers.

    Auch bei den Sessions lassen ich in der php.ini Einstellungen tätigen, die für die Sicherheit relevant sind.

    session.save_path = /ProgramRoot/conf 
    session.save_handler = files 
    session.gc_maxlifetime= 60 
    session.cookie_lifetime = 3600

    In der Standardkonfiguration liegen die Session-Daten in einer Datei im Verzeichnis temp (bei Windows) oder tmp (bei Unix). Diese Verzeichnisse haben allerdings Schreib- und Leserechte. Session-Daten könnten somit unter Umständen ausgelesen werden. In den ersten beiden Zeilen wird ein neuer sicherer Pfad bestimmt, indem die Session-Daten als Datei (session.save_handler = files) abgelegt werden. Die max. Lebensdauer der Session sollte von einen Tag auf eine Stunde herabgesetzt werden. Auch besteht die Möglichkeit, die max. Lebensdauer der Cookies einzustellen.

    Eine Einstellung, die sowohl Vorteile als auch Nachteile bietet, ist das Maskieren von Übergabedaten.

    magic_quotes_gpc = On

    Diese Einstellung ermöglicht eine automatische Validierung von Übergabe-Parametern. Dabei werden Sonderzeichen, wie beispielsweise das Hochkomma und die die Anführungszeichen, mit einem Backslash maskiert. Dieser Backslash eliminiert die Funktionalität des Zeichens und gibt dieses als normalen Text weiter. Ob die Einstellung aktiviert oder deaktivert werden sollte, ist je nach individuellem Fall zu entscheiden. Bei einer Aktivierung, können XSS- oder SQL-Injection-Angriffe vermieden werden. Allerdings können bestimmte escape-Funktionen für die Validierung von SQL-Statements dann nicht mehr korrekt ausgeführt werden. Im Allgemeinen sollte diese Funktion aber aktiviert sein.

    Die vorherigen Beispiele sind nur ein Teil der Möglichkeiten um eine PHP-Konfiguration sicher zu machen. Es hängt allerdings immer vom Einzelfall ab. Die Sicherheit schränkt die Benutzerfreundlichkeit ein und es ist daher drauf zuachten, das die Einstellungen nach den Bedürfnissen des Anwenders (Entwicklers) angepasst werden.

    Web Application Firewalls

    Definiton und Funktionsweise

    Web Applications Firewalls (WAFs) sind zusätzliche Schutzmaßnahmen der Webanwendung. Sie laufen auf der Anwendungsebene und sind technisch nicht von der Webapplikation abhängig. Eine WAF dient dazu, Sicherheitslücken in einer Webanwendungen vor Angriffen abzusichern. Diese Absicherung verlangt einen geringen Aufwand. Es wird eine nachträgliche Absicherung vor bestehenden Schwachstellen, die entweder schwer änderbar sind oder erst im nächsten Update geändert werden können, gewährleistet. Eine Web Application Firewall übnerwacht den Datenstrom zwischen den Browser und der Webapplikation. Sollten Eingaben nicht den vordefinierten Regeln entsprechen, wird die Übertragung abgebrochen oder es wird eine Aktion ausgeführt, die vorher durch den Administrator festgelegt worden ist.

    Bei einigen WAFs ist es möglich, die Ausgaben an den Browser zu überwachen. Dies ermöglicht, dass schadhafter Code gar nicht erst zum Browser gelangt. Die WAF ist in der Lage zu “lernen” und erkennt nach einiger Zeit ungewohnte Datenströme, die von den herkömmlichen Strömen abweichen.

    Eine WAF kann sowohl hardwarebasiert als auch softwarebasiert vorkommen. Im Bereich der softwarebasierten WAF gibt es sowohl eigenständige Lösungen als auch Plug-In-Lösungen für Webserver. Eine WAF kann auch als Reverse Proxy zwischen Browser und Applikation gestellt werden.

    Vor- und Nachteile

    • Vorteile:
    • nachträgliche Absicherung des Verhaltens von Webapplikationen
    • Grundschutz gegen bekannte Angriffsmethoden
    • erhöht die Robustheit der Webanwendungen
    • Nachteile:

    • WAF kann evtl. umgangen werden
    • hoher Konfigurationsaufwand (Regeln definieren)
    • Performanceverlust der Webanwendung (durch die Kontrolle der Datenströme)
    • Ausfälle bei falscher Konfiguration der Filter
  • Modsecurity

    Diese Web Application Firewall ist eine freizugängliche, kostenfreie Absicherung der Webanwendung. Diese Firewall ist als Plug-In für den Apache Webserver verfügbar. Allerdings ist es auch möglich Modsecurity als Reverse Proxy vor den Webserver zu schalten. Modsecurity funktioniert aber erst ab der Apache-Version 2.x. Bei vorherigen Versionen kann es zu Problemen kommen.

    Die Folgenden Funktionsmöglichkeiten sollen als kleiner Ausschnitt für den Umfang von Modsecurity dienen.

  • Sitzungsunterstützung (überprüft, ob der Nutzer nach mehreren, internen Seitenwechseln in einer Session immer noch die selbe Person ist)
  • enthält bereits einige Filter für die Eingabevalidierung
  • bietet die Möglichkeit diese zu erweitern
  • enthält sowohl Methoden für das Blacklisting als auch für das Whitelisting
  • Regeln die alle bekannten Verwundbarkeiten und Schwachstellen ermitteln sind vordefiniert
  • Die Regeln sind in mehreren Dateien und Kategorien aufgeteilt (einzelne Filter lassen sich an- oder ausschalten)
  • erkennt ungewöhnliche HTTP-Anfragen
  • erkennt Angriffe auf die Web-Applikation
  • erkennt automatisierte Zugriffe
  • erkennt lokale Trojaner
  • erkennt Fehlermeldungen des Webservers
    • bietet zwei Regelsätze

    • Protokollieren (Fehler werden erkannt, aber es werden keine Maßnahmen dagegen getroffen. Der Fehler wird in einer Log-Datei gespeichert)
    • Ablehnen (Die WAF erkennt den Angriff und wehrt ihn ab)
  • normalisiert Anfragen mit Hilfe von Methoden wie lowercase, hexdecode etc. (lassen sich in der Konfiguration einstellen)
  • ab Version 2.5 gibt es ein automatisches Regelupdate
  • ermöglicht die Beschränkung von IP-Bereichen. Ermittelt diese anhand der GEO-Informationen und verweigert Unzulässige.
  • kann berechnen ob eine Kreditkartennummer echt ist
  • Die Regeln lassen sich wie folgt definieren:

    SecRule REQUEST-URI password

    Prüft, ob in einer URL die Bezeichnung password vorkommt.

    SecRule ARGS "union.*select"

    Prüft, ob in den übergebenen Parametern die SQL-Statements union oder select vorkommen.

    SecRule ARGS:username "admin"

    Prüft, ob bei den übergebenen Parametern ein Parameter mit den Namen username den Wert admin hat.

    VN:F [1.9.11_1134]
    Bewerte diesen Artikel
    Rating: 0.0/5 (0 votes cast)

    Keine ähnlichen Artikel.

    Hinterlasse einen Kommentar

    *