Mit bncms kann jede Datenbank schnell in benutzerfreundlicher Form dargestellt werden. Die Datenbankrelationen werden visualisiert und den Datenbank-Feldern können CMS Typen zugewiesen werden wie HTML-Editor, Datum, Bildupload, Textarea, Passwort usw. Den Benutzern können Bereiche zugewiesen werden. Es vereinheitlicht und vereinfacht den Entwicklungsprozess und erlaubt es günstiger und schneller zu produzieren. Die Backendprogrammierung fällt bei Individuallösungen nahezu weg und man kann sich auf das Frontend konzentrieren. Geeignet für CRM, CMS, DBMS, Spezialprogrammierungen, überall wo rasch einige MySQL-Tabellen bearbeitbar gemacht werden müssen.
Vorteile
- Formulargenerierung, - validierung, -speicherung und -sicherheit sind zentralisiert. Codeänderungen betreffen automatisch alle Formulare. Das selbe ist mit den CRUD Abläufen von Tabellen möglich. Konfiguriert wird die Darstellung der Felder durch die Feldtypen, die den Tabellen bei der Erstellung im Administrationsbereich mitgegeben werden.
- Relationierte Daten können in die Formulare und Tabellen miteingefügt werden und können auch gleich bearbeitet werden. Dies ermöglicht es theoretisch jede Datenstruktur bearbeiten und visualisieren zu können. Bloss durch Konfiguration und Funktionsaufrufe.
- Der Code ist sehr simpel, leichtgewichtig und schnell (ca. 100 kB pro Seitenaufruf). Die Programmierung ist minimalistisch und pragmatisch. Die Einfachheit des Codes ist ein weiterer Pluspunkt der schnelle und kostengünstige Entwicklung ermöglicht.
Wieso bncms?
Die Programmierprozesse und Anforderungen sind im Webbereich im Grunde technisch gesehen immer die selben. Inhalte aus Tabellen müssen dargestellt werden und müssen auch in einem Administrationsbereich zugänglich gemacht werden (CRUD, Create Read Update Delete). Diese Daten sind in der Datenbank mit Relationen verbunden. bncms stellt einfach die Relationen (n zu 1 und n zu m Relationen) dar und bietet dann die CMS Funktionen für die Felder. Somit kann man jede Datenbank-Struktur rasch und übersichtlich darstellen lassen und es stellt die Datensätze samt involvierter relationierter Daten gleich auch zur Bearbeitung zur Verfügung. Es kann konfiguriert werden wieviel Benutzer sehen und so können zugeschnittene Mini-Backends in hoher und einheitlicher Qualität bereitgestellt werden, für jede erdenkliche Konstellation von Feldern und Tabellen.
In den HTML-Kopfbereich der Dateien in welchen mit bncms gearbeitet werden soll kommt folgendes<? define(RELATIVEPATHAPP,""); define(APPNAME,"bncms"); define(ADMINMAIL, "email@adresse.ch"); define(SALT, "SALT WERT VERGEBEN"); ?>
In den Körper kommt dies<script type="text/javascript" src="bncms/jquery.js"></script> <script type="text/javascript" src="bncms/lib/jquery-visible-master/jquery.visible.js"></script> <script>RELATIVEPATH = "<?= RELATIVEPATH?>";</script> <script type="text/javascript" src="bncms/frontend.inc.js"></script> <link rel="stylesheet" href="bncms/lib/jquery-ui/jquery-ui.min.css"> <script src="bncms/lib/jquery-ui/jquery-ui.min.js"></script> <link rel="stylesheet" href="bncms/frontend.css">
<?php require_once("bncms/inc/start.inc.php");?> <h3>Kontaktformular</h3><br> <?php if ($_POST[after] == "after_contact") { mail("", $_POST[title], $_POST[text]); echo "<script> alert('Nachricht gesendet.');</script>"; } $q = "CREATE TABLE IF NOT EXISTS `contact` ( `id` int(11) unsigned NOT NULL auto_increment, `name` varchar(25) NOT NULL default '', `email` varchar(50) NOT NULL default '', `title` varchar(50) NOT NULL default '', `text` text NOT NULL default '', `date` int(30) NOT NULL default '0', PRIMARY KEY (`id`) )"; dbQuery($q); displayRow( '', 'id', 'NUMMER_DER_TABELLE_IM_ADMINBEREICH', "<input type=hidden name=after value='after_contact'><input type=hidden name=date value='".time()."'>", "", $a ); ?>
<h3>Kontaktanfragen</h3><br> <?php displayTable(4,"id"); ?>
Grundidee
Auf die Idee für bncms kam ich als ich eine zeitlang extrem oft Datatables / CRUD erstellen musste. Ich
war damals angestellt als Programmierer eines CRM. Die Aufgabenstellungen waren äusserst oft sehr
ähnlich. In diesem Bereich geht es immer darum sehr Datenbank-nah und so einfach und kosteneffektiv wie
möglich auf Datensätze zuzugreifen und diese editieren, löschen und erstellen usw. zu können.
Normalerweise geschieht dies nur mit Datensätzen aus einer Tabelle (Beispiel Kontaktformular). Die
Darstellung der Felder ist dabei eigentlich immer ähnlich, Kalender, Bildupload, WYSIWYG usw und kann
standartisiert werden. Die einzige Erweiterung dieses Konzepts, die es eigentlich gibt, ist, dass Daten
aus verbundenen Tabellen auch in den Prozess integriert werden müssen. Beispielsweise wenn wir ein
Objekt haben Bestellungen, dann müssen oft Daten aus einem Objekt Produkte mit in einem Formular oder
einer Auflistung angezeigt werden. Dies ist meist das einzige was hinzukommt zum CRUD von einzelnen
Tabellen in der Datenbank. Es gibt nur zwei Arten von Verbindungen, n:1-Verbindungen und
n:m-Verbindungen, alle Daten sind immer so verbunden. Es ist eben auch so, dass vorallem im Backend
eigentich alle Vorgänge und Funktionen immer nur aus dieser Aufgabenstellung und solchen Formularen und
Auflistungen bestehen (Beispielsweise das Magento Backend besteht eigentlich nur aus Formularen und
Auflistungen). Im Backend ist auch das Design und die Personalisierung relativ unwichtig und wichtig ist
vorallem, dass es funktioniert, einfach und günstig ist. Wenn es doch möglich wäre diese Vorgaben mit
einer Library sauber abzudecken würde man sehr viel Zeit sparen und man könnte die Backend-Entwicklung
stark abkürzen und wurde somit Zeit und Ressourcen gewinnen um sich um andere Dinge wie das Frontend usw
zu kümmern.
Bncms fürs Frontend
Zudem kann bncms auch im Frontend eingesetzt werden. Wenn wir zum Beispiel eine Seite nehmen wie ein Jobportal. Auf dieser Seite gibt es vielleicht gut ein Dutzend verschiedene Formulare, welche eigentlich alle das selbe tun. Sie schreiben in eine Tabelle, manchmal auch in mehrere. Wie aufwändig wäre es jetzt jedes einzelne Formular für sich zu stylen, die Sicherheit abzuklären, testen usw. Es würde ein grosses Budget benötigen und auch sicherheitstechnisch ein Risiko darstellen. Es wären vielleicht mehrere Programmierer involviert und diese müssten sich an Standarts halten was sie eventuell nicht tun (Zeit- und Kostendruck) und als Konsequenz daraus müsste man zusätzliche Programmierer haben, die sich um die Sicherheit kümmern. Nicht so bei bncms. Die Sicherheit und die Funktionsweise der Formulare wird zentral gesteuert. Hat man das Sicherheitskonzept bei einem Formular integriert wird es bei jedem anderen Formular auch angewandt. Auf dem momentanen Stand des Skripts ist es nicht so personalisierbar und flexibel wie wenn mit einem herkömmlichen Framework jedes Formular einzeln entwickelt wird mit Templates usw aber darauf ist es auch nicht ausgerichtet. Es ist eher für Anwendungen gedacht, bei welchen die Personalisierung nicht eine so grosse Rolle spielt und vorallem schnell, kosteneffektiv und einfach verlässliche und sichere Applikationen bereitgestellt werden sollen.
Sicherheit
In Hinsicht auf die Sicherheit von Webanwendungen gibt es 4 Sicherheitslücken / Anfälligkeiten, deren
Absicherung man besondere Beachtung schenken muss wenn man sichere Webanwendungen erstellen will. Alle
anderen sicherheitstechnischen Anforderungen betreffen nicht die Anwendungsentwicklung sondern sind
systembedingt / anwenderbedingt und betreffen also die Computersysteme und die Anwender (zb Phishing,
SSL, Sicherheit der Computer, die Adminzugrif haben usw). Es gibt noch einige andere Dinge die
Sicherheitslücken öffnen können, diese kommen aber nur zur Geltung wenn sie explizit geöffnet werden
durch falsche Handhabung / falsche Codierung wie beispielsweise über Get-Parameter Dateinamen
weitergeben, die dann ausgeführt werden. Diese Dinge müssen selbstverständlich trotzdem noch beachtet
werden.
Die 4 für die Web-Anwendungsentwicklung relevanten Punkte sind:
- Cross Site Scripting (CSS). Benutzereingaben müssen gesäubert oder vor der Ausgabe maskiert (htmlspecialchars) werden. Diese könnten Tags enthalten und durch die Ausgabe ermöglichen, dass fremder Javascript-Code ausgeführt wird.
- SQL Injection. Zeichen in Benutzerdaten, die SQL Anfragen manipulieren können müssen mit Slashes escaped werden. Geschieht meist durch den Befehl mysql_real_escape_string.
- Cross Site Request Forgery (CSRF). Dass eingeloggten Benutzern keine Anfragen untergeschoben werden können, welche sensible Aktionen auf der Webseite ausführen, wie zB Löschungen, Geld senden usw. Beispielsweise wäre dies der Fall, wenn ein Angreifer einem in der Anwendung eingeloggten Benutzer einen Link per Email zuschickt welcher mit Get-Parametern eine Aktion in der Anwendung durchführt wie zb index.php?userid=123&deleteprofile=1. Wenn alle anderen sicherheitsrelevanten Punkte abgedeckt sind, also vorallem die Logik, wäre es ohne CSRF-Absicherung für den Angreifer trotzdem möglich auf der Seite sensible Aktionen durchzuführen. Er schickt dem Opfer den Link per Email und wenn es darauf klickt würde die Seite im Browser geöffnet und da es eingeloggt ist würde die Aktion ausgeführt in dem Fall das Profil gelöscht. Es ist daher notwendig, dass alle sensiblen Aktionen dagegen abgesichert werden. Es geschieht dadurch, dass die Anfragen mit Tokens versehen werden und, dass sie über Post ablaufen. Das Token würde bei der Generierung des Links auf der Webseite generiert und da der Angreifer den Link selbst generiert kennt er die Tokens nicht. Zudem sollten diese Aktionen mit einer Benutzerbestätigung versehen werden, wie "Wollen Sie ihr Profil wirklich löschen?" Dies verunmöglicht CSRF effektiv. Dieser Punkt ist am aufwändigsten zu intergrieren und wird bei den meisten Anwendungen vernachlässigt.
- Die Logik, dass Benutzer nicht durch Manipulation von Get/Post-Parametern auf Daten zugreifen können für die sie keine Berechtigung besitzen. Das bedeutet, dass bevor sensible Aktionen durchgeführt werden gegengecheckt werden muss ob die betreffenden Daten dem Benutzer gehören, der auf sie zugreifen will.
Formulare, die mit bncms generiert werden, sind standartmässig gegen die ersten 3. Punkte
abgesichtert. Die Logik muss aber bei der Entwicklung trotzdem immer
beachtet werden. Beispielsweise darf es den Benutzern nicht möglich sein durch
Manipulation von Parametern Daten anderer Benutzer anzusehen oder ändern. Zusätzlich muss
mysel_real_scape_string verwendet werden wenn eigener zusätzlicher Code (in Konfigurationsdaten ua)
geschrieben wird, der in die Datenbank schreibt. Wenn aber sonst nur die Formulare und
Standartfunktionalitäten von bncms verwendet werden benötigt es zusätzlich kein
weiteres Eingreifen, es sei denn, dass die Anwendung wirklich hohen sicherheitstechnischen
Anforderungen gerecht werden muss. Allerdings ist dann aller relevante Code vereinheitlicht,
einfach und an einer Stelle zentriert zu finden und es wird die Absicherung stark
vereinfachen.
Praktisch unhackbare Webanwendungen mit bncms erreichen
Unter der Voraussetzung, dass alle datenbankmanipulierenden Formulare und Auflistungen einer
Webanwendung bncms verwenden gibt es noch 2 Dinge, die beachtet werden müssen um Anwendungen zu
erhalten, die praktisch unmöglich zu hacken sind.
1. Die Logik, wie oben beschrieben, wenn eigener Code hinzugefügt wird in beispielsweise den
Benutzerfunktionen, Konfigurationsdateien usw
2. Das Escapen von Datenbankanfragen üblicherweise mit mysqli_real_escape_string() (oder der Abkürzung e()) ebenfalls in
eigenem Code
Wenn das beachtet wird wird die Anwendung einen sehr hohen Grad an Websicherheit erreichen.
So kann man Anwendungen
erstellen die praktisch unmöglich zu hacken sind (was die Anwendung
betrifft und Verwantwortung der Webproduzenten. Phishing usw betrifft den Anwender und dagegen kann man
eine Webanwendung generell nicht absichern, da alle relevanten Dinge des Angriffs ausserhalb der
Anwendung ablaufen). Wenn ein Angreifer es nicht schafft ein Formular zu hacken wird er kein anderes
hacken können, weil alle gleich sind. Es ist ja immer der selbe Code und der ist stark optimiert.
Get-Links gegen CSRF absichern
Oft sind Anwendungen so aufgebaut, dass Links verwendet werden, die sensible Aktionen ausführen aber aus Get-Parametern bestehen. Zum Beispiel der genannte Link index.php?userid=123&deleteprofile=1. Wenn es viele solche Links in einer Anwendung gibt wird es richtig aufwändig diese alle in Post Formulare umzuwandeln. bncms bietet dazu ein Konzept von Get-Tokens um gegen CSRF abzusichern. Die Tokens werden den Get-Links durch die Funktion h() mitgegeben (Beispiel href='".h("?userid=1&deleteprofile=1").'" und der PHP Code der die Aktion durchführt wird mit checkGetToken() validiert. Die Tokens laufen ab und werden bei jedem Seitenaufruf neu generiert. Dies bietet hohen Schutz gegen CSRF, besser ist es allerdings mit POST-Formularen und Benutzerbestätigung, dies ist weil es theoretisch möglich ist Tokens per Javascript abzugreifen (Voraussetzung gleichzeitige CSS-Sicherheitslücke). Man könnte aber alle derartigen Get-Aktionen kurzerhand standartmässig mit einer Benutzerbestätigung versehen und es würde so sehr effektiv gegen CSRF absichern. Dies ist momentan nicht integriert aber es wäre in kurzer Zeit umzusetzen durch Änderung der checkGetToken() Funktion.
Veröffentlicht als open source.
Entwickelt von Damian Hunziker,
First Good Company, hu100 at ok.de