Geschrieben von ssd_bonn am 06.10.2005, 13:28

Hallo zusammen!
In diesem Tutuorial möchte ich mich mit dem Schutz vor CrossSideScripting sowie der Auslagerung von Funktionen und Inhalten befassen und euch kurz zeigen, wie man eine einfache Trennung von Inhalt und Design mit Hilfe bbCode-formatierter Textdateien erstellen kann.

Was ist CrossSideScripting und wie schütze ich mich davor?
Wenn ihr bereits einmal ein eigenes Gästebuch o.ä. programmiert habt, wisst ihr sicherlich, dass bei einfach gestrickten Scripten schnell die Möglichkeit besteht, von außen das Layout der darstellenden Webseite zu verändern, indem man im Gästebuch einfach HTML-Code postet.
Das ist insbesondere dann ärgerlich, wenn mit das Gästebuch ansonsten tadellos funktioniert und/oder nun irgendwelche Befehle oder Scripts auf der Seite ausgeführt werden, die Schaden beim Besucher anrichten.
Ein ganz besonderes Ärgernis ist z.B. die mögliche Einbindung eines externen Stylesheets...
Diese Eingriffe von außen bezeichnet man als CrossSideScripting.

Wie kann man sich aber nun dagegen wehren?
Dazu gibt es verschiedene Lösungsansätze.
Zum einen besteht die Möglichkeit, einfach im Text (also im String) nach HTML-Tags zu suchen und diese über die PHP-Funktion strip_tags() entfernen zu lassen.
Da die Funktion auch über die Möglichkeit verfügt, Ausnahmen anzugeben, ist die Formatierung über bbCode kein Problem; daneben hat der User auch die Möglichkeit, die entsprechenden (erlaubten) Formatierungsbefehle direkt als HTML-Tag einzugeben.

Dies funktioniert nach folgendem Muster:


<?
$text = strip_tags($text,"<b><i>");
?>

durch diese Funktion werden nun im String „$Text“ alle HTML-Tags bis auf b und i entfernt, also alle bis auf die Formatierungen für Fett- und Kursivschrift.
Die Liste der Ausnahmen ist natürlich beliebig erweiterbar, so können beispielsweise img-Tags freigegeben werden, etc etc. Voraussetzung ist nur, dass die Ausnahmetags wie im obigen Beispiel zusammen in Anführungszeichen als zweites Argument der Funktion aufgerufen werden.

Neben dieser recht einfachen Methode gibt es aber auch noch weitere Varianten.
Eine Möglichkeit, die ich für den weiteren Verlauf des Tutorials benutzen möchte, ist die Aussortierung von HTML-Tags über die Funktion htmlspecialchars().
Mit dieser Funktion werden die in HTML verwendeten Steuerzeichen, also < > / \ & in Zeichenfolgen umgewandelt, die dann ausgegeben werden, beispielweise & lt; für die linke eckige Klammer.
Damit hat man nun nicht nur komfortabel alle HTML-Befehle untedrückt, man kann auch zurückverfolgen, wer welchen Code gepostet hat, und obendrein bietet diese Methode Spielraum für die Hervorhebung von einzelnen Code-Passagen, z.B. im Rahmen von Tutorials o.ä.
Daher will ich im folgenden Auf diese Methode zurückgreifen.
Als Ergänzung zur Funktion htmlspecialchars() bietet sich noch die Funktion htmlentities() an. Diese wandelt alle Sonderzeichen, also Umlaute oder akzentuierte Vokale in Standard-Ausgabezeichenfolgen um, also statt ö z.B. & ouml;.
Die beiden Funktionen werden mit der gleichen Syntax aufgerufen:

<?
$text = htmlspecialchars($text);
$text = htmlentities($text);
?>

So hat man direkt einen einfachen und effektiven Schutz gegen CrossSideScripting, ohne sich schöne Formatierungsbefehle zu verbauen.

Wie kann ich eine benutzerdefinierte Funktion erstellen und diese auslagern?
Die bbCode-Funktionen bieten sich zum Erstellen einer benutzerdefinierten Funktion geradezu an.
Hierbei hat man zum Einen die Möglichkeit, das Auslagern und Einbinden zu üben, zum Anderen kann man sich so bequem eine Funktionsbibliothek anlegen, und die darin enthaltenen Funktionen an jeder beliebigen Stelle und in jeder beliebigen Datei nutzen, ohne erst aufwändig die Funktion definieren zu müssen.

Eine eigene Funktion definiert man wie folgt:

<?
Function bbCode ($Argument) {
//Anweisungen
return $Argument;
}
?>

Auf diese Weise hat man bereits festgelegt, dass maximal ein Argument übergeben wird, und das (veränderte) Argument als Rückgabewert mit return weitergegeben wird.
Selbstverständlich lassen sich Funktionen auch abweichend von diesem Schema definieren, für unsere Zwecke bietet dies jedoch einige Vorteile.
Wir füttern nun die Stelle mit den Anweisungen entsprechend:

<?
Function bbCode ($Argument) {
$Argument = htmlspecialchars($Argument);
$Argument = htmlentities($Argument);
$Argument = str_replace(str_replace("[ b ]","<b>",$Argument);
$Argument = str_replace("[ /b ]","</b>",$Argument);
$Argument = eregi_replace ("([img])(.*)([/img])","<img src=' \2 '>",$Argument);
//ggf folgen hier weitere Anweisungen
return $Argument;
}
?>

Wir haben nun eine eigene Funktion geschaffen, die Steuerzeichen und Sonderzeichen umwandelt, nach Fettschriftformatierungen sucht und Bilder einfügt.
Der Aufruf dieser Funktion gestaltet sich nun wie folgt:

<?
//oben muss die Funktion definiert werden
//...

$text = bbCode($text1);
?>

Nun möchte man ja rationeller Weise nicht in jedem Dokument/Script, in dem man diese Funktion anwenden möchte, per Copy n Paste die Funktionsdeifinition unterbringen müssen.
Dazu bedient man sich eines einfachen Tricks:

Die Funktionsdefinition schreibt man in eine andere Datei, z.B. in eine Datei namens funktionsbibliothek.php.
Diese bindet man nun über den include oder den require-Befehl in das Dokument ein, in dem man die Funktion aufrufen möchte. Diese Befehle schreiben den Quelltext der anderen Datei an die entsprechende Stelle:


<?
include("bibliothek.php");
//...
$text = bbCode($text);
echo $text;
?>

Ist die Definition einmal eingebunden, kann die Funktion beliebig oft aufgerufen werden. So spart man Platz im Code, allerdings muss die Bibliothek stets fehlerfrei gehalten werden, um das Verschleppen der Fehler in andere Dateien zu verhindern.

Auslagerung von Inhalten? Wieso das denn?
Heutzutage ist das Web dynamisch geworden, das bedeutet sprunghafte Veränderungen in zeitlich sehr kurzen Abständen.
Damit man bei einer Neugestaltung der Webseite nicht auch alle Texte und Inhalte neu erstellen muss, trennt man rationellerweise den Inhalt vom Design.
Neben der Verwendung von CSS, was nur eingeschränkt für eine wirkliche Trennung sorgt, gibt es noch dutzende weiterer Möglichkeiten. Eine davon, die ich auch auf meiner eigenen Webseite ( http://www.rettungsgeil.de.tf ) anwende, möchte ich hier näher erläutern.

Auslagerung von Texten und anderen Inhalten mithilfe bbCode-formatierter Textdateien
Ich bediene mich hierzu einiger kleiner Kniffe.
So benutze ich beispielsweise zum Einlesen der Datei nicht die Funktion include(), sondern die Funktion file(), die den Inhalt der Datei zeilenweise in ein array einliest.
Dieses array wird nun mit einer foreach-Schleife mit der bbCode-Funktion aufgerufen und ausgegeben.
Zwar erhöht sich dadurch die Ladezeit der einzelnen Sites, auf der anderen Seite sind aber für die Administration der Webseite keinerlei HTML-Kenntnisse notwendig, was sich insbesondere bei Redaktionen bezahlt macht.


<?
$Dateiname = "tuts";

$Datei = file("Pfad/$Dateiname.inc");

if(is_array($Datei)) {
foreach ($Datei as $Zeile) {
$Zeile = bbCode($Zeile);
echo $Zeile, "<br>";
}
} else {
echo 'Es ist ein Fehler aufgetreten. Unter dem Namen $Datei ist kein Array abgelegt. Bitte kontaktieren Sie den Administrator.';
}
?>

Dies mag auf den ersten Blick etwas verwirrend aussehen, ist aber eigentlich sehr leicht durchschaubar.
Erst wird ein Dateiname bestimmt (dies geschieht bei mir bereits durch den Aufruf der Seite: index2.php?page=tuts)
Diese Datei wird dann in ein Array eingelesen.
Die if-Struktur prüft nun, ob es sich wirklich um ein Array handelt, wenn ncht, wird die Funktion mit einer Fehlermeldung abgebrochen.
Wenn es ein Array ist, wird in jeder Zeile der enthaltene bbCode umgewandelt und die Zeile wird ausgegeben.
Die Sicherheitsüberprüfung ist notwendig, weil die Datei leer sein könnte oder der Dateiname falsch ist.
Es gibt aber auch andere Möglichkeiten um diese Überprüfung zu realisieren, sogar ohne den User dies bemerken zu lassen.
Noch ein Hinweis: Die einfachen Anführungszeichen beim letzten Aufruf der Funktion echo() sorgen dafür, dass das Dollarzeichen nicht als Einleitung des Variablennamens interpretiert wird; es erscheint also bei der Ausgabe nicht der Inhalt der Variable/des Arrays $Datei.

Bitte beachtet auch mein erstes Tut zur Stringmanipulation, in dem die Grundlagen der hier verwendeten Funktionen angesprochen werden.
http://www.lima-city.de/tutorials.php?m=show&id=1583

Wer sich im Bereich bbCode etwas weiterbilden möchte, dem empfehle ich wärmstens die Zeitschrift
"PC Pr@xis Sonderheft: INTERNET intern: Neue Highlights für ihre Website mit PHP & Co."
Aus genanntem Heft habe ich zu diesem Tutorial auch einige Beispiele entlehnt.

Wie immer gilt:
Solltet ihr Fragen und/oder Verbesserungsvorschläge haben, nutzt mein Profil-Gästebuch oder schreibt mir eine PN.

Vielen Dank
Gruß
ssd_bonn

Bewertung Anzahl
6
60,0 %
3 Bewertungen
4
20,0 %
1 Bewertungen
3
20,0 %
1 Bewertungen