Clansuite Community Forum


 
Willkommen Gast. Bitte einloggen oder registrieren.
Haben Sie Ihre Aktivierungs E-Mail übersehen?

Einloggen mit Benutzername, Passwort und Sitzungslänge
 
Seiten: [1]   Nach unten
  Drucken  
Autor Thema: Http Request  (Gelesen 728 mal)
0 Mitglieder und 2 Gäste betrachten dieses Thema.
paulbr
Developer
*****
Offline Offline

Beiträge: 126


« am: Mai 10, 2011, 11:42:43 »


Noch etwas aus meiner "Liste" was mir nicht so gut gefällt Smiley

Im HttpRequest werden die POST und GET Parameter getrennt, warum?

Wäre doch viel einfacher alle in einem array $parameters zu speichern.
Mit getParameter( $name ) hat man so zugriff auf die parameter egal ob POST oder GET
Mit getParameters() erhält man das array mit allen Parametern zurück.

Wenn man z.B. einen datensatz editieren möchte, hat man mit dem Modul aufruf
die ID als GET, welche man auslesen muss. Nach dem Speichern hat man diese ID im normalfall als POST.

Wenn man die actions immer nach '_edit' und '_save' trennt ist das ja ok.
Dann braucht man in '_save? nur nach POST abfragen,
wenn man das in einer action machen will geht das nicht.

Entsprechend muss man um die richtige ID zu haben immer 3 schritte ausführen:
 1. die ID in GET suchen, wenn nicht vorhanden
 2. in POST nachschauen.
 3. wenn nicht vorhanden abbruch ansonsten weiter

Ginge auch in einem Schritt:
 1. ist die ID in parameters nicht vorhanden dann abbruch ansonsten weiter
 
Bezüglich dem Filterformular und der Pagination ist es dann auch unkomplizierter, man braucht nur
in einem Array nachschauen.

Eine vereinfachung wäre auch das Prüfen auf Submitted eines Formulares:
z.B.
Code:
public function IsSubmitted( $name = 'submit' ) {
    if ( array_key_exists( self::getParameter( $name ) ) and
        !empty( self::getParameter( $name ) )
    ) return( true );
    return( false );
}
So kann man sich die verschiedenen varianten sparen:
  $submit = $this->request->getParameterFromPOST('submit');
  if( !empty( $submit ) )
oder:
  $submit = isset($_POST['submit']) ? $_POST['submit'] : '';
  if( !empty( $submit ) )

Was wenn das kleine Formular (z.b. Suche via GET erfolgt?)
Formulare müssen ja nicht zwangsläufig mittels POST gesendet werden, kann ja auch GET sein.

Der Aufrufen: if( $this->request->IsSubmitted() )  reicht hier völlig.

man müsste sich um solche konstrukte wie z.b. im Guestbook keinen Kopf machen:
Code:
    public function save_comment()
    {
        $gb_id      = $this->request->getParameterFromGet('gb_id');
        $comment    = $this->request->getParameterFromPost('value');
        ...

Formulardaten können einfach mittels: $formdata = $this->request->getParameters() komplett
geholt werden ohne GET + POST zu berücksichtigen.

Pro und Contra ist erwünscht Smiley

-------------------------------------------------

in der httprequest.core.php zeile: 168  -> # block XSS
Ist da eine XSS Prüfung geplant?
Prüft den IDS nicht auch die URL auf javascript und response splitting attacks?



gruss
paul
Gespeichert
Jens-A. Koch
Maintainer
*
Offline Offline

Beiträge: 574

One-Man Team


« Antworten #1 am: Mai 10, 2011, 05:48:16 »

Zitat
Im HttpRequest werden die POST und GET Parameter getrennt, warum?

Die Antwort: aus dem gleichen Grund, warum "register_globals" abgeschafft wurde.
Das Trennungsprinzip der Eingangsdatenarrays hilft die Sicherheit des Systems zu wahren.
Sicherheitsaspekte zu berücksichtigen macht das Leben nicht einfacher.
Im Gegenteil, die Regeln und Konventionen machen es etwas umständlicher, mit dem System umzugehen.

Superglobale sind die Einfallstore für Angriffe. Die Eingabedaten - egal ob aus Cookie ($_COOKIES), URL-Parameter ($_GET) oder  Formular-Post ($_POST) wurden früher automatisch zu PHP-Variablen, die man dann im Script auslesen konnte. Daneben wurden GET + POST + COOKIES zum superglobalen REQUEST Array zusammengefasst. Dabei kann ein Variableninhalt untergeschoben werden, da er aus allen drei Eingangstoren kommen kann.
Man hat daher aus Sicherheitsgründen zu register_globals "off" geraten und später die Entscheidung getroffen es ganz aus PHP zu entfernen.
Hier gilt die Grundregel: man muss wissen, welche Daten eingehen und woher sie stammen.

Ich versuche zumindest, dass das Trennungsprinzip im Bereich der Eingangsdatenströme eingehalten wird. Soweit $_REQUEST überhaupt vorhanden ist, wird es neuerdings gelöscht.
Diese Programmierkonvention "hilft" etwas sicherer zu scripten und richtig grobe Schnitzer zu vermeiden. In etwa so, wie das eval() oder eregi() Verbot.
GET und POST in einem Parameter Array zusammenzufassen käme ja dem alten Verfahren gleich.
HttpRequest stellt einen abstrahierenden Zugriff auf die gefilterten, einzelnen Parameterarrays zur Verfügung.

$_REQUEST, GET+POST zusammenfassen, eval() oder gar das neue "GOTO":
Machen kann man das alles machen - nur nicht in diesem System  Grinsend

Neben der Sicherheitsargumentation gibt es noch eine Programmierweise, die man berücksichtigen sollte: und zwar REST. REST zu beachten, bedeutet eigentlich nichts Neues, denn HTTP ist so konzipiert. Dennoch wird es sehr oft missachtet.
Um es kurz zu machen: man kann anhand der URL erkennen, welche auf welche Ressource verändernd oder ausliefernd zugegriffen wird.
Bspw:  "/news/show/23" oder "/news/show-ajax/23" oder "/news/edit/23" und "/news/save/23" (welche Resource aus GET) + (Inhalt aus POST).

Daneben gibt es noch (für mich unschöne) Verfahren der REST-Tunnelung von GET durch POST.
Beispiel: GET "/backend" und im POST ein ['do'] oder ['get'] oder ['action'] wie "/news/edit/23" (was eigentlich gut ein GET Request sein könnte).

Zitat
man müsste sich um solche konstrukte wie z.b. im Guestbook keinen Kopf machen:
$gb_id      = $this->request->getParameterFromGet('gb_id');
$comment    = $this->request->getParameterFromPost('value');
Die ID kommt über GET und identifiziert die Resource und die Daten kommen über POST.
Zumindest aus meiner Perspektive, ist das gut gemacht, weil REST mitgedacht wurde.

IDS
Zitat
in der httprequest.core.php zeile: 168  -> # block XSS
Ist da eine XSS Prüfung geplant?
Prüft den IDS nicht auch die URL auf javascript und response splitting attacks?

In so wenigen Zeilen so viele Sachen.. mann, mann.

Mal der Reihe nach:
Durch Manipulation von $_SERVER php_self oder query_string ist es möglich,
einen anderen Server als Empfänger einzusetzen.
Beide Parameter werden im System verwendet und daher mit htmlspecialchars() behandelt.

XSS steht für Cross-Site-Scripting Angriffe und ist von Response-Splitting Angriffen zu unterscheiden. Response Splitting Attacken werden über den Header abgesetzt. Die beiden $_SERVER Parameter werden in header redirects verwendet (als Grundlage für die URL-Bildung ). Daher ist potentiell ein XSS Angriff möglich.

Zitat
"Prüft den IDS nicht auch die URL auf javascript und response splitting attacks"
Der Angriff setzt voraus, das ein GET Parameter innerhalb von header() eingesetzt wird oder der Header per javascript gesetzt wird. Ich hoffe, wir machen so was nicht Smiley

Nun zu IDS: IDS prüft GET, POST und COOKIES. D.h. die Eingangsdatenströme sind zumindest behandelt. Ob man "teilgesichert gegen XSS" sagen kann, hängt von der Aktualität der IDS-Regeln ab.
Weitere XSS-Abwehr / ein Mehr an Prüfung ist erstmal nicht geplant.

Hört sich komisch an, aber ich bin dankbar für einige XSS-Angriffe gegen Clansuite.
Das würde uns im Hinblick auf die Sicherheit sehr weiterhelfen.
Natürlich könnte man auch noch htmLawed in die Libraries packen - das dürfte dann wohl die meisten Angriffsvektoren aushebeln. Ich glaube htmlPurifier ist auch schon vorhanden und wird von IDS intern mitgenutzt. Insgesamt ist noch genügend Spielraum, um weiter abzusichern und noch schwerere Geschütze als IDS aufzufahren.

Gruß Jens
Gespeichert

Keine Supportanfragen per PN oder Mail. Fragen bitte nur im Forum stellen (Wie man Fragen richtig stellt).
paulbr
Developer
*****
Offline Offline

Beiträge: 126


« Antworten #2 am: Mai 10, 2011, 07:41:46 »


Zitat
Die Antwort: aus dem gleichen Grund, warum "register_globals" abgeschafft wurde.
Ich war noch nie ein freund von register_globals zu und habe es schon immer abgelehnt damit zu arbeiten.
Weshalb ich dies Gloablen immer in einem $aParameter = array() gespeichert hatte und
die Globalen geleert hatte.

Nun das prinzip war mir schon klar, die Frage zielte lediglich darauf hin, warum man nach dem
Cleanen der variablen POST + GET, diese in getrennten arrays ablegt.
Ich sehe hier keinen Vor-/Nachteil ob diese nun in einem oder in 2 containern gespeichert werden.

Sinn macht es da eher, die Parameter auszulesen, zu prüfen und zur weiteren Nutzung zu speichen.
Idealerweise löscht man die Globalen Variablen nachdem man diese in ein array gespeichert hat und füllt sie neu.

Zitat
GET und POST in einem Parameter Array zusammenzufassen käme ja dem alten Verfahren gleich.
Kommt auf die Sichtweise an, ist ja nur für den Entwickler eine vereinfachung.
Es wird hier ja keine Globale mit GET und POST daten vermischt befüllt.
Wie gesagt wenn man die actions immer trennt nach add/edit/save/delete spielt das keine Rolle.
Save ist POST, der rest immer GET. Nutzt man nur eine action, dann muss man halt erst GET dann POST checken.
Ich kann damit leben, muss mir halt angewöhnen die actions zu trennen Smiley

Für einen Angreifer ist es doch hier egal ob GET + POST nun in 2 arrays geschrieben werden oder in einem.
GET + POST existieren nach wie vor und können überall genutzt werden. Eine Sicherheit ist das nicht.

Hier sollte aber GET + POST geprüft und bereinigt werden.
IDS prüft ja nur und bricht bei detection mit weiser Seite und IDS Meldung dann ab.

Die Reihenfolge sollte anders sein:
 - GET und POST bereinigen in arrays speichern
 - Globale Variablen löschen und neu mit den geprüften daten füllen
 - mit IDS prüfen

Der Vorteil ist der, das man dadurch evtl. den Abbruch durch das IDS vermeiden kann,
wenn evtl. schadcode vorher entfernt werden konnte.

Beispiel:
Code:
/**
 * Secure URL :  Entfernen von Splitting (Injection) sowie Javascript-Urls aus einem zu prüfenden String
 * @param   string url
 * @return  string filtered url
 */
private static function secureURL( $sUrl, $JS=true ) {
    if ( $JS ) $sUrl = self::removeJavascriptURL( $sUrl );
    $sUrl = self::filterHTTPResponseSplitting( $sUrl );
    return $sUrl;
}

/**
 * Remove potential javascript in urls
 * @param   string url
 * @return  string filtered url
 */
private static function removeJavascriptURL( $sUrl ) {
    $HTML_stripJavascriptURL = 'javascript:[^"]+';
    $sUrl = preg_replace("/$HTML_stripJavascriptURL/i", '', $sUrl );
    return $sUrl;
}

/**
 * Filter URLs to avoid HTTP response splitting attacks
 * @param   string url
 * @return  string filtered url
 */
private static function filterHTTPResponseSplitting( $sUrl ) {
    $dangerousCharactersPattern = '~(\r\n|\r|\n|%0a|%0d|%0D|%0A)~';
    return preg_replace( $dangerousCharactersPattern, '', $sUrl );
}

private static function RemoveXSS( $val )
{
    // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
    // this prevents some character re-spacing such as <java\0script>
    // note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
    $val = preg_replace('/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val);

    // straight replacements, the user should never need these since they're normal characters
    // this prevents like <IMG SRC=&#X40&#X61&#X76&#X61&#X73&#X63&#X72&#X69&#X70&#X74&#X3A&#X61&#X6C&#X65&#X72&#X74&#X28&#X27&#X58&#X53&#X53&#X27&#X29>
    $search = 'abcdefghijklmnopqrstuvwxyz';
    $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $search .= '1234567890!@#$%^&*()';
    $search .= '~`";:?+/={}[]-_|\'\\';

    for ( $i = 0; $i < strlen($search); $i++ )
    {
        // ;? matches the ;, which is optional
        // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
        // &#x0040 @ search for the hex values
        $val = preg_replace('/(&#[x|X]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;

        // &#00064 @ 0{0,7} matches '0' zero to seven times
        $val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
    }

    // now the only remaining whitespace attacks are \t, \n, and \r
    $ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');

    $ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');

    $ra = array_merge($ra1, $ra2);

    // keep replacing as long as the previous round replaced something
    $found = true;

    while ( $found == true ) {
        $val_before = $val;
        for ( $i = 0; $i < sizeof($ra); $i++ )
        {
            $pattern = '/';
            for ( $j = 0; $j < strlen($ra[$i]); $j++ )
            {
                if ( $j > 0 )
                {
                    $pattern .= '(';
                    $pattern .= '(&#[x|X]0{0,8}([9][a][b]);?)?';
                    $pattern .= '|(&#0{0,8}([9][10][13]);?)?';
                    $pattern .= ')?';
                }
                $pattern .= $ra[$i][$j];
            }
            $pattern .= '/i';

            // add in <> to nerf the tag
            $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2);

             // filter out the hex tags
            $val = preg_replace($pattern, $replacement, $val);

            if ( $val_before == $val )
            {
                // no replacements were made, so exit the loop
                $found = false;
            }
        }
    }
    return $val;
}

z.B.
$_SERVER['QUERY_STRING'] = secureURL($_SERVER['QUERY_STRING'], true);

GET und POST in einer schleife durchlaufen und die values auf RemoveXSS() testen
dann in das jeweilige array get_parameters/post_parameters schreiben.

GET und POST löschen und aus get_parameters/post_parameters neu befüllen.

$doorKeeper->runIDS();


Es ist klar das es keine 100% Sicherheit gibt.
Im moment wird lediglich eine dedection durch das IDS durchgeführt.

Das problem beim IDS ist, das man unter umständen zuviele freigaben in der config definieren muss.
Bei diversen tests mit unterschiedlichen Sprachen hatte ich sehr oft einen IDS Abbruch mit Detection Warnung ausgabe. Nur weil in den texten reservierte Wörter wie z.b. like vorkam.
Ich hab nicht analysiert welche Worte im einzelnen das System zum stillstand brachten, aber es waren eine menge.

gruss
paul
Gespeichert
Jens-A. Koch
Maintainer
*
Offline Offline

Beiträge: 574

One-Man Team


« Antworten #3 am: Mai 11, 2011, 02:00:07 »

Zitat
Die Reihenfolge sollte anders sein:
 - GET und POST bereinigen in arrays speichern
 - Globale Variablen löschen und neu mit den geprüften daten füllen
 - mit IDS prüfen

Der Vorteil ist der, das man dadurch evtl. den Abbruch durch das IDS vermeiden kann,
wenn evtl. schadcode vorher entfernt werden konnte.


Warum soll man denn den Abbruch im Angriffsfall vermeiden?

IDS dient nicht dazu irgendwelche Veränderungen an eingehenden Daten vorzunehmen, irgendetwas zu bereinigen oder zu sanitizen etc. Es wird lediglich erkannt, wenn ein Angriff stattfindet. Fall ein Angriff stattfindet, dann muss man doch nicht dafür sorgen, dass der Applikationsablauf gewährleistet ist. Das System bricht ab - oder loggt noch kurz und redirected auf die Startseite. Eigentlich halte ich vom IDS-Logging nichts. Das bedeutet im Angriffsfall nur Last und klärt nicht mehr auf, als man schon durch die httpd-Logs weiß.

Deswegen überlasse ich die Angriffserkennung IDS ganz am Anfang und wenn Angriff, dann sofortiges Ende. Wenn kein Angriff, dann Werte aus der Umgebung ins System holen.

Unbehandelt sind nur die IDS Ausnahmen: wer Clansuite angreifen will, der sollte dort anfangen.

Ich möchte nicht gegen die removeXSS() sprechen, dass Ding ist leistungsstark und wir nehmen es an Bord. Es ist vielmehr so, dass ich IDS stärker einschätze, weil die Filterregeln durch konstanten Beschuss mit Angriffen erstellt wurden (auch wenn es viele "false positives" gibt). Und falls ein Angriff an IDS vorbeikommt, dann wohl auch an removeXSS().

Ob das mit dem vorangestellten Bereinigen mehr Sicherheit gibt, muss ich mir erstmal überlegen.
Derzeit würde ich das jetzige Verfahren beibehalten und ein lokales Filtern und Bereinigen des Inputs vorziehen, denn dort kennt man den Kontext..

Beispiel: innerhalb eines Moduls
$email = getParameterFromPost('email'); # ist an IDS vorbeigekommen, kann dreckig und keine email sein...
$email = inputfilter($email, 'email'); # email entspricht den erwartungen an eine email addresse etc.

Weitere Diskussion erwünscht...

Aufgaben aus diesem Thread
Kurze Zusammenfassung in Ticket-Form, damit nichts verloren geht.
http://trac.clansuite.com/ticket/209 - formhandler um isSubmitted() methode ergänzen
http://trac.clansuite.com/ticket/210 - removeXSS() ergänzen und global anwenden
...

Gruß Jens

Gespeichert

Keine Supportanfragen per PN oder Mail. Fragen bitte nur im Forum stellen (Wie man Fragen richtig stellt).
paulbr
Developer
*****
Offline Offline

Beiträge: 126


« Antworten #4 am: Mai 11, 2011, 01:22:52 »


Zitat
Warum soll man denn den Abbruch im Angriffsfall vermeiden?
Weil nicht alles ein Angriff sein muss.

Wenn IDS nur bei einem tatsächlichen Angriff abbrechen würde, wäre dies ja ok.
Wenn man aber textfelder aus die IDS Prüfung nehmen muss, damit IDS nicht wegen irgendeinem Wort das vermeindlich ein Angriff darstellen könnte abbricht, bringt das nicht viel. Ist ein textfeld aber aus der IDS Prüfung ausgenommen, kann man sehr wohl schadcode dort eintragen.

Wenn man:
 - einen text eingibt,
 - IDS einen Abbruch erzwingt,
 - das Formular neu starten muss,
 - den text analysieren und umformulieren muss, weil man nicht weiss was Schuld an dem Abbruch war
 - und das ganze mehrmals hintereinander bis IDS Gnade walten lässt,

neigt man dazu das entsprechende textfeld kurzerhand in die IDS ausnahme zu setzen.
Zumindest sollten dann diese Ausnahmen aus Sicherheitsgründen trotzdem geprüft werden.

Hierzu könnte man evtl. ein array mit den Ausnahme Parametern gem. IDS-Config anlegen, die exceptions von IDS auslesen und alle POST.<parameter> Ausnahmen auslesen, POST prüfen ob der Parameter in dem Ausnahme-Array steht und dann dessen value auf XSS prüfen. Kostet zwar etwas Zeit ist aber dann sicherer.

Post daten + der editor vom Templatemanager, sowie der news_body sitzen bereits in der ausnahme.
Warum?  Ich denke mal aus oben genannten Gründen!
Gut man kann jetzt sagen, das ist im Adminbereich und das ein Administrator/Moderator keinen Schadcode da eingibt.
Das sollte auch so sein.

Man neigt aber dann auch dazu evtl. öffentliche textfelder wie comments, Gästebuch etc. (wenn es hier ein mehrmals zu IDS Abbrüchen
kam) auf die Ausnahmen zu setzen. Dann ist man sehr wohl in der Gefahr anfällig zu sein.

Einer meiner Kunden (ein Auktionshaus) hatte mal den Fall, allerdings wurde hier der schadcode in einem Bild upgeloadet. Der Schadcode erstellte im cache-ordner ein Script, welches alle greifbaren userdaten in einer datei speicherte und per email an den Angreifer schickte. Die datei war knapp 1 GB gross. Ist auch nur aufgefallen weil der Server sehr langsam wurde und das script bei der Ursachensuche ins Auge gefallen ist. An allen eventualitäten hatte ich damals gedacht, nur nicht das ein Angriff über ein Bild erfolgen könnte.
Das war mir eine Lehre Smiley

gruss
paul

PS:
Dieses Thema ist auch kein Angriff, sondern soll nur aus der Diskussion evtl. Anregungen/Verbesserungen ziehen.

Gespeichert
Jens-A. Koch
Maintainer
*
Offline Offline

Beiträge: 574

One-Man Team


« Antworten #5 am: Mai 11, 2011, 01:35:13 »

Zitat
Dieses Thema ist auch kein Angriff, sondern soll nur aus der Diskussion evtl. Anregungen/Verbesserungen ziehen.
Ich weiß, ich weiß. Es ist und bleibt ein kompliziertes Thema.
Schließlich verdienen einige Leute ihren Lebensunterhalt damit, Webapplikationen auf Sicherheit zu prüfen und Entwickler entsprechende zu schulen. Siehe Sektion Eins, etc.

Alle eingehenden Daten sind nicht vertrauenswürdung und potentielle Angriffe.

Grundsätzlich laufen wir in die gleiche Richtung, nur dir ist IDS etwas zu streng...
Zitat
Hierzu könnte man evtl. ein array mit den Ausnahme Parametern gem. IDS-Config anlegen, die exceptions von IDS auslesen und alle POST.<parameter> Ausnahmen auslesen, POST prüfen ob der Parameter in dem Ausnahme-Array steht und dann dessen value auf XSS prüfen. Kostet zwar etwas Zeit ist aber dann sicherer.

Korrekt. Statt des globalen Ansatzes würde ich es an Ort und Stelle der Verwendung der Daten machen.

Als zusätzliche Idee: wir könnten schlichtweg die phpIDS Filterregen automatisch downloaden bei einer Aktualisierung durch das phpIDS Team. Die Regeln sind ja unabhängig von der PHP-Lib.

Weitere Idee: Aus Sicherheitsgründen würde ich die Feldnamen immer gleich nennen.
"inputtext_body_with_html" oder sowas, dann gibt es nur diese IDS-Ausnahme für alle Input Textfields.

-----

So, nachdem ich ne Nacht drüber geschlafen habe ergibt sich folgendes:
Es mag sich etwas komisch anhören, aber je länger man über das Konzept Websicherheit nachdenkt, desto mehr ergibt sich, dass die korrekte Lösung eigentlich ganz anders aussehen müsste.

Eigentlich ist sowas wie phpIDS konzeptionell der völlig falsche Ansatz.
Erstens aus Performancegründen und zweitens aus Sicherheitsgründen.
Wenn phpIDS einen Angriff meldet, dann ist die Aussage eigentlich:
die Einsatzumgebung der Applikation ist schlecht gesichert ist!

Theoretisch müsste ein IDS/IPS System vor dem Webserver liegen.
Webserver Module, wie Apache's mod_security sind eigentlich auch zu spät.
Die Realität sieht anders aus: Nichtmal professionelle Webservice Provider nutzen IPS Systeme oder mod_security. Ich glaube für nginx oder lighttpd gibt es vergleichbares auch gar nicht.

Die eingehenden Daten global zu filtern oder zu bereinigen ist für die Katze.
Das steht zwar in jedem Tutorial, ist aber schlichtweg falsch.

Meine Argumentation ist wiederum an etwas festzumachen, was im PHP Kern liegt/lag,
nämlich "magic_quotes". Warum wurde das entfernt? Weil es nicht funktioniert.
Falsches Konzept. Man kann eingehende Daten nicht global säubern bzw. quoten und dadurch Sicherheit schaffen.

Die Reihenfolge ist daher korrekt.

1. Wir säubern nicht global.

2. Wir weisen mittels phpIDS auf eine schlechte Sicherung hin und lassen unser System nicht laufen.
Wer eine gesicherte Umgebung stellt, kann phpIDS abschalten.

3. Wir sichern an dem Ort, wo die Daten verwendet werden.
Das ist das Konzept kontextbezogener Sicherheit.
Ein Whitelisting-Ansatz, bei dem wir spezifizieren, was wir von den Daten erwarten.
Mit anderen Worten, was uns da als Email-Daten verkauft wird, sollte dem Email Format entsprechen.
$email = getParameterFromPost('email'); # ist an IDS vorbeigekommen, kann dreckig und keine email sein...
$email = inputfilter($email, 'email'); # email entspricht den erwartungen an eine email addresse etc.

4. Wir escapen für die Zielsprache.
Das Escapen ist die Sicherung gegen XSS.
Dinge die in HTML eingebettet werden, werden mit htmlspecialchars() behandelt.
Dinge die in MYSQL eingebettet werden, werden mit mysql_real_escape_string() behandelt.
Für beides sorgen die jeweiligen Engines: Template/Db.

5. Wir filtern und bereinigen nur vorformatierte HTML-Daten aktiv.
Das sind HTML-Markup Geschichten über WYSIWYG Editoren etc.
Die Elemente werden sich oft mit den phpIDS Ausnahmen decken.
Und exakt hier können wir mit removeXSS() oder htmlPurifier() bzw. besser noch einer PHP-Extension wie Tidy ansetzen. Das bleibt ein Sicherungsversuch.

Zitat
Gut man kann jetzt sagen, das ist im Adminbereich und das ein Administrator/Moderator keinen Schadcode da eingibt. Das sollte auch so sein.
Genau - und ich bin geneigt folgendes zu machen:
Wir filtern und bereinigen nur vorformatierte HTML-Daten ---des Frontends--- aktiv.
Nach Login macht es eh keinen Sinn, wegen Templateeditor und embeddable PHP.
Das kann man nicht filtern oder säubern. Da muss man dem eingeloggten User schlicht vertrauen.

Pff, Romane... so genug... zu den Waffen!  Grinsend
Gespeichert

Keine Supportanfragen per PN oder Mail. Fragen bitte nur im Forum stellen (Wie man Fragen richtig stellt).
Seiten: [1]   Nach oben
  Drucken  
 
Gehe zu:  


Powered by SMF 1.1.16 | SMF © 2006-2009, Simple Machines

Google visited last this page Mai 20, 2012, 07:04:47