PHP Framework
Stand: 07/2018
Lesedauer: ca. 21 Minuten
Inhalt:
Versionshistorie
Zahlen, Daten, Fakten
Funktionalitäten
Sicherheit / Security
Voraussetzungen
Fazit
Das PHP Framework (im Folgenden csf oder Framework) bietet die Möglichkeit durch eine einheitliche Struktur und die zur Verfügung gestellten Methoden neue Webanwendungen in PHP einfach, schnell und effizient zu entwickeln. Der Entwickler einer Anwendung muss sich lediglich um die (Geschäfts-)Logik der Anwendung und um die Strukturen der REST-Schnittstelle sowie der Datenbank-Tabellen kümmern. Die komplette Speicherung von Objekten in der Datenbank, die Validierung der Eingaben, die Anzeige, die Absicherung und die Implementierung der REST-Schnittstellen werden dem Benutzer nahezu komplett abgenommen.
Durch die Konzentration des Entwicklers auf die wesentlichen Bestandteile (Logik und Datenbankschema) kann die Entwicklung von neuen Anwendungen erheblich beschleunigt und das Ergebnis verbessert werden.
Für die Verwendung des Frameworks muss die zu entwickelnde Anwendung in bestimmte vorgegebene Klassen integriert werden. Da dies allerdings nur wenige Klassen betrifft und anschließend die Nutzung jeder Komponente und Funktion komplett freigestellt ist, kann eine Anwendung vom Entwickler nahezu komplett ohne das Framework programmiert und gewünschte Funktionen beliebig verwendet werden.
Die folgende Auflistung zeigt die Versionen des Frameworks und die jeweilige Fertigstellung:
Version 2.0 (Juli 2018)
Version 1.8 (September 2017)
Version 1.7 (Juli 2017)
Version 1.6 (November 2016)
Version 1.5 (September 2016)
Version 1.4 (Mai 2016)
Version 1.3 (März 2016)
Version 1.2 (Februar 2016)
Version 1.1 (Dezember 2015)
Version 1.0 (August 2015)
Die folgende Auflistung beschreibt einige Fakten bezüglich des Frameworks:
Aktuelle Version: 2.0 (Juli 2018)
Anzahl an PHP-Codezeilen: 27.056
Anzahl an JS-Codezeilen: 935
Anzahl an PHP-Dateien: 159
Anzahl an PHP-Klassen: 81
Anzahl an PHP-Funktionen: 908
Anzahl an git Commits: 1.324
Entwicklungszeitraum: ca. 10 Jahre
Das Framework bietet dem Entwickler eine Fülle von nutzbaren Funktionen und Modulen. Eine Auswahl der wichtigsten Funktionen werden im Folgenden möglichst kurz beschrieben:
Diese Funktion befreit Nutzereingaben automatisch von HTML-Elementen und verhindert XSS-Angriffe.
Das Model ermöglicht dem Entwickler eine einfache Relation zwischen Datenbanktabellen und Objekten in PHP herzustellen. Hierbei kann der Entwickler Objekte in die Datenbank schreiben, aus der Datenbank lesen und Objekte löschen. Haben Objekte Referenzen auf andere, so werden diese automatisch bei einem Aufruf aus der Datenbank geladen. Die integrierte Suchfunktion bietet die Möglichkeit Objekte in der Datenbank nach beliebigen Attributen und Kombinationen (UND|ODER|NICHT) zu suchen.
Alle Datenbankabfragen werden über Prepared Statements durchgeführt, um automatisch SQL-Injections zu verhindern. Der Anwendungsentwickler muss sich daher über eine solche Absicherung keine Gedanken machen.
Für jedes Objekt muss eine PHP-Klasse angelegt werden. Diese kann mithilfe der Generierfunktion sehr einfach und automatisiert erstellt werden.
Beispiel - Speichern eines PHP-Objekts (neu oder bereits vorhanden):
$model->setObject($object, true);
Beispiel - Löschen eines PHP-Objekts:
$model->deleteObject($object);
Beispiel - Anlegen einer Funktion zum parametrisierten Auslesen von Objekten im Model:
public function getVarStringsByNameLanguageAndString($name, $language, $string) { $whereCondition = 'BINARY name=? AND BINARY language=? AND BINARY string=?'; return $this->getFirstElement($this->getObject('CsfVarStringBean', $whereCondition, array($name, $language, $string))); }
Exceptions können mit der Funktion throwException an beliebigen Stellen geworfen werden. Die im Framework entwickelte Exception-Funktionalität erweitert das Werfen von Exceptions um das automatische Speichern aller relevanten Informationen in einer Log-Datei und das Ausgeben von für den Benutzer wichtigen Informationen in einer Infobox in der von ihm ausgewählten Sprache.
Das Framework besitzt eine Sprachimplementierung die es dem Entwickler erlaubt die Webseite auf beliebig vielen Sprachen anzubieten. Alle Texte werden als Platzhalter eingebettet und durch das Framework rekursiv und in der vom Benutzer ausgewählten Sprache vollkommen automatisch ersetzt.
Das Framework bietet sowohl eine Schnittstelle zum Versenden als auch zum Empfangen von E-Mails. Hierbei können E-Mails mit variablen Textbausteinen und verschiedenen Sprachen erstellt und hinterlegt werden.
Das Framework bietet eine einfache Funktion zum Erstellen von Validierungen über einen Link in einer E-Mail an. Diese Funktion kann für beliebige Vorgänge verwendet werden. Für das Zusenden der E-Mail, das Erstellen eines Validierungslinks und die Funktionalität bei Anklicken des Links übernimmt das Framework komplett. Diese Funktionalität wird beispielsweise für die Aktivierung des Benutzeraccounts verwendet.
Das Framework implementiert ein eigenes Session-System, welches deutlich sicherer, als das von PHP vorhandene ist. Dieses System kann zusätzlich genutzt werden, um eigene Variablen über Aufrufe hinweg zu speichern. Ein automatisches Erkennen von eingeloggten Benutzern, sowie der temporär ausgewählten Sprache, wird ebenfalls über dieses Session-System umgesetzt.
In den Settings des Frameworks kann die Expiry-time der Sessions festgelegt werden. Die expiry-Implementierung des Frameworks ist deutlich sicherer, als die in PHP integrierte. Um Session-Übernahmen durch Cookie-Klau zu erschweren wird die SessionID automatisch alle 5 Minuten erneuert und die alte SessionID auf Server- und Clientseite entfernt. Um den Angriff "Session fixation" zu verhindern wird nach erfolgreichem Log-in eines Benutzers die verwendete SessionID durch eine neu erzeugte ersetzt und die alte SessionID gelöscht. Zusätzlich speichert die Session Informationen über den Benutzer. Sollten diese sich zwischen zwei Aufrufen verändern, so wird der Benutzer automatisch ausgeloggt und die Session gelöscht.
Das Framework bietet eine einfache Methode für Multithreading (siehe unten). Da die Threads nicht auf das eigene System beschränkt sind, sondern auf beliebigen Computern ausgeführt werden können, können hier auch Ergebnisse, die nicht verlässlich sind, zurückgegeben werden. Hierfür gibt es die reliableWorker-Funktion. Diese verteilt automatisch eine "Aufgabe" an verschiedene Worker auf unterschiedlichen Systemen. Anschließend werden die Antworten ausgewertet und das Ergebnis mit den meisten identischen Antworten, sowie eine Bewertung, wie verlässlich die Antwort ist, zurückgegeben.
Eine integrierte Trigger-Funktion ermöglicht es dem Framework Aufgaben in periodischen Abständen durchzuführen. Hierbei kann jede Aufgabe beliebigen Code oder Aufrufe enthalten und zeitlich wie Cronjobs eingestellt werden. Mit dieser Funktionalität ist es beispielsweise möglich innerhalb weniger Zeilen Code ein eigenes Chronjob-System aufzusetzen, welches einem Benutzer beliebige automatisierte Aufrufe externer Webseiten zu beliebigen Zeiten ermöglicht.
Das Framework besitzt eine eingebaute Prüffunktion, die Änderungen am Code in einem eingestellten Zeitintervall erkennt. Nach einer erkannten Veränderung des Frameworks oder der Anwendung erhält der Administrator unverzüglich eine E-Mail mit weiterführenden Informationen. Dies wurde aus Sicherheitsgründen eingeführt, da ein erfolgreicher Hacker möglicherweise den Code verändert oder Dateien hinzufügt. Dies erlaubt dem Administrator Veränderungen sofort zu erkennen und darauf zu reagieren.
Als weitere Funktion bietet das Framework sehr einfach zu verwendende Funktionen zum Ver- und Entschlüsseln von beliebigen Inhalten an. Da es eine Vielzahl von Einstellmöglichkeiten und zu beachtenden Vorgängen bei einer ordentlichen Verschlüsselung gibt, wurde dies vom Framework gekapselt. Zur Ver- und Entschlüsselung wird hierbei lediglich ein Passwort benötigt. Die Verschlüsselung wird stets mit AES-256 durchgeführt.
Neben der oben genannten Verschlüsselung bietet das Framework eine weitere Möglichkeit zur Verschlüsselung. Beispielsweise sollen in der zu entwickelnden Anwendung viele und/oder große Dateien verschlüsselt werden. Da ein Ändern des Passworts durch den Benutzer rechenintensiv ist, wurde ein System integriert, welches alle Dateien mit einem zufällig generierten, extrem langen Schlüssel verschlüsselt. Dieser zufällig generierte Schlüssel wird anschließend durch das Passwort des Benutzers verschlüsselt. Der zufällig generierte Schlüssel verlässt hierbei niemals das System. Ändert ein Benutzer nun sein Passwort, so muss lediglich der automatisch generierte Schlüssel neu verschlüsselt werden. Alle hierfür benötigten Funktionalitäten werden durch das Framework dem Entwickler fertig zur Verfügung gestellt.
Eine Funktion des Frameworks bietet die Möglichkeit ganze Ordner zu einer Datei zusammenzufassen und zu minimieren. Dies bietet sich beispielsweise für CSS-Ordner oder JS-Ordner an. Ruft der Client-Browser diese Funktion beispielsweise als CSS-Datei ab, so wird bei der Abfrage der komplette CSS-Ordner ausgelesen, alle CSS-Dateien zusammengeführt und anschließend durch einen integrierten CSS-Minimizer minimiert. Das Ergebnis erhält der Client-Browser anschließend mit richtigem Typ. Hierbei erkennt das Framework automatisch ob es sich um CSS- oder JS-Dateien handelt, wählt den richtigen Minimizer und setzt den richtigen Response-Header.
Die Klasse FileSystem bietet eine einfache und schnelle Möglichkeit von Dateisystemoperationen über das Framework.
Einfache Navigation durch up() und down(dirname) Funktionen.
Einfaches Auslesen (getPathname()) und direktes Setzen des Dateipfads (setPathname(dateipfad)).
Zwischenspeichern des aktuellen Pfades auf einen Stack pushPath() und zurückspringen popPath().
Auslesen aller enthaltenen Dateien (getFiles()) und Ordner (getDirectories()) des aktuellen Ordners (Rückgabe als Array).
Einfaches Auslesen von Datei- und Ordner-Eigenschaften mit getFileInformation(filename) und getDirectoryInformation.
Einfaches Erstellen des MD5 und SHA Hashes einer Datei.
Einfaches Lesen, Schreiben, Erstellen, Erweitern, Überschreiben und Löschen von Dateien.
Einfaches Erstellen und Löschen von Ordnern.
Einfaches Kopieren und Einfügen von Dateien.
Einfaches Überprüfen ob eine Datei im aktuellen Ordner vorhanden ist oder nicht.
Einfaches Erstellen eines Hashs über alle Dateien in einem Ordner und allen Unterordnern.
Komplette rekursive Suche nach Dateinamen im Dateisystem mittels String oder RegEx.
Einfaches Packen und Entpacken von ZIP-komprimierten Dateien.
In dem Adminisatorbereich des Frameworks sind alle Funktionen bereits in einem Explorer [Abbildung 1] integriert. Dieser bietet neben den oben genannten weitere Funktionen, wie beispielsweise das Betrachten von Bildern, schreiben von Textdateien und weitere.
Abbildung 1: Explorer
Die Json-Klasse bietet die Möglichkeit, ein beliebiges JSON-Objekt dynamisch zu erstellen. Bei jedem Aufruf von $csf->getNewJson() wird ein neues CsfJson-Objekt generiert und zurückgegeben. Anschließend kann das CsfJson-Objekt über die Setter-Methoden mit Werten und der Angabe des Datentyps gefüllt werden. Setter-Methoden stehen für Boolean, Number, String, Array und Object zur Verfügung.
Das so erstellte und beliebig erweiterbare beziehungsweise jederzeit anpassbare Objekt kann entweder als natives PHP-Objekt über getAsObject() (für eine weitere Bearbeitung) oder als JSON-String über getAsJson() abgefragt werden.
Die Linker-Klasse ist zum Packen des Frameworks gedacht. Das Framework kann sowohl im originalen, als auch im gepackten Zustand verwendet werden. Das Packen löscht alle nicht benötigten Dateien und Dokumentationen, packt eine Vielzahl von Dateien zu einer zusammen und löscht Kommentare, Leerzeilen, Zeilenumbrüche, ... aus dem Code. Hierdurch reduziert sich die Größe des Frameworks auf ca. 35% der ursprünglichen Grüße und die Ausführungszeit erhöht sich um ca. 20%. Das Framework kann jederzeit, auch während des Livebetriebs, über den Linker gepackt werden.
Das Logging-Konzept bietet die Möglichkeit Log-Meldungen zu erstellen und zu speichern.
Das Logging bietet die Möglichkeit, Log-Meldungen in den Code einzustreuen, die automatisch in die Log-Datei geschrieben werden. Für jeden Tag wird eine neue Log-Datei angelegt. Über die Einstellungen des Frameworks (Settings) lässt sich festlegen, welcher LogLevel verwendet, ob Debugging- und/oder DB-Logs eingetragen und ob Debugging-Logs in einer separaten Datei abgelegt werden sollen.
Die Log-Dateien können im Adminbereich des Frameworks wieder eingelesen, gefiltert und durchsucht werden.
Das sichere Logging bietet die Möglichkeit Log-Meldungen sicher vor Veränderungen und Manipulation, mit der BlockChain-Technik abzuspeichern. Hierbei kann ein beliebiges Set an verschiedenen Log-Ketten aufgebaut werden. Jede Log-Kette erhält hierbei einen eindeutigen Namen.
Das sichere Logging enthält den Namen (Hash-Kette), den Hash des vorherigen Logs, einen Timestamp, die zu loggenden Daten, einen Integer-Wert zur Erschwerung der Re-Generierung neuer Hashes sowie einen Hash über den kompletten Log (ohne den finalen Hash). Wird ein Log eingetragen wird sowohl der Log in die Log-Datei geschrieben, als auch als E-Mail an die in den Settings hinterlegte E-Mail-Adresse verschickt. Durch die Hashes mit integrierter Verkettung ist es einem Angreifer nicht möglich eine Log-Meldung zu verändern, hinzuzufügen oder zu löschen. Soll eine Log-Meldung gelöscht werden, müsste man die komplette Kette der Logs neu schreiben und die dazugehörigen Hashes berechnen. Durch das Versenden der Logs mit allen Hashes per E-Mail müsste der Angreifer sowohl die Log-Datei fälschen, alle Logs neu schreiben und berechnen und das E-Mail Postfach manipulieren, was nahezu ausgeschlossen ist.
Alle Log-Dateien können nicht nur geschrieben, sondern auch ausgelesen und validiert werden. Hierfür stehen spezielle Funktionen zur Verfügung.
Um offline Webanwendungen zu erstellen, wird ein sogenanntes Manifest benötigt. Das Framework kann diese durch das Auslesen aller Dateien, Ordnern und Unterordnern automatisch erstellen. In den Einstellungen des Frameworks können hierfür Dateien, Ordner, ... die nicht mit aufgenommen werden sollen, festgelegt werden.
Die Multithreading-Funktionen des Frameworks erlaubt es, Worker auf demselben oder auf einem anderen System anzusprechen und Aufgaben (PHP-Code) zu verteilen. Für jeden Aufruf eines Workers wird ein eigenständiger Thread verwendet. Lokale Worker auf dem gleichen System werden unverschlüsselt, remote Worker mittels AES265-Verschlüsselung und SHA512-Check angesprochen. Aufrufe eines Workers können sowohl synchron, als auch asynchron oder asynchron mittels "fire and forget" durchgeführt werden. Ferner ist es möglich, dass mehrmals derselbe Worker angesprochen wird. Dies erzeugt für jeden Aufruf einen eigenen Thread auf dem System des Workers.
Beispiel:
$worker[] = $this->csf->getNewMultithreading(); // create a new worker $worker[0]->init($this->userWorker->getUrl(), $this->userWorker->getPassword()); // initialize the worker with the userWorker/server data. $worker[0]->doWork('echo "Hallo";', 'false'); // first thread (worker 1) ... $worker[1]->doWork('echo "Hallo2";', 'false'); // second thread (worker 2) ... while(!$worker[1]->isFin()) {usleep(300000);} // check every 0.3 seconds if the worker is finish. return $worker[1]->getResponse(); // read the response of the worker
Der Store im Framework bietet die Möglichkeit beliebige Key-Value-Paare im RAM abzulegen und wieder zu lesen. Alle abgespeicherten Daten stehen nur während der Bearbeitung des aktuellen Requests zur Verfügung.
Der RamDrive Store bietet dieselbe API wie der normale Store. Der Unterschied ist lediglich die Speicherung der Daten. Diese werden im RamDrive Store als Datei auf der Festplatte (im Ordner "ramDrive") gespeichert. Für eine sehr starke Steigerung der Performance sollte dieser Ordner als RamDrive angelegt/eingebunden werden.
Der permanente Store im Framework bietet dieselbe API wie der normale Store. Alle abgespeicherten Daten werden beim PermanentStore permanent in der Datenbank abgelegt, bis sie wieder gelöscht werden. Daher ist eine Speicherung und Verwendung von Werten über verschiedene PHP-Aufrufe hinweg (unabhängig des Aufrufers) möglich.
Die Privileges-Funktionen des Frameworks bieten dem Entwickler ein umfangreiches und vollständig implementiertes Rechtemanagement für Projekte. Hierbei können beliebige Rechte angelegt, Nutzer mit beliebigen Rechten ausgestattet und Funktionen einfach um die Prüfung auf Rechte erweitert werden. Rechte können beliebig angelegt, gelöscht und Benutzern zugeordnet werden. Rechte können sich von anderen ableiten und die Überprüfung, ob ein Benutzer das Recht zum Zugriff auf die Methode besitzt, wird nicht nur über die direkten Zuordnungen zwischen Rechten und Benutzern, sondern rekursiv auch auf abgeleitete Rechte durchgeführt.
Die Rest-Funktionen des Frameworks bieten dem Entwickler die Möglichkeit, einfach und schnell REST-Schnittstellen umzusetzen. Hierbei können alle HTTP-REST-Methoden (GET, POST, PUT und DELETE) verwendet werden. Für jede REST-Schnittstelle muss angegeben werden, welchem HTTP-Method-Type sie angehört, sowie eine Liste mit Parametern, die erwartet wird. Für jeden erwarteten Parameter muss zusätzlich ein Typ angegeben werden, der automatisch vom Framework überprüft wird. Hierbei wird automatisch der Typ und der Inhalt der Benutzereingaben geprüft und von XSS und anderen ungewollten Eingaben befreit.
Beispiel - Anlegen einer REST-Schnittstelle mit zwei aufrufbaren Funktionen:
case "user/admin/lockuser": if($param = $csf->getRest()->restParamCheck('PUT', array('email' => 'TEXT'))) { $csf->getPrivileges()->requirePrivileges(array('admin')); $csf->getResponse()->setHttpStatusCode(200) ->appendContent($csf->getUser()->lockUser($param['email'])) ->send(); } break; case "user/admin/unlockuser": if($param = $csf->getRest()->restParamCheck('PUT', array('email' => 'TEXT'))) { $csf->getPrivileges()->requirePrivileges(array('admin')); $csf->getResponse()->setHttpStatusCode(200) ->appendContent($csf->getUser()->unlockUser($param['email'])) ->send(); } break;
Das Framework bietet eine Vielzahl (>80) von Einstellungsmöglichkeiten, die durch den Entwickler beliebig erweitert und verändert werden können. Statische Settings werden in einer Datei, dynamische in einer Datenbanktablle gespeichert. Das Framework wurde so konzipiert, dass an jeder Stelle die eine Option bieten kann, diese auch in die Settings ausgelagert wurde.
Beispiele für Settings:
themeName: Gibt den Namen des zu verwendenden Themes (Design) für die Webseite an. Es können beliebige Designs erstellt und verwendet werden.
domain: Gibt den Domainnamen der Webseite an.
rsVersion: Gibt die Version der REST-Schnittstelle an, die verwendet werden soll.
defaultLocale: Gibt die Standard-Sprache der Webseite an, die verwendet wird, wenn der Benutzer keine Sprache ausgewählt hat.
maxFailedLogins: Gibt die Anzahl an falschen Log-in-Versuchen bis zu einer ersten Sperrung des Benutzeraccounts an.
maxLoginTriesOfOneIP: Gibt die Anzahl an falschen Log-in-Versuchen pro IP-Adresse bis zu einer Sperrung (unabhängig des Accounts) an.
displayCookieInfo: Gibt an, ob eine Datenschutzbestätigung für Cookies auf der Webseite angezeigt werden soll oder nicht.
disableHtmlByUserInput: Gibt an, ob bei jeder Eingabe eins Benutzers automatisch HTML-Entities entfernt werden sollen.
requireSSL: Gibt an ob die Webseite nur mit HTTPS ausgeliefert werden darf. Ein HTTP-Aufruf führt automatisch zu einem Redirect.
defaultDateFormat: Gibt das Datumsformat für alle Ausgaben auf der kompletten Webseite an.
sessionExpiry: Gibt die Zeit bis die User-Session auf Serverseite abgelaufen ist an.
passwordPattern: Gibt per RegEx ein Pattern an, welches die Passwörter auf der Webseite erfüllen müssen.
...
Mit den Sockets-Funktionen des Frameworks hat man die Möglichkeit eine Verbindung (HTTP/HTTPS) zu einem beliebigen Webserver aufzubauen und beliebige Daten zu Übertragen, oder gesamte HTML-Seiten abzurufen. Hierbei stehen die HTTP-Methoden GET, POST, PUT und DELETE zur Verfügung.
Neben dem Berechtigungssystem bietet das Framework eine umfangreiche und vollständige Benutzerverwaltung. Hierbei können Benutzer angelegt, geändert und gelöscht werden. Zudem ist eine Suche nach Benutzern über Parametern, das Sperren, Entsperren, Ein- und Ausloggen, Validieren der E-Mail-Adresse und diverse weitere Funktionen fertig implementiert. Über den Adminisatorbereich des Frameworks können die Benutzer der Webseite grafisch verwaltet werden. Die Benutzerobjekte sind hierbei so offen gestaltet, dass Anwendungsentwickler dem Benutzerobjekt beliebige weitere Attribute geben können. Diese werden automatisch mit in der Datenbank abgespeichert und stehen zu den bereits vorhanden Attributen jederzeit zur Verfügung.
Die Utile-Funktionen des Frameworks beinhalten alle Methoden, die keiner anderen Klasse zuzuordnen sind. Aber für Anwendungen sehr nützlich sein können.
Im Folgenden werden einige Funktionen der Utile-Klasse vorgestellt:
getRandHash: Diese Funktion liefert einen zufälligen Hash zurück, der beispielsweise für E-Mail Validierungen verwendet werden kann.
getPasswordHash: Diese Funktion wandelt das Passwort des Benutzers und den dazugehörigen Salt in den Hash des Passworts um, welcher anschließend überprüft wird.
checkPassword: Diese Funktion überprüft das Passwort des Benutzers.
createRandPassword: Diese Funktion generiert ein zufälliges Passwort, welches dem PasswordPattern in den Settings entspricht.
getIntToCreateHashWithBeginningZeros: Diese Funktion sucht einen Integer-Wert, der einen Hash-Wert mit einer angegebenen Anzahl von führenden Nullen aus dem angegebenen Text erstellt. Dies wird verwendet, um die BlockChain des permanenten Loggings abzusichern.
minifyPhp: Diese Funktion ließt PHP-Code ein und minimiert diesen, indem Leerzeichen, Leerzeilen, Tabulatoren, Kommentare, ... entfernt werden.
sortArrayByLength: Diese Funktion sortiert ein Array nach der Anzahl der Zeichen.
trueByLikelihood: Diese Funktion gibt true mit der angegebenen Wahrscheinlichkeit zurück. Dies wird verwendet um das Ergebnis von Wahrscheinlichkeiten zu erhalten.
getParsedPhpFile: Diese Funktion lässt ein PHP-Skript durch den PHP-Interpreter laufen und liefert das Ergebnis als Response zurück.
Check Funktionen: Die Utile-Klasse hat eine Vielzahl von Check-Funktionen, die beispielsweise Objekte überprüfen, ob diese vorhanden oder gelöscht sind, oder ob Credentials vom Benutzer stimmen.
Timing Funktionen: Die Timing-Funktionen erlauben es dem Entwickler, während der Entwicklung, Laufzeitanalysen des PHP-Codes durchzuführen und so den PHP-Code zu optimieren.
Neben der Logik, dem Model und der REST-Schnittstelle bietet das Framework eine eigene View-Komponente. Die View ist dabei so gestaltet, dass es eine Reihe von unabhängigen HTML-Blöcken gibt, mit deren Hilfe Webseiten einfach und schnell im Baukastenprinzip zusammengebaut werden können, keine Komponente aber verwendet werden muss. Der Entwickler einer Webseite kann jederzeit eigene Blöcke mit Logik hinzufügen und so die Anwendung um weitere Komponenten erweitern.
Die View-Komponente des Frameworks nimmt hierbei einen Großteil der zu implementierenden Logik ab. Hierzu zählen beispielsweise das Überprüfen von Parametern auf ausgefüllt/required oder ihren Typ, das Einloggen von Benutzern, das Setzen der Sprache, das Absichern von Eingaben, das Setzen von Meldungen für den Benutzer, das Anzeigen von Eingabefeldern und vieles weitere.
Alle Komponenten, sowie die komplette View können jederzeit durch den Entwickler verändert, durch Parameter angepasst oder in den Settings verändert werden. Meist stehen mehrere Ausprägungen und Designs für eine Komponente zur Verfügung. Hierzu zählt beispielsweise die Implementierung einer Cookie-Abfrage. Diese kann in den Settings aktiviert werden und anschließend erhält die Webseite eine Abfrage für Cookies mit Bestätigung.
Die View des Frameworks ist zudem modular aufgebaut, sodass ein Entwickler beliebige Themes für das Framework erstellen kann. Hierbei richtet sich der Aufbau der Themes an den Themes von Joomla. Dadurch ist es innerhalb von kurzer Zeit möglich, Joomla Themes in das System des Frameworks zu überführen und so eine Vielzahl von bestehenden Themes sofort nutzbar zu machen.
Das Framework bietet von Haus aus drei vorgefertigte Themes, die für beliebige Anwendungen verwendet werden können. Im Folgenden wird eine Auswahl an vorhandenen Elementen, die auf jeder Seite eingesetzt werden können vorgestellt:
Alert - Erstellt eine Meldung für den Benutzer. Diese kann in verschiedenen Farben ausgegeben werden und beliebigen Text enthalten. Alerts können vom Benutzer über das "x" wieder geschlossen werden.
Section - Erstellt eine Section in der HTML-Seite, welche automatisch in den ScrollSpy aufgenommen wird. Sie fügt automatisch vor jeder Section eine abgetrennte Überschrift mit der gewählten Hintergrundfarbe ein.
Extended Section - Erstellt eine Section mit optionalem Hintergrundbild. Das Hintergrundbild kann wie im Google-Kalender mitscrollen, wobei das Scrollverhalten einstellbar ist. Die Extended Section verwendet speziell für Smartphones und Tablets angepasste Überschrift.
NewsBox - Eine Box auf einer Seite, die mit News (Titel, Anreißertext, Bild, URL, Datum) gefüllt wird.
Chart - Ein Chart/Diagramm, mit unterschiedlichen Diagrammtypen, welches mit JavaScript automatisch in einem Canvas gezeichnet wird.
Panel - Ein Panel, bestehend aus einem Head/Überschrift und einem beliebigen Content. Klickt man auf den Head, so kann der Content ein- bzw. ausgeklappt werden. Ein Festlegen des initialen Zustands ist durch die Parameter der Funktion möglich.
Table - Eine Tabelle, die ein Zebra-Muster enthält und optional durch den Benutzer sortiert werden kann. Zudem ist jede Tabelle einklappbar.
Pagination - Eine Anzeige auf welcher Seite man sich gerade befindet (mit der Möglichkeit des Seitenwechsels).
ProgressBar - Eine Fortschrittsanzeige.
Searchbox - Ein Suchfeld das auf Serverseite automatisch überprüft wird.
Form - Ein Formular in das Formularelemente eingesetzt werden können.
Button - Erstellt einen Bootstrap-formatierten Button mit oder ohne Link.
Input - Eingabefeld, mit optionaler Validierung, in beliebigen Typen (input, email, color, ...).
DateInput - Datums-Eingabefelder die ein PupUp zur Auswahl des Datums zeigen. Bietet viele Optionen welche Werte erlaubt sind und welche nicht. Zudem bietet es die Möglichkeit zwei Date-Eingabefelder miteinander zu verknüpfen (Start und Ende).
InputGroup - Zum Gruppieren von Checkbox- und Radio-Eingabefeldern. Jedes Input-Element besitzt einen Titel, der vor dem Input angezeigt wird. Da dies bei Radio und Checkbox nicht der Fall ist, können diese gruppiert werden. Die Gruppierung fügt den Titel und die Beschreibung ein.
Checkbox und Radio - Erzeugt Eingabefelder wie im HTML-Standard definiert.
Select - Eine Auswahlliste.
Separator - Fügt eine horizontale Trennlinie ein.
Modal - Fügt der Seite ein PopUp/PopOver hinzu, das beliebigen Inhalt enthalten kann.
Vorgegebenes Log-in-Modal, dass ein Modal für das Einloggen eines Benutzers öffnet.
Vorgegebenes Language-Modal, dass ein Modal für das Auswählen der aktuellen Sprache öffnet.
Vorgegebenes Confirm-Modal, dass ein Modal zur Bestätigung einer Benutzeraktion oder einer Information mit belieben Aktionen bei Akzeptierung ausführen kann.
Carousel - Ein Karussell, dass Inhalt/Bilder in mehreren Seiten (scrollen links-rechts) anzeigen kann. Diverse Einstellmöglichkeiten sind vorhanden.
ScrollToTop - Ein Button, der am unteren Bildschirmrand erscheint, wenn der Benutzer mehr als x Pixel nach unten gescrollt hat. Durch einen Klick auf den Button scrollt die Seite (mit einem slide-Effekt) nach oben.
ScrollspyBubble - Ein Scrollspy am Rand der Seite, dass per Punkt anzeigt, bei welcher Section sich der Benutzer gerade befindet. Ein Klick auf einen Punkt scrollt zur referenzierten Section. Sections und Extended Sections werden dem Scrollspy automatisch hinzugefügt.
Über Einstellungen in den Settings des Frameworks kann das Verhalten und Aussehen der kompletten View-Komponente angepasst werden. Dennoch können beliebige Einstellungen in jedem Servlet überschrieben und so die Anzeige individuell angepasst werden. Im Folgenden wird eine Auswahl an Einstellmöglichkeiten vorgestellt:
metaDescription - Über diesen Funktionsaufruf kann jedes Servlet eine eigene Beschreibung, für Benutzer, die die Seite über eine Suchmaschine suchen, angegeben werden.
displayWholeFooter - Schalter der festlegt ob der komplette Footer oder nur eine minimierte Version angezeigt werden soll.
displaySidebar - Schalter der festlegt ob das Navigationsmenü auf der linken Seite mit eigenem Scrollspy angezeigt oder der Content die komplette Breite der Seite verwenden soll.
theme - Einstellung die festlegt, welches Theme das Servlet verwenden soll.
Möglichkeit einen eigenen CSS-Klassennamen für das body-Element zu setzen. Hierdurch wird das einfache Verwenden eigener CSS-Regeln für das aktuelle Servlet möglich.
displayScrollspyBubble - Schalter der festlegt, ob ein Scrollspy mit Punkten, der die aktuelle Position im Dokument anzeigt, angezeigt werden soll.
displayScrollUpButton - Schalter der festlegt, ob ein Button angezeigt werden soll, der die Seite mit einem Klick wieder ganz nach oben scrollt.
breadcrumb - Zeigt den Aufrufpfad der aktuellen Seite an, damit der Benutzer zurück navigieren kann.
Das Framework wurde nach dem Grundsatz "Secure by default" entwickelt und versucht deshalb möglichst alle sicherheitskritischen Fälle in der Anwendung ohne das Zutun des Entwicklers abzufangen.
Funktion in der Csf-Klasse, die Strings von XSS-Angriffen befreien kann. Diese wird beispielsweise zur Reinigung des $_SERVER-Arrays verwendet, da hier XSS-Code enthalten sein kann.
Verpflichtendes HTTPS in den Settings einstellbar. Automatische Umleitung auf HTTPS, wenn eine Seite mit HTTP aufgerufen wird.
Zugriff auf Ordner durch .htaccess - Dateien blockiert. Bei einem anderen Webserver als Apache muss dies anderweitig umgesetzt werden!
Directory Listung durch das Vorhandensein einer index.php-Datei in jedem Ordner unterbunden.
In den Settings einstellbar, dass keine PHP-Fehler ausgegeben werden. (Für Test- und Entwicklungszwecke kann dies deaktiviert werden.)
Session wird nach X Minuten Inaktivität sicher gelöscht. Bei der PHP-eigenen Implementierung ist dies nicht sichergestellt.
SessionId wird alle 5 Minuten erneuert. Hierbei wird die alte SessionId auf Client- und Server-Seite gelöscht.
Angriff des "Session fixations" wird verhindert, indem die SessionId nach dem erfolgreichen Log-in sofort erneuert und die alte gelöscht wird. (Siehe vorherigen Punkt)
Alle temporären Daten (Zustandsdaten) für Benutzer werden niemals in einem Cookie, sondern in der Session (auf Serverseite) gespeichert.
Ändert sich bei einem eingeloggten Benutzer der "HTTP_USER_AGENT" (Informationen über Browser, Betriebssystem, ...), die "REMOTE_ADDR" (IP-Adresse) oder die "HTTP_ACCEPT_LANGUAGE" (Die Liste von Sprachen die der Browser akzeptiert), wird die Session auf Serverseite umgehend gelöscht und ein erneutes Einloggen ist nötig.
Absicherung gegen SQL-Injection durch das ausschließliche Verwenden von Prepared Statements.
Absicherung gegen XSS-Angriffe (die meisten). Alle Parameter bei den Servlets und alle Parameter des Typs TEXT und LENGTH der REST-Schnittstelle werden automatisch HTML-Entitites escaped. Ist das Escaping nicht gewünscht, so muss dies beim Abrufen des Parameters explizit angegeben werden. Bei der REST-Schnittstelle ist das Deaktivieren nicht möglich. Hier kann allerdings die "Umkehrfunktion" (html_entity_decode) auf das Ergebnis angewendet werden.
Die Passwörter der Benutzer werden gesalzen (zufällige Generierung) und als SHA512 in der Datenbank abgelegt.
Wird das Passwort eines Benutzers mehr als X mal (in den Settings konfigurierbar (Standard ist 3)) falsch eingegeben, wird der Account gesperrt und der Benutzer muss diesen über einen Link per E-Mail (automatischer Versand) erneut freischalten.
Parameter (über REST oder Servlets) können und sollten die Typ-Überprüfungen verwenden, welche sehr einfach genutzt werden können. (Bei REST ist dies Pflicht.) Für die Parameter stehen Typ-Überprüfungen auf "TEXT", "[RegEx]" (Eigens definierter RegEx), "INT", "FLOAT", "NUMERIC", "BOOLEAN", "[Size]" (max. Länge eines Strings), "EMAIL", "DATETIME", "DATE", "TIME", "URL", "IP" und "[range]" (Int in einem definierten Zahlenbereich) zur Verfügung.
Alle Servlets (View) und REST-Schnittstellen, sowie Funktionen (Controller), die nur für berechtige Benutzer zugänglich sein sollten, können mit einer entsprechenden Rechteabfrage versehen werden. Alle Admin-Funktionalitäten die das Framework mit ausliefert, sind durch das Recht "admin" standardmäßig abgesichert. Beliebige Rechte können angelegt und beliebigen Benutzern zugewiesen werden. Um die Sicherheit zu erhöhen ist es zusätzlich möglich ein Ablaufdatum für die Zuordnung zwischen Benutzer und Recht festzulegen.
Das Einlesen von Log-Dateien ist durch Escaping gegen XSS geschützt.
Alle Formulare übertragen per default alle Eingaben per POST.
Log-out löscht Session auf Serverseite.
Automatisches Erstellen eines Formular-Tokens, wenn ein Formular verwendet wird. Beim Absenden wird das Token automatisch validiert. Dies schützt vollkommen automatisch vor CSRF-Angriffen.
Bei Benutzereinstellungen muss zusätzlich das aktuelle Passwort des Benutzers eingegeben werden. Dies schützt zusätzlich zum Formular-Token vor CSRF-Angriffen.
In den Settings ist ein Pattern (RegEx) für sichere Passwörter definiert. Jedes Passwort eines Benutzers muss diese Überprüfung bestehen. Die RegEx kann jederzeit beliebig angepasst werden und gilt nur für neue/geänderte Passwörter.
Die Mail-Funktion wurde gegen XSS und Splitting abgesichert.
Bei zu vielen falschen Passworteingaben (unabhängig des Benutzernamens) wird die IP-Adresse des Anfragenden gesperrt.
Die Benutzeraccounts besitzen eine Absicherung gegen zu viele falsche Log-in-Versuche, um das Ausprobieren aller möglichen Passwörter zu verhindern. Hierbei werden die fehlerhaften Log-in-Versuche pro Account gezählt und nach jeweils fünf falschen Log-in-Versuchen eine Wartezeit erzwungen. Während der Wartezeit findet keine Überprüfung der Zugangsdaten statt. Die fehlerhaften Log-in-Versuche werden bei einem erfolgreichen Log-in zurückgesetzt.
Fehlerhafte Log-in-Versuche und anschließende Wartezeit:
05 fehlerhafte Log-in-Versuche: 2 Minuten Wartezeit
10 fehlerhafte Log-in-Versuche: 5 Minuten Wartezeit
15 fehlerhafte Log-in-Versuche: 10 Minuten Wartezeit
20 fehlerhafte Log-in-Versuche: 30 Minuten Wartezeit + E-Mail an den Accountbesitzer
25 fehlerhafte Log-in-Versuche: 2 Stunden Wartezeit + E-Mail an den Accountbesitzer
30 fehlerhafte Log-in-Versuche: 12 Stunden Wartezeit + E-Mail an den Accountbesitzer
In den Einstellungen kann der Entwickler über die Einstellung "maxFailedLogins" zudem festlegen, bei wie vielen fehlerhaften Log-in-Versuchen der Account eines Benutzer vollständig gesperrt werden soll. Bei vollständiger Sperre stehen keine Log-in-Versuche mehr zur Verfügung. Die einzige Möglichkeit den Account zu entsperren ist durch das Anklicken des Bestätigungslinks in der E-Mail oder durch das Wechseln das Passworts zum Account. Beim Wechseln des Passworts werden ebenfalls alle fehlerhaften Log-in-Versuche gelöscht.
Nach 20, 25, 30, sowie der vom Entwickler festgelegten Maximalzahl der fehlerhaften Log-in-Versuche erhält der Besitzer des Accounts, an die hinterlegte E-Mail Adresse, eine Nachricht über die fehlerhaften Log-in-Versuche und die Möglichkeit die fehlerhaften Log-in-Versuche, durch einen Klick auf den enthaltenen Link, zurückzusetzen. Dadurch hat der Besitzer der E-Mail Adresse stets Zugriff auf den Account und erkennt eine Anhäufung von unberechtigten Log-in-Versuchen.
Um zu verhindern, dass ein Angreifer alle Accounts durch das einfach durchprobieren von E-Mail-Adressen sperrt und so für ärger sorgt, wurde im Framework eine Schutzvorkehrung gegen solch einen Angriff implementiert.
Jeder Log-in-Versuch, welcher nicht zu einem erfolgreichen Log-in führt, wird mit der IP-Adresse des Anfragenden gespeichert. Hierbei werden alle falschen Log-in-Versuche über einen Tag hinweg zusammengezählt. Überschreitet die Anzahl an fehlerhaften Log-in-Versuchen die in den Einstellungen ("maxLoginTriesOfOneIP") festgelegten Wert, so werden Log-in-Anfragen von dieser IP-Adresse für den aktuellen Kalendertag blockiert.
Aus Sicherheitsgründen kann der Zähler der fehlerhaften Log-in-Versuche pro IP-Adresse und Tag nicht zurückgesetzt werden.
Im Folgenden werden die benötigte Software sowie die aktivierten PHP-Plugins, die zum Betrieb des Frameworks benötigt werden, aufgelistet:
Webserver
PHP >=5.5
PHP Plugins
date
filter
hash
json
mysql
session
sockets
openSSL/mcrypt
MariaDB / MySQL >=5.0
Mit der Verwendung der zentralen REST-Definition wird zusätzlich die RewriteEngine von Apache benötigt.
Das eigens entwickelte Framework ist bisher ein voller Erfolg. Hierdurch ist es möglich eigene und sichere Anwendungen (keine einfachen Webseiten) innerhalb kürzester Zeit zu erstellen. Dies wird ermöglicht, da das komplette Model und nahezu die komplette View (im MVC) durch das Framework abgenommen wird. Der Entwickler neuer Anwendungen muss sich lediglich um die Logik der Anwendung kümmern und kann hierbei auf eine Vielzahl von fertigen Komponenten, wie eine Benutzer- und Rechteverwaltung, Sprachenmanagement, Ver- und Entschlüsselungsfunktionen und diverse andere zurückgreifen, was die Entwicklung der Logik der Anwendung weiter beschleunigt.
Die ausführliche Beschreibung des Frameworks umfasst 64 A4 Seiten. Für weiterführende Informationen bezüglich des Frameworks oder anderer Projekte, können Sie mich gerne über das Kontaktformular kontaktieren.