Website Sicherheit



  • Moin!

    Ich hatte in der Uni einige Vorlesungen über Internet-Security und möchte für meine kleine Website nicht alle ignorieren.
    Was muss ich alles beachten um eine sichere Seite zu erstellen?

    Die Seite soll keine hochgradigen Geheimnisse beinhalten, sie besitzt aber einen Internen bereich der nur mitgliedern gestattet ist.
    Genutzt wird php 5.5 und mySQL.

    Aktuell habe ich sessions verwendet welche über password_hash() in der Datenbank gespeichert werden.
    Die gesamte website spielt sich auf der Index seite ab, welche über diese session verfügt. Alle unterseiten werden included.

    - Was muss ich beim schutz meiner mySQL datenbank beachten?
    - muss ich die unterseiten sichern? (Direkt zugriff). Wie macht man das am besten?
    - Kann ein Angreifer irgendwie die php Seiten ansehen? Wenn nein, würde es ja fast schon reichen die unterseiten nur in verbindung mit der index seite anzuzeigen (if(index_key...))
    - Wie fange ich XSS ordentlich ab? Also Eingabefelder und so einafch strip_tags()?



  • Moin,

    Du musst einfach alles beachten, was Du in den Vorlesungen gelernt hast 🙄 .



  • tntnet schrieb:

    Moin,

    Du musst einfach alles beachten, was Du in den Vorlesungen gelernt hast 🙄 .

    Das sind alleine zu XSS 800 Seiten 😕

    Ich hatte jetzt eigentlich gehofft, dass es eine Checkliste gibt die ihr dabei so Abarbeitet.
    Zumal in den Vorlesungen nicht auf so allgemeine Dinge wie Webzugriff eingegangen wurde.
    Eine übersichtliche Auflistung aller Schwachstellen die man stopfen sollte.




  • Mod

    Es gibt im Prinzip eine oberste Direktive: trauer keinem User Input.
    Immer alles korrekt escapen. Für SQL queries, für Ausgabe in HTML, etc. IMMER und ÜBERALL.

    Das ist die Grundlage. Nachher geht es dann um die Absicherung von Resourcen. Wenn du zB "lösche User" als Button im Admin interface hast - wie schützt du dich davor dass ich in einem Forum ein Link Poste und sage "cl90, das wird dir gefallen". Du klickst drauft und löscht nen User. Dafür brauchst du dann CSRF-Sicherung und ab jetzt wird es kompliziert.

    Deshalb verwendet man für Webseiten fertige Frameworks die das alles schon automatisch abdecken. Die haben automatismen für die meisten Fehlerfälle eingebaut.

    Ansonsten wird es anstrengend - dann musst du dich damit wirklich sehr intensiv beschäftigen. OWASP wie mein Vorredner verlinkt hat ist da eine gute Anlaufstelle.

    Wenn du konkrete Fragen hast, dann frag ruhig. Aber Allgemeine Tips gibt es relativ wenige die man dir geben kann. Aber du kannst uns gerne zB dein Session Management vorstellen und wir schauen ob es korrekt implementiert ist.

    Wie gesagt: ich empfehle hier immer fertige Lösungen, die vielfach getestet sind.



  • Für SQL gibt es vernünftige APIs, wo man gar nichts "escapen" muss.
    Für Ausgabe in HTML hat man eine Funktion, die Text für Menschen schreibt und eine handvoll Funktionen, die Tags auf und zu machen, Attribute schreiben usw.
    Wer so banale Sprachen wie HTML, SQL oder sogar UTF-8 nicht einmal lexikalisch durchschaut, hat in der IT nichts zu suchen*. Alle anderen müssen sich keine großen Sorgen um Sicherheit im Speziellen machen.

    * Meiner Erfahrung nach kapieren mindestens 20% aller aktiven Softwareentwickler das Konzept "Kodierung" nicht, unabhängig von Alter oder "Erfahrung".



  • Okay die Liste ist gut.
    Ich habe nur glück, dass ich den leuten im gesicherten bereich vertrauen kann und da nicht so sehr escapen muss. Es geht eigentlich nur um die leute von außerhalb. 🙂



  • cl90 schrieb:

    Okay die Liste ist gut.
    Ich habe nur glück, dass ich den leuten im gesicherten bereich vertrauen kann und da nicht so sehr escapen muss. Es geht eigentlich nur um die leute von außerhalb. 🙂

    Die meisten Angriffe kommen von innen aus dem gesicherten Bereich. Und es kommt häufig vor, dass Anwendungen, die eigentlich für den gesicherten Bereich geschrieben wurden, irgendwie doch nach aussen geöffnet werden.

    Du solltest Dir die 800 Seiten durch arbeiten. Offensichtlich studierst Du und wenn Du dann als studierter anfängst zu arbeiten, dann würde zumindest ich erwarten, dass Du was von "Website Sicherheit" verstehst.

    Und um dich ein wenig zu ermutigen: so schwer ist das nicht. Ich weiß eigentlich nicht so recht, wie man damit 800 Seiten füllen kann. Aber das muss ich nicht wissen um im Alltag zu bestehen 😃 .

    Und für die anderen (ausser TyRoXx): hört auf, SQL zu escapen. Lernt prepared statements mit Platzhaltern zu verwenden.



  • cl90 schrieb:

    Okay die Liste ist gut.
    Ich habe nur glück, dass ich den leuten im gesicherten bereich vertrauen kann und da nicht so sehr escapen muss. Es geht eigentlich nur um die leute von außerhalb. 🙂

    Sorry, aber du scheinst es noch nicht begriffen zu haben. Sicherheitstechnisch gibt es keinen Unterschied zwischen "Leuten von innerhalb und außerhalb", was auch immer das heißen soll. Es kann natürlich Aktionen geben, die nur bestimmten Nutzern erlaubt sind, aber das findet auf einer ganz anderen Ebene statt als irgendwelches "Escapen".
    Es klingt fast so als wolltest du "internen Leuten" explizit Injections erlauben.

    cl90 schrieb:

    Du solltest Dir die 800 Seiten durch arbeiten. Offensichtlich studierst Du und wenn Du dann als studierter anfängst zu arbeiten, dann würde zumindest ich erwarten, dass Du was von "Website Sicherheit" verstehst.

    800 Seiten über "Sicherheit" ohne mit konkreten Beispielen auf den Punkt zu kommen klingt nach Müll.

    tntnet schrieb:

    Und für die anderen (ausser TyRoXx): hört auf, SQL zu escapen. Lernt prepared statements mit Platzhaltern zu verwenden.

    Richtig, die kann man zum Beispiel verwenden. Es gibt da auch noch so DSLs, die im Inneren SQL bauen.



  • TyRoXx schrieb:

    tntnet schrieb:

    cl90 schrieb:

    Okay die Liste ist gut.
    Ich habe nur glück, dass ich den leuten im gesicherten bereich vertrauen kann und da nicht so sehr escapen muss. Es geht eigentlich nur um die leute von außerhalb. 🙂

    Sorry, aber du scheinst es noch nicht begriffen zu haben. Sicherheitstechnisch gibt es keinen Unterschied zwischen "Leuten von innerhalb und außerhalb", was auch immer das heißen soll. Es kann natürlich Aktionen geben, die nur bestimmten Nutzern erlaubt sind, aber das findet auf einer ganz anderen Ebene statt als irgendwelches "Escapen".
    Es klingt fast so als wolltest du "internen Leuten" explizit Injections erlauben.

    Danke TyRoXx. Ich will nur mal klar stellen, dass Deine Antwort eine Antwort an cl90 und nicht an mich ist.



  • Das ist eben genau das was ich damit sagen möchte wenn ich eine "liste" meine.
    In den Büchern, Skripts meiner Profs geht es um alles mögliche. Aber vor allem um Theorie.
    Das ist weit weg von jeder Praxis. Zumal ich als Informatik-Ingenieurwesen mich eher um Software Sicherheit kümmern muss (Wo ich auch gut bescheid weiß).

    tntnet schrieb:

    Ich weiß eigentlich nicht so recht, wie man damit 800 Seiten füllen kann. Aber das muss ich nicht wissen um im Alltag zu bestehen 😃

    Bingo! Und genau diese Dinge die im Altag wichtig sind interessieren mich als blutiger theorie Anfänger im thema Web-Sicherheit.

    Die Website muss keinen Atomkrieg überstehen. Sie soll nur nicht die grob fahrlässigsten Fehler beinhalten die man einfach verhindern kann...

    Ich habe aktuell folgende Sicherungen:
    - Jedes webfile (egal wie unwichtig) besitzt am anfang:

    if(isset($_SESSION["user"])) {...}
    

    (Um direkten zugriff auf unterseiten/elemente leer ausgehen zu lassen wenn der zugriff irgendwie klappt.)

    - Jede Eingabe Post/Get wird Escapted:

    $user 	= $_POST["username"];
    	$malicious = false;
    	strip_tags($user);
    	if (strpos($user, '://') !== FALSE || strpos($user, '../') !== FALSE) {
    		$user 		= "";
    		$malicious 	= true;
    	}
    

    - Ich habe keinerlei Stellen wo eingaben von Usern direkt in scripts umgesetzt werden, außer so etwas:

    $last = $_GET["last"];
            ...escape...
            if($last < $maxLastShouts && $last > 0) {
                $showNPosts        = $last;
            } else {
                $showNPosts        = $defLastShouts;
            }
    

    Und wenn ich ehrlich bin ist das bisher alles.
    Ich weiß auch nicht was ich noch alles absichern muss.


  • Mod

    TyRoXx schrieb:

    Für Ausgabe in HTML hat man eine Funktion, die Text für Menschen schreibt und eine handvoll Funktionen, die Tags auf und zu machen, Attribute schreiben usw.

    Äh... Nö.
    Du hast Templates - aber je nach Position des Wertes musst du ihn anders escapen. Ein Urlescape ist etwas anderes als ein Htmlespace ist etwas anderes als ein JavaScriptEscape etc.

    cl90 schrieb:

    Ich habe aktuell folgende Sicherungen:
    - Jedes webfile (egal wie unwichtig) besitzt am anfang:

    if(isset($_SESSION["user"])) {...}
    

    (Um direkten zugriff auf unterseiten/elemente leer ausgehen zu lassen wenn der zugriff irgendwie klappt.)

    Das ist nutzlos.
    Was denkst du erreicht das?

    Mal abgesehen davon dass ich sofort aufschreie: du verwendest $_SESSION, das bedeutet du verwendest kein Framework und kapselst es nicht - also das riecht mal wie ein Fehler.

    - Jede Eingabe Post/Get wird Escapted:

    $user 	= $_POST["username"];
    	$malicious = false;
    	strip_tags($user);
    	if (strpos($user, '://') !== FALSE || strpos($user, '../') !== FALSE) {
    		$user 		= "";
    		$malicious 	= true;
    	}
    

    Ich sehe hier kein escape.
    Bedenke dass ein escape immer vom Kontext abhängt. Daten die in eine Datenbank geschrieben werden müssen anderes escaped werden als Daten die in HTML ausgegeben werden.
    Ein One-Size-Fits-All-Escape funktioniert nicht.

    Sobald Jemand "strip_tags" verwendet, schreit bei mir alles auf.

    - Ich habe keinerlei Stellen wo eingaben von Usern direkt in scripts umgesetzt werden, außer so etwas:

    $last = $_GET["last"];
            ...escape...
            if($last < $maxLastShouts && $last > 0) {
                $showNPosts        = $last;
            } else {
                $showNPosts        = $defLastShouts;
            }
    

    Direkt $_GET verwendet - nimm ein ordentliche Framework oder Kapsle die Sachen sauber.
    Hier würde ich $last dennoch nach int casten - auch wenn es hier jetzt wirklich kein direktes Problem ist.

    Aber hast du zB soetwas wie Benutzernamen oder dergleichen? Die auf der Webseite angezeigt werden? Das sind schonmal gute Anlaufstellen für XSS.

    Und wenn ich ehrlich bin ist das bisher alles.
    Ich weiß auch nicht was ich noch alles absichern muss.

    Mir gefällt dein Ansatz ehrlich gesagt nicht. Nimm zumindest ein Microframework wie Silex oder dergleichen. Das spart dir unendlich viel Arbeit und sichert automatisch einiges ab. Und wenn du alles händisch machen willst, dann lehne dich an Silex/Dancer/Flask/... an - die haben ein gutes Design und zeigen dir schon wie man es richtig macht.



  • if (strpos($user, '://') !== FALSE || strpos($user, '../') !== FALSE) {
            $user       = "";
            $malicious  = true;
        }
    

    Damit hab ich dich schon fast in der Tasche.


  • Mod

    EOP schrieb:

    if (strpos($user, '://') !== FALSE || strpos($user, '../') !== FALSE) {
            $user       = "";
            $malicious  = true;
        }
    

    Damit hab ich dich schon fast in der Tasche.

    Kurze Erklärung dazu was EOP meint:

    Der Code checkt auf 2 gängige Angriffsvektoren. Sowas wird manchmal gerne von einer Application Firewall gemacht (obwohl ich diese Dinger hasse) aber der Code selber sollte robust gegen alle Angriffsvektoren sein.

    Es geht dabei darum, dass der Angreifer unendlich viel mehr Zeit hinein steckt herauszufinden wo da eine Schwachstelle ist, als der Programmierer in die Verteidigung steckt. Deshalb muss man mit dem Holzhammer drüber fahren und nicht einzelne Vektoren abdichten sondern direkt alles.

    Der Wert wird in HTML ausgegeben? htmlspecialchars()
    Der Wert wird in einer regex verwnedet? preg_quote()
    Der Wert wird in eine DB geschrieben? mysql_real_escape_string()

    Aber! und hier das große aber: man verwendet fertige Systeme dafür. Für HTML Ausgabe einfach Twig verwenden, dann ist jeder Wert automatisch korrekt escaped. Datenbank? einfach prepared Statements oder gleich ein ORM. und so weiter und so fort.



  • Was ist z.B. mit

    username=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd
    

    ?
    Was du gecodet hast kann ganz schnell in die Hose gehen. 😉

    EDIT:
    Es zeigt mir dann evtl.

    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    ...
    

    Von da an ist es meistens nur noch ein kleiner Schritt bis dein Server komplett kompromittiert ist.


Anmelden zum Antworten