Sicherheit geht vor

Ein sehr guter Kollege von mir, der hauptsächlich Webapplikationen entwickelt, hat vor Kurzem ein "modernisiere-uns-das-mal"-Projekt von einem seiner Kunden angenommen. Es ist schon unangenehm genug das Projekt eines anderen Entwicklers übernehmen zu müssen, weitaus schlimmer ist es aber, wenn er (oder sie) unsauber gearbeitet hat. Nachdem er sich etwas eingelesen hatte, schickte er mir ein Stückchen Quellcode des Admin-Tools mit der Frage: "was ist hier falsch?". Selbstverständlich möchte ich euch dieses kleine Prachtstück nicht vorenthalten:
session_start();

$username = $_POST['username'];
$password = $_POST['password'];

if( $username=="admin" && $password=="12345" )
{
$_SESSION['login'] = $username;
header( "location:./admin_panel.php" );
}

Okay, jeder schreibt Code ein wenig anders und ich hätte hier sicher einiges anders gemacht (vor allem hätte ich Benutzername und Passwort nicht direkt im Code hinterlegt), aber grundsätzlich würde der Code zur Authentifizierung, so wie er da steht, funktionieren.
Das wirkliche Problem liegt aber an einer ganz anderen Stelle und zwar in der Tatsache, dass "admin_panel.php" weder die Session weiterführt, noch die Variable "$_SESSION['login']" jemals wieder benutzt. Mit anderen Worten: Wer die aufzurufende Seite kennt, kann mit Hilfe dieses "Tools" alle Inhalte ändern, ohne sich vorher anmelden zu müssen. Das ist dann allerdings schon ein Hammer, denn der Kunde weiß hiervon nichts und meldet sich weiterhin brav an. Fest im Glauben, dass nur durch diese Anmeldung "böse Hacker" vom Manipulieren der Inhalte auf der Webseite abgehalten werden.

Wie verbessert man den Zustand jetzt?
Zuerst einmal etwas Grundsätzliches zu Benutzernamen und Passwörtern: Wenn eine Datenbank verfügbar ist und auch verwendet werden darf (das ist bei einigen Projekten nicht selbstverständlich), legt man Benutzernamen und Passwörter darin ab. Logischerweise werden die Passwörter nicht im Klartext, sondern als gesalzene Hashwerte hinterlegt (man weiß ja nie, wer den Inhalt mal in die Finger bekommt). Ist keine Datenbank verfügbar, muss man entweder eine Passwort-Datei schreiben, oder aber tatsächlich "hardcoden". Dann aber bitte als Variablen in einer zentralen "config"- oder "settings"-Datei und nicht mitten im Code, wo ein anderer Entwickler sich irgendwann mal dumm und dämlich suchen wird. Auch hier gilt wieder: KEIN KLARTEXT!

Die einzelnen Teile des Admin-Tools bekommen jetzt am Anfang jeder Datei eine neue Zeile verpasst:
include_once( './admin_session.php' );

// Eigentlicher Code für dieses Modul

Was steckt hinter diesem "include"?
session_start();

if( !isset( $_SESSION[ 'login' ] ) )
{
header( "location:./admin_login.php" );
die( "Nicht angemeldet!" );
}

Warum das Ganze in eine separate Datei packen und inkludieren? Weil es ansonsten an vielen Stellen (nämlich in jedem einzelnen Modul) dupliziert werden müsste und wartungstechnisch ein Albtraum wäre. Der pragmatische Programmierer spricht hier von DRY (Don't Repeat Yourself).

Zwar ist die oben genannte Lösung auch noch lange nicht das Gelbe vom Ei, aber man muss mit dem arbeiten, was vorgegeben wurde. Das Wichtigste ist, dass die Anmeldung wieder einen Zweck erfüllt und auch ein kleines bisschen Sicherheit dazu gewonnen wurde. Diese kleine Änderung entspricht arbeitstechnisch auch in etwa der Zeitvorgabe des Kunden: Es muss schnell gehen und darf praktisch nichts kosten.
23.01.2013 - 01:22

Kommentare

besucher
23.01.2013, 18:28
neeeeerd
KIENI
24.01.2013, 14:32
Manchmal muss es eben auch mal technischer Humor sein (auch, wenn er einen etwas ernsthafteren Hintergrund hat).
Und, ja, ich gebe es zu: ich bin ein Nerd. Sticks and stones, mein Freund. Sticks and stones...
Maxi
13.02.2013, 16:44
Du bist kein Neeeeeerd, Kieni. Du sieht halt alles ein wenig anders in deiner kleinen Welt
KIENI
18.02.2013, 16:16
KLEINE WELT? Meine Welt hat zwar gewisse Grenzen, aber klein ist sie deswegen noch lange nicht...!