Hallo,
ich würde gerne wissen, ob und wenn ja wie man in PHP möglichst "sauber"
programmieren kann. Ich nenne hierfür ein einfaches Beispiel, bei dem
ich keine wirklich zufriedenstellende Lösung gefunden habe:
Ich möchte in einer PHP-Datei das HTML-Header Gedöns reinschreiben,
diese Datei soll von allen einzelnen PHP-Seiten eingebunden werden.
Außerdem gibt es eine CSS-Datei, die bereits innerhalb der header-Datei
eingebunden werden soll / muss.
Wenn ich nun einen Unterordner habe, und die header.php mittels
1
include '../header.php'
einbinde, dann funktioniert das nicht, weil nach dem einbinden die CSS
Datei mit z.B.
1
href ="main.css"
nicht mehr gefunden wird, da diese sich ja ebenfalls in einem höher
liegenden Ordner befindet. Wird die header-Datei im Unterordner
eingebunden, so ist der angegebene Pfad jetzt falsch.
Nun habe ich es so gelöst, dass ich für jeden Unterordner wiederum eine
Header-Datei habe. In dieser wird definiert wo sich der Hauptpfad
befindet, anschließend wird die übergeordnete Header Datei eingebunden.
In dieser Header Datei wird dann der Hauptpfad benötigt um die CSS Datei
richtig zu finden. Ein bisschen Quellcode sagt mehr als 1000 Worte:
Hauptheader:
Somit funktioniert alles, ich finde es dennoch sehr unsauber, dass
Variablen in einer Datei "global" definiert werden und von anderen
Dateien einfach genutzt werden. Anders ausgedrückt: In der
Hauptheaderdatei wird auf die Variable "$mainpath" zugegriffen, die
dieser Datei alleine vollkommen unbekannt ist. Erst dadurch, dass diese
Datei von einer anderen Datei eingebunden wird, bekommt diese Variable
erst ihre Definition.
Gibt es da andere Wege um sowas ordentlich zu machen?
PHP-Noob schrieb:> [...]> Hauptheader:<!DOCTYPE html>> <html lang="de">> <head>> <title><?php echo $title; ?></title>> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>> <link rel="stylesheet" type="text/css" href ="<?php echo $mainpath;> ?>main.css">> </head>>> [...]> Gibt es da andere Wege um sowas ordentlich zu machen?
CSS wird nicht von PHP eingebettet, sondern von HTML. Das in dem href
="" hat daher erst einmal nichts mit dem Pfad der PHP-Datei im
Dateisystem zu tun -- sondern mit dem URL, unter dem der Webbrowser die
Datei main.css anrufen kann. Dieser URL hat aber vor allem mit der
Konfiguration Deines Webservers und weniger mit dem Ablageort im
Dateisystem zu tun.
Außerdem bist Du leider dabei, Dir einen schlechten Stil anzugewöhnen.
Auch wenn es war einmal die Grundidee von PHP gewesen ist, PHP-Code ins
HTML einzubetten, war und ist das einer der größten Kritikpunkte an PHP
und einer der wichtigsten Gründe dafür, warum Richtige Entwickler(tm)
der Sprache und ihren Benutzern mit einer gewisse Skepsis begegnen...
Profis schreiben lieber HTML-Templates, die dann mit einer
Templateengine wie Smarty verarbeitet werden, so daß HTML und PHP-Code
in unterschiedlichen Ordnern liegen und damit sauber voneinander
getrennt sind.
Auch CSS-Dateien haben nichts in Verzeichnissen zu suchen, in denen auch
Dein PHP-Code untergebracht ist. CSS-Dateien gehören, eventuell
vielleicht noch zusammen mit JavaScript-Dateien, in ein separates
Verzeichnis, das oft "static/" genannt wird. Der Webserver ist dann
dafür verantwortlich, daß der URL "http://www.example.com/static/"
korrekt auf das Verzeichnis "/var/www/example.com/static/" gemappt wird,
so daß Dein HTML-Code für das Stylesheet nur den absoluten URL-Pfad
"/static/main.css" einbinden muß.
HTH, YMMV.
ICh sehe, und betreibe das genauso,
such dir deine Lieblings-Template-Engine und benutze diese, da wirst du
auf dauer wesentlich glücklicher mit!
Guck dich einfach mal Hier um:
https://github.com/ziadoz/awesome-php
In dem speziellen Fall ist der Absatz Templating interesant:
https://github.com/ziadoz/awesome-php#templating
Ausser das dir das hilft den Überblick zu bewahren führt das auch dazu
das du alles was du brauchst Sammelst und das dann anzeigt statt dein
Markup zu schreiben und immer wieder Dinge einzusammeln und
Entscheidungen zu treffen.
Grüße, Dirk
Dirk D. schrieb:> ICh sehe, und betreibe das genauso,> such dir deine Lieblings-Template-Engine und benutze diese
PHP IST eine Template Engine, eine sehr mächtige sogar. Es ist
technologischer Unfug höchsten Grades da noch eine zweite obendrüber zu
stülpen.
Bernd K. schrieb:> Dirk D. schrieb:>> ICh sehe, und betreibe das genauso,>> such dir deine Lieblings-Template-Engine und benutze diese>> PHP IST eine Template Engine, eine sehr mächtige sogar. Es ist> technologischer Unfug höchsten Grades da noch eine zweite obendrüber zu> stülpen.
Vor allem ist es jedenfalls technologischer Unfug, die Programmlogik in
den Darstellungslayer einzubetten.
Andererseits hast Du nicht völlig unrecht: man kann PHP innerhalb von
PHP als Templateengine benutzen, aber das ist eher etwas für
Fortgeschrittene. Für Einsteiger ist sowas sehr verwirrend und führt sie
in Versuchung, doch wieder mit dem Unfug anzufangen.
Deswegen ist Smarty an dieser Stelle der bessere Einstieg, weil es zu
einer Trennung von Logik und Darstellung führt und recht leicht zu
lernen ist. So gewöhnt sich der künftige Entwickler gleich ein
ordentliches Softwaredesign an, was beim Einstieg zweifellos wichtiger
ist, als die Einsparung einiger Sekundenbruchteile Laufzeit auf einem
massiv beharkten Server.
Guten morgen, vielen Dank für eure Antworten!
Ich habe mir mal smarty konfiguriert und mich ein bisschen eingelesen
und denke nicht, dass es das richtige für mich ist. Ich werde vermutlich
niemals beruflich PHP programmieren und auf meiner Seite werde ich wohl
für immer der Programmierer und Designer bleiben, ich bin also auf eine
so starke Trennung nicht angewiesen.
Sheeva P. schrieb:> Auch CSS-Dateien haben nichts in Verzeichnissen zu suchen, in denen auch> Dein PHP-Code untergebracht ist. CSS-Dateien gehören, eventuell> vielleicht noch zusammen mit JavaScript-Dateien, in ein separates> Verzeichnis, das oft "static/" genannt wird. Der Webserver ist dann> dafür verantwortlich, daß der URL "http://www.example.com/static/"> korrekt auf das Verzeichnis "/var/www/example.com/static/" gemappt wird,> so daß Dein HTML-Code für das Stylesheet nur den absoluten URL-Pfad> "/static/main.css" einbinden muß.
Ich weiß nicht, ob ich dich richtig verstanden habe... muss ich den
Server umkonfigurieren, damit er mit dem absoluten URL-Pfad klarkommt?
Ich habe einen Standard-billigen 0815 Server bei 1&1 und bei einem
absoluten Pfad findet er die CSS Datei nicht, wenn die PHP- bzw. HTML
Datei in einem Unterordner liegt.
Wie hätte man mein Beispiel denn vor der smarty Zeit gelöst? Gibt es da
noch andere Tricks?
PHP-Noob schrieb:> Wie hätte man mein Beispiel denn vor der smarty Zeit gelöst?
Ein Ordner "static" am Webserver (oder auch mehrere, "styles",
"images","scripts").
Im HTML mit src="/static/abc.png" arbeiten.
Hat alles mit PHP nix zu tun, ist reines HTML.
Vorteile:
- Kannst direkt für die statischen Verzeichnisse mit .htaccess
mod_expires konfigurieren, für viel schnelleren Seitenaufbau
- Kannst in den statischen Ordnern das Ausführen von PHP verbieten
lassen. (Mehr Sicherheit, falls durch irgendeinen Fehler woanders ein
User-Upload in diese Ordner erlaubt ist.
- Funktioniert unabhängig von der Lage deiner PHP-Dateien, und auch wenn
du per mod_rewite "schönere" URLs erzeugen willst.
(z.B. http://meine.seite/artikel/2016/thema_abc statt
http://meine.seite/artikel.php?Jahr=2015&thema=abc)
Bernd K. schrieb:> PHP IST eine Template Engine, eine sehr mächtige sogar. Es ist> technologischer Unfug höchsten Grades da noch eine zweite obendrüber zu> stülpen.
Dann machen sehr viele Leute wohl sehr viel falsch.
Wann immer ich denke das Viele Leute grundsätzlich was falsch machen,
aber ich nicht, versuche ich mal mein Weltbild zurecht zu rücken,
probier das doch auch mal :)
Dirk D. schrieb:> Dann machen sehr viele Leute wohl sehr viel falsch.
Bernd K. hat schon recht, ich sehe das genauso. Und nur weil es viele
falsch machen ist es noch lange nicht richtig oder gut.
Natürlich gehören Views (=Templates) getrennt von der restlichen Logik.
Aber eben in PHP geschrieben und nicht in irgendeiner Template-Sprache
wie Smarty oder Blade die am Ende wieder in PHP übersetzt wird.
PHP-Noob schrieb:> Ich habe mir mal smarty konfiguriert und mich ein bisschen eingelesen> und denke nicht, dass es das richtige für mich ist. Ich werde vermutlich> niemals beruflich PHP programmieren und auf meiner Seite werde ich wohl> für immer der Programmierer und Designer bleiben, ich bin also auf eine> so starke Trennung nicht angewiesen.
Da habe ich mich vielleicht mißverständlich ausgedrückt: wenn ich von
Design rede, meine ich nicht das grafische Design und Layout Deiner
Website, sondern das Softwaredesign bzw. die Architektur. Das hat wenig
damit zu tun, ob Du PHP beruflich oder privat benutzen willst, sondern
vielmehr damit, wie Deine Software aufgebaut ist; zum Beispiel gehören
HTML-Templatedateien, Dateien mit PHP-Code und statische Dateien in
unterschiedliche Verzeichnisse, und Programmlogik (PHP-Code) sollte
nicht in HTML-Code eingebettet werden.
> Sheeva P. schrieb:>> Auch CSS-Dateien haben nichts in Verzeichnissen zu suchen, in denen auch>> Dein PHP-Code untergebracht ist. CSS-Dateien gehören, eventuell>> vielleicht noch zusammen mit JavaScript-Dateien, in ein separates>> Verzeichnis, das oft "static/" genannt wird. Der Webserver ist dann>> dafür verantwortlich, daß der URL "http://www.example.com/static/">> korrekt auf das Verzeichnis "/var/www/example.com/static/" gemappt wird,>> so daß Dein HTML-Code für das Stylesheet nur den absoluten URL-Pfad>> "/static/main.css" einbinden muß.>> Ich weiß nicht, ob ich dich richtig verstanden habe... muss ich den> Server umkonfigurieren, damit er mit dem absoluten URL-Pfad klarkommt?> Ich habe einen Standard-billigen 0815 Server bei 1&1 und bei einem> absoluten Pfad findet er die CSS Datei nicht, wenn die PHP- bzw. HTML> Datei in einem Unterordner liegt.
Der Webserver hat die Aufgabe, URLs auf Dateisystempfade zu mappen, also
für eine angeforderte URL die richtige Datei zu finden. In der
klassischen Apache-Konfiguration gibt es dazu unter anderem die
Direktive "Alias". Zum Beispiel könnte in einer Apache-Konfiguration die
folgende Zeile zu finden sein:
1
Alias /static /var/www/example.com/static
Dies weist den Apache-Webserver an, bei einem Request nach URLs, die mit
"/static" beginnen, ins Verzeichnis "/var/www/example.com/static" zu
suchen. Wenn Deine Website also
einbindet, wird der Webbrowser den Webserver nach der Datei
"/static/main.css" fragen, und der Webserver liefert dann die Datei
"/var/www/example.com/static/main.css" an den Webbrowser zurück (oder,
wenn er diese Datei in angegebenen Pfad nicht findet, einen HTTP-Fehler
404).
Wie der Gast Planlos ebenso dankenswerter- wie richtigerweise anmerkt,
hat das aber nichts mit PHP zu tun, sondern ist eine Sache der
Konfiguration des Webservers, und bei statischen HTML-Seiten genauso
gilt.
Wie man das auf einem "Standard-billgen 0815 Server bei 1&1"
konfiguriert, kann Dir vielleicht jemand anders hier sagen; ich bin in
verschiedenerlei Dingen eher traditionell orientiert und konfiguriere
meinen Apachen daher noch ganz klassisch von Hand. ;-)
S R schrieb:> Natürlich gehören Views (=Templates) getrennt von der restlichen Logik.> Aber eben in PHP geschrieben und nicht in irgendeiner Template-Sprache> wie Smarty oder Blade die am Ende wieder in PHP übersetzt wird.
Was spricht den dagegen?
Dirk D. schrieb:> Was spricht den dagegen?
- Man muss völlig sinnbefreit "noch eine Sprache" lernen, und zwar alle
die eventuell mitwirken (z.Bsp. auch der Frontend-Entwickler).
- Man muss eine IDE finden die das Syntax-Highlighting unterstützt damit
es Spaß macht
- Performance MUSS schlechter sein
...
Was ist denn der Unterschied ob ich nun {$var} oder <?= $var; ?>
schreibe? Oder in Blade halt {{ $var }}
S R schrieb:> Dirk D. schrieb:>> Was spricht den dagegen?>> - Man muss völlig sinnbefreit "noch eine Sprache" lernen, und zwar alle> die eventuell mitwirken (z.Bsp. auch der Frontend-Entwickler).
Je nach Projektkontext hat man dann aber nur EINE Templatesprache,
sowohl für dinge die auf dem Server gerendert werden als auch für dinge
die nachträglich im Browser gerendert werden.
> - Man muss eine IDE finden die das Syntax-Highlighting unterstützt damit> es Spaß macht
Das ist dann wohl ein Nachteil JEDER sprache :(
> - Performance MUSS schlechter sein ...
Nein.
wenn du das richtig machst wird in Produktion keine Template
interpretiert, dann hast nur die zu php kompilierten templates auf dem
Server.
> Was ist denn der Unterschied ob ich nun {$var} oder <?= $var; ?>> schreibe? Oder in Blade halt {{ $var }}
Das wirst du lernen wenn in $var z.b. "<script>alert('this could be a
xss-attack');</script>" steht :)
> - Man muss völlig sinnbefreit "noch eine Sprache" lernen, und zwar alle> die eventuell mitwirken (z.Bsp. auch der Frontend-Entwickler).
Gerade Frontend-Entwickler sollten diese "Sprachen" bereits können.
> - Man muss eine IDE finden die das Syntax-Highlighting unterstützt damit> es Spaß macht
Was, zumindest für Smarty, heutzutage so gut wie jede IDE tut.
> - Performance MUSS schlechter sein
Nicht wirklich, das Template wird in PHP-Code umgewandelt und
gespeichert. Beim Aufruf der Seite wird dann direkt der PHP-Code
ausgeführt.
> Was ist denn der Unterschied ob ich nun {$var} oder <?= $var; ?>> schreibe? Oder in Blade halt {{ $var }}
Zumindest bis PHP 5.4 war das schlechter Stil, "<?=" konnte nur
verwendet werden wenn auch die Short-Open-Tags aktiviert waren.
Bei deinem einfachen Beispiel erspart man sich natürlich noch nicht sehr
viel Tipparbeit, bei folgenden Beispielen sieht das aber schon anders
aus:
1
<?=strtoupper($var);?>
2
3
{$var|upper}
1
<?=empty($var)?'keine Angabe':$var;?>
2
3
{$var|default:'keineAngabe'}
1
<?phpif(empty($var)):
2
echo'keine Einträge vorhanden';
3
else:
4
foreach($varas$item):
5
echo$item;
6
endforeach;
7
endif;?>
8
9
{foreach from=$var item=$item}
10
{$item}
11
{foreachelse}
12
keine Einträge vorhanden
13
{/foreach}
Des weiteren werden bei Smarty Variablen escaped, die von dir genannten
Beispiele haben also sogar einen sehr großen Unterschied.
Richtig wäre <?= htmlspecialchars($var, ENT_QUOTES); ?> vs {var}.
Wie wär es wenn du den Pfad zum Stylesheet einfach relativ zum
Document-Root angibst? Dazu musst du am Anfang des Dateipfades einfach
nur einen / einfügen, also wie folgt:
Dadurch wird dann unabhängig davon ob du gerade [URI]/, [URI]/foo,
[URI]/foo/bar aufrufst immer [URI]/assets/css/main.css geladen.
Alternativ könntest den Stylesheet auch wirklich komplett absolut
angeben, also inklusive http://[URI]
Leute, ich dachte nicht dass man hier noch erklären muss, dass Variablen
escaped gehören...
Das erledigen gängige Template Helper wie e($str);
<?= ist nach PSR Standard gängig, vor-PHP 5.4 ist bitte keine Referenz
mehr.
Ich benutze <?php dennoch nicht, weil es mir egal ist ob ich <?php echo
oder <?= tippe.
1
<?phpif(empty($var)):
2
echo'keine Einträge vorhanden';
3
else:
4
foreach($varas$item):
5
echo$item;
6
endforeach;
7
endif;?>
Würde ich so machen:
1
<?phpif(empty($var)):?>
2
Keine Einträge vorhanden.
3
<?phpelse:?>
4
<?phpforeach($varas$item):?>
5
<?phpechoe($item);?>
6
<?phpendforeach;?>
7
<?phpendif;?>
Die Mehrarbeit beim Tippen übernimmt die IDE.
> - Performance MUSS schlechter sein
Nicht wirklich, das Template wird in PHP-Code umgewandelt und
gespeichert. Beim Aufruf der Seite wird dann direkt der PHP-Code
ausgeführt.
Genau, aber beim ersten Aufruf muss auch das erstmal umgewandelt werden.
Noch kurz zu meinem Beispiel oben; klar überwiegen da im Moment die
<?php Tags; aber da im Realfall auch noch ein Haufen HTML dazwischen
hängen wird, ist es so IMHO deutlich übersichtlicher.
Es gibt in html auchnoch den "base" tag, welcher ändern kann wozu
relative URLs relativ sind. Von der verwendung des "base" tags rate ich
jedoch ab.
Ich habe mal eine Templateingengine zusammengehackt, die ich
gelegentlich bei Schulaufgaben verwende. Ich mache das gewönlich so,
dass ich bei jeder unterseite nur das Templateingscript einbinde. Dann
lade ich das Haupttemplate und defineire alle Ordner, wo der Inhalt zu
finden ist (Current Working Directory und ein anderes Verzeichnis, und
ein Array). Dann Suche ich die zu ersetzenden teile mit preg_match (ich
markiere die mit #var#, %var%, und !!!var!!!), suche den passenden
content und ersetze den Platzhalter mit str_replace, und je nach
Markierung escape ich alles mit htmlentities, oder evaluire php code,
oder mache die Ersetzung vor jeglicher PHP code evaluation. Die
Ersetzung ist dabei Rekursiv.
Dabei habe ich das Problem mit den Pfaden folgendermassen gelöst:
(funktioniert nur wenn der Pfad keine Symlinks enthält)
Und füge vor allen Pfaden htmlentities($urlroot) ein (ausser in den css
files, dort sind die pfade relativ zum css file).
Eine bessere alternative zum Code oben wäre wohl:
Daniel A. schrieb:> Eine bessere alternative zum Code oben wäre wohl:$urlroot => str_repeat('../',substr_count($_SERVER['REQUEST_URI'],'/'));
Warum willst du das unbedingt relativ angeben? Damit sich der Webbrowser
mit dem cachen schwerer tut?
Und beachte: REQUEST_URI kann je nach Server-Config (Reverse-Proxy usw.)
auch gerne ein 'http://hostname/...'; enhalten. Dann zählst du zwei '/'
zuviel. Und ein Query-String mit weiteren '/' kann auch noch dabei sein.
und sobald mod_rewrite für (Buzzword) SEO-Friendly URLs im Einsatz ist,
versagt die Methode völlig, dann können es auch zuwenige sein.
Hallo,
nochmals vielen Dank für eure Hilfe!
Sheeva P. schrieb:> Da habe ich mich vielleicht mißverständlich ausgedrückt: wenn ich von> Design rede, meine ich nicht das grafische Design und Layout Deiner> Website, sondern das Softwaredesign bzw. die Architektur.
Ich bezog mich beim "Programmierer" und "Designer" auf die Einleitung
der Spezifikation von smarty. Dort wird DER Vorteil von Smarty dadurch
beschrieben, dass der Programmierer und der Designer unabhängig
voneinander und gleichzeitig an einem Projekt arbeiten können. Diese
Anforderung habe ich aber ja nicht für meine Seite.
Ein gutes Design in der Software ist für mich sehr wichtig, deshalb
frage ich ja auch hier nochmal nach. Und ich denke, dass ich smarty
dafür nicht brauche, da ich der einzige Programmierer bin.
Wie hier einige Leute richtig geschrieben haben: Die Lösung im Falle der
CSS-Datei ist ein einfacher Schrägstrich vor dem Pfad. Damit wird die
CSS Datei immer gefunden, egal von wo aus sie gebraucht wird.
Wie im Beispiel ganz oben brauche ich für den HTML-Header noch den Titel
der jeweiligen Seite. Dies habe ich jetzt durch eine Funktion
GetHeader($title) im der PHP-Header Datei gelöst und denke, dass dies
"die Richtige" Lösung sein sollte.
PHP-Noob schrieb:> Und ich denke, dass ich smarty> dafür nicht brauche, da ich der einzige Programmierer bin.
Falsche Herangehensweise. Damit gewöhnst Du Dir nur was Dummes an. Wenn
mal ein zweiter/dritter dazukommt, willst Du dann umstellen? Ich sage ja
auch nicht "Ich nehm grün/gelb für die Phase, bin ja der einzige
Elektriker im Haus".
Ich nutze auch für private Projekte die strikte Trennung mittels Smarty.
Hatte das vorher auch anders, aber der enstehende Verhau ist einfach nur
hässlich. Außerdem kann so auch jemand an den Templates arbeiten ohne
Dir die Programmierung oder mehr zu zerschiessen.
Bei deiner GetHeader() Lösung allerdings...
Kopierst du mal HTML Source mit einem ' rein haste nen Fehler und mußt
suchen und escapen. Selbiges wenn Du " statt ' nutzt. Außerdem wird dann
PHP noch alles mit einem $ als Variable betrachten.
Am Ende packt man auch noch CSS und JS mit rein, weil extra Dateien sind
ja so uncool. Bei solchen Projekten gibt es bei mir nur eine Lösung:
rm -rf
Smarter schrieb:> Ich sage ja> auch nicht "Ich nehm grün/gelb für die Phase, bin ja der einzige> Elektriker im Haus".
Naja, dieser Vergleich ist aus mehreren Gründen unpassend:
In deinem Fall
- besteht Lebensgefahr
- ist (spätestens beim Unfall) illegal
- ist die Wahrscheinlichkeit, dass eine andere Person da irgendwann
rangehen wird nahezu 100% (z.B. nach einem Verkauf, einer Vermietung
oder meinem Tod). Die Wahrscheinlichkeit, dass jemand an meinen
Webseitenqullcode rangeht ist nahezu 0%.
Aber...
ich habe jetzt ein bisschen weiterprogrammiert, und merke, dass die
Programmierung "unsauber wirkt" und ich werde wohl doch auf Smarty
umstellen. (Noch ist es ja nicht zu spät)
Eine Frage hätt ich trotzdem nochmal vorab:
Ist die Prgrammierung mit Smarty was die Angreifbarkeit von Außen angeht
sicherer oder vielleicht sogar unsicherer?
Als Beispiel nenne ich ein HTML-Formular, in dem einfach jemand ganz
frech irgendeinen JavaScript Code reinschreibt? Oder ist das ein
vollkommen unabhängiges Thema?
PHP-Noob schrieb:> Als Beispiel nenne ich ein HTML-Formular, in dem einfach jemand ganz> frech irgendeinen JavaScript Code reinschreibt? Oder ist das ein> vollkommen unabhängiges Thema?
Das ist wieder was anderes, Solche Felder prüfst du mit PHP auf
Plausibilität, du würdest so ein Feld ja auch nicht direkt an eine DB
übergeben weil da ja auch "blabla;drop table...." drinstehen könnte.
Warum willst Du eigentlich im Jahre 2016 noch ein neues Projekt mit PHP
anfangen oder gar Lebenszeit mit der Einarbeitung in diese sterbende
Museumstechnologie verbrauchen?
Wenn ich heute ein neues Web-Projekt anfangen wollte würde ich Go
verwenden.
Bernd K. schrieb:> PHP> anfangen oder gar Lebenszeit mit der Einarbeitung in diese sterbende> Museumstechnologie verbrauchen?
lol, ymmd :'D
totgesagte leben länger, sieht man sehr gut an c.
lol schrieb:> totgesagte leben länger, sieht man sehr gut an c.
Naja, der Vergleich hinkt. Für C(++) hat sich noch kein Nachfolger
etabliert der es in allen denkbaren Einsatzgebieten ersetzt und in
jeder Hinsicht übertrifft. Das wird der Grund sein für sein
hartnäckiges Nichtverschwinden
Aber bei PHP verhält es sich genau umgekehrt: Kannst Du zum Beispiel
irgendeine aktuelle Alternative zu PHP nennen die in irgendeiner
Kategorie noch schlechter abschneidet als PHP? Serverside-Brainfuck
vielleicht, aber sonst noch welche? Da muss man schon angestrengt
nachdenken.
PHP-Noob schrieb:> ich habe jetzt ein bisschen weiterprogrammiert, und merke, dass die> Programmierung "unsauber wirkt" und ich werde wohl doch auf Smarty> umstellen. (Noch ist es ja nicht zu spät)
;-)
> Ist die Prgrammierung mit Smarty was die Angreifbarkeit von Außen angeht> sicherer oder vielleicht sogar unsicherer?
Smarty ist nur eine Templateengine und setzt die Daten, die Du ihm
gibst, in Deine Templates ein. Wenn Deine Daten ordentlich validiert
worden sind, hat Smarty überhaupt keine Auswirkungen auf das
Sicherheitsniveau.
Nur wenn Du Deine Daten nicht ordentlich validierst, bietet Smarty eine
kleine Verbesserung der Sicherheit: normalerweise maskiert Smarty die
Ausgabedaten, ersetzt also zum Beispiel "<" und ">" durch die passenden
HTML-Entities "<" und ">". Wo es gewünscht ist, kannst Du das mit
einem Smarty-Filter (|safe) ausschalten, dann ist Deine Applikation an
dieser einen Stelle genauso unsicher wie ohne Smarty. Trotzdem ist die
einzige Möglichkeit, die Sicherheit Deiner Applikation zu gewährleisten,
die korrekte und vollständige Validierung aller Eingabedaten, die aus
nicht-vertrauenswürdigen Quellen kommen.
> Als Beispiel nenne ich ein HTML-Formular, in dem einfach jemand ganz> frech irgendeinen JavaScript Code reinschreibt? Oder ist das ein> vollkommen unabhängiges Thema?
Der kluge PHP-Entwickler benutzt für so etwas HTML_QuickForm2. Damit
kann man nicht nur Formulare erstellen, sondern auch Funktionen zur
Validierung der Eingaben definieren und ausführen -- die Sicherheit
Deiner Applikation steht und fällt mit der Qualität Deiner Validierung.
Ein Beispiel findest Du hier: [1].
HTML_QuickForm2 bietet Dir außerdem die Möglichkeit, Deine Eingabedaten
bereits clientseitig vor dem Absenden mit JavaScript zu überprüfen. Das
hat den Vorteil, daß invalide Daten normalerweise gar nicht erst auf dem
Server ankommen, was Deinen Server schont, und die Benutzer eine
deutlich schnellere Rückmeldung bekommen, was Deine Benutzer schont.
Wichtig ist allerdings, daß eine clientseitige Validierung die
serverseitige höchstens unterstützen, aber niemals ersetzen kann, da die
clientseitige Validierung bei böswilligen Benutzern und solchen, die
JavaScript deaktiviert haben, natürlich nicht funktioniert.
Insofern: immer serverseitig validieren -- und zwar wirklich ALLES, auch
einen simplen Radiobutton, eine Checkbox oder eine Selectbox. Den Schutz
gegen CSRF nicht vergessen!
[1]
https://pear.php.net/manual/en/package.html.html-quickform2.tutorial.php
Sheeva P. schrieb:> Smarty ist nur eine Templateengine und setzt die Daten, die Du ihm> gibst, in Deine Templates ein. Wenn Deine Daten ordentlich validiert> worden sind, hat Smarty überhaupt keine Auswirkungen auf das> Sicherheitsniveau.
Das ist nur die halbe Wahrheit, valide Daten müssen ggf. noch Escaped
werden, und zwar passend zur Ausgabemethode.
Du musst z.B. ein Freitextfeld anders Escapen, je nach dem ob es als
Text im HTML, in einem Attribut, oder als teil eines Links verwendest.
da du ja vorher nicht weißt wo du die Daten im Template benötigst, und
diese evtl sogar mehrfach nutzt muss das Escapen im Template selbst
passieren.
Beispiel:
deine Daten:
Er sagte: "Meine Mama ist die Beste!"
das Kannst du innerhalb eines Textbereiches in HTML einfach so
durchgehen lassen.
Wenn das aber ein Attribut eines Elements werden soll, z.b. Der Text
eines Buttons musst du die Anführungszeichen durch " ersetzen.
Soll der Text als Get-Parameter an einen Link angehängt werden sind
wieder andere dinge zu tun...
An sonnsten kann ich mich dir da nur anschließen.
Bernd K. schrieb:> lol schrieb:>> totgesagte leben länger, sieht man sehr gut an c.>> Naja, der Vergleich hinkt. Für C(++) hat sich noch kein Nachfolger> etabliert der es in allen denkbaren Einsatzgebieten ersetzt und in> jeder Hinsicht übertrifft. Das wird der Grund sein für sein> hartnäckiges Nichtverschwinden>> Aber bei PHP verhält es sich genau umgekehrt: Kannst Du zum Beispiel> irgendeine aktuelle Alternative zu PHP nennen die in *irgendeiner*> Kategorie noch schlechter abschneidet als PHP? Serverside-Brainfuck> vielleicht, aber sonst noch welche? Da muss man schon angestrengt> nachdenken.
Naja, "aktuell"... Server-Side Includes existieren. ;-)
Dirk D. schrieb:> Sheeva P. schrieb:>>> Smarty ist nur eine Templateengine und setzt die Daten, die Du ihm>> gibst, in Deine Templates ein. Wenn Deine Daten ordentlich validiert>> worden sind, hat Smarty überhaupt keine Auswirkungen auf das>> Sicherheitsniveau.>> Das ist nur die halbe Wahrheit, valide Daten müssen ggf. noch Escaped> werden, und zwar passend zur Ausgabemethode.
Nein, das war die ganze Wahrheit. Die Daten werden auf der Eingabeseite
validiert, Smarty macht hingegen nur die Ausgabe. Die Darstellung, um
die sich Smarty kümmert, ist allerdings nicht sicherheitsrelevant, da
die Daten ja bereits auf der Eingangsseite validiert worden sind.
Sheeva P. schrieb:> Dirk D. schrieb:>> Sheeva P. schrieb:>>>>> Smarty ist nur eine Templateengine und setzt die Daten, die Du ihm>>> gibst, in Deine Templates ein. Wenn Deine Daten ordentlich validiert>>> worden sind, hat Smarty überhaupt keine Auswirkungen auf das>>> Sicherheitsniveau.>>>> Das ist nur die halbe Wahrheit, valide Daten müssen ggf. noch Escaped>> werden, und zwar passend zur Ausgabemethode.>> Nein, das war die ganze Wahrheit. Die Daten werden auf der Eingabeseite> validiert, Smarty macht hingegen nur die Ausgabe. Die Darstellung, um> die sich Smarty kümmert, ist allerdings nicht sicherheitsrelevant, da> die Daten ja bereits auf der Eingangsseite validiert worden sind.
ich hab dir dafür doch grade schon ein beispiel geliefert.
was valide ist oder nicht bestimmt einzig und alleine dein Datenmodell.
Und wenn dein Datenmodell vorsieht das Doppelte Anführungszeichen oder
Leerzeichen valide sind dann ist das so.
Trotzdem musst du das je nach Ausgabemethode Escapen.
Sheeva P. schrieb:> Die Darstellung, um> die sich Smarty kümmert, ist allerdings nicht sicherheitsrelevant, da> die Daten ja bereits auf der Eingangsseite validiert worden sind.
Das ist nicht immer der richtige Ort für sowas. Nehmen wier z.B. die
Postform dieses Forums. Hier kann man wegen der Validation keinen
HTML-Code mit einem Link-Tag posten. Das ist absolut bescheuert, weil
dass, wenn es immer korrekt escaped wird, vollkomen unbedenklich und
manchmal sogar notwendig ist.
Daniel A. schrieb:> Hier kann man wegen der Validation keinen> HTML-Code mit einem Link-Tag posten.
Falsche Baustelle. Das filtern von “hre f“ dient hier nur der
SPAM-Abwehr.
Dirk D. schrieb:>> Nein, das war die ganze Wahrheit. Die Daten werden auf der Eingabeseite>> validiert, Smarty macht hingegen nur die Ausgabe. Die Darstellung, um>> die sich Smarty kümmert, ist allerdings nicht sicherheitsrelevant, da>> die Daten ja bereits auf der Eingangsseite validiert worden sind.>>> ich hab dir dafür doch grade schon ein beispiel geliefert.>> was valide ist oder nicht bestimmt einzig und alleine dein Datenmodell.>> Und wenn dein Datenmodell vorsieht das Doppelte Anführungszeichen oder> Leerzeichen valide sind dann ist das so.>> Trotzdem musst du das je nach Ausgabemethode Escapen.
Ok, nochmal langsam: die Validierung stellt sicher, daß die
Eingangsdaten dem Datenmodell entsprechen. Wenn sie das nicht tun, nehme
ich die Daten nicht entgegen und weise sie zurück. Auf diese Weise
kommen erst gar keine Daten in mein System, die meinem Datenmodell nicht
entsprechen würden. Anders gesagt: nach einer korrekten Validierung auf
der Eingabeseite sind die Daten in meinem Systems per se
vertrauenswürdig. Das ist ja der ganze Sinn einer Eingabevalidierung:
aus nichtvertrauenswürdigen Eingabedaten vertrauenswürdige Eingabedaten
zu machen.
Die Ausgabe validierter, mithin: vertrauenswürdiger Daten hat, egal, ob
mit Escaping oder ohne, zwar etwas mit meinem Datenmodell zu tun, aber
nichts mehr mit der Sicherheit. Denn meine Daten sind ja eingangs schon
geprüft worden, jetzt geht es nur noch um die Darstellung valider Daten.
Richtig ist, daß die Darstellung und das Escaping der Daten von meinem
Datenmodell abhängen. Aber mit der Sicherheit von Smarty -- und die war
gefragt -- hat das nichts mehr zu tun.
Daniel A. schrieb:> Sheeva P. schrieb:>> Die Darstellung, um>> die sich Smarty kümmert, ist allerdings nicht sicherheitsrelevant, da>> die Daten ja bereits auf der Eingangsseite validiert worden sind.>> Das ist nicht immer der richtige Ort für sowas.
Aber natürlich ist das der richtige Ort für sowas. Wo sollte der denn
sonst sein? Bevor ein Programm mit Eingabedaten arbeiten kann, muß
sichergestellt sein, daß diese valide sind. Und das kann natürlich nur
dort geschehen, wo das Programm die Daten annimmt.
> Nehmen wier z.B. die> Postform dieses Forums. Hier kann man wegen der Validation keinen> HTML-Code mit einem Link-Tag posten. Das ist absolut bescheuert, weil> dass, wenn es immer korrekt escaped wird, vollkomen unbedenklich und> manchmal sogar notwendig ist.
Mir ist leider nicht ganz klar, was Du mir mit diesem Beispiel sagen
möchtest. Daß die Forensoftware HTML-Links zulassen sollte?
Sheeva P. schrieb:>> Trotzdem musst du das je nach Ausgabemethode Escapen.>> Ok, nochmal langsam: die Validierung stellt sicher, daß die> Eingangsdaten dem Datenmodell entsprechen. Wenn sie das nicht tun, nehme> ich die Daten nicht entgegen und weise sie zurück. Auf diese Weise> kommen erst gar keine Daten in mein System, die meinem Datenmodell nicht> entsprechen würden. Anders gesagt: nach einer korrekten Validierung auf> der Eingabeseite sind die Daten in meinem Systems per se> vertrauenswürdig. Das ist ja der ganze Sinn einer Eingabevalidierung:> aus nichtvertrauenswürdigen Eingabedaten vertrauenswürdige Eingabedaten> zu machen.>> Die Ausgabe validierter, mithin: vertrauenswürdiger Daten hat, egal, ob> mit Escaping oder ohne, zwar etwas mit meinem Datenmodell zu tun, aber> nichts mehr mit der Sicherheit. Denn meine Daten sind ja eingangs schon> geprüft worden, jetzt geht es nur noch um die Darstellung valider Daten.>> Richtig ist, daß die Darstellung und das Escaping der Daten von meinem> Datenmodell abhängen. Aber mit der Sicherheit von Smarty -- und die war> gefragt -- hat das nichts mehr zu tun.
Okay, noch viel langsamer, extra für dich:
Stell dir vor: Du willst sowas wie pastebin.com, oder ein Forum
implementieren.
Plötzlich besteht dein Datenmodell darauf das HTML und JavaScript valide
Daten sind.
Das Daten vertrauenswürdig sind heißt ja nur das da nichts drin ist was
du da nicht drin erwartest, das heißt nicht das die Daten nicht ggf.
doch gefährlich sind.
Beispiele:
- du erwartest einen Integer, du bekommst '1a'. das Validiert nicht,
alles okay.
- du erwartest einen Integer, du bekommst '11'. Das Validiert, alles
okay.
- du erwartest ein Forumspost, du bekommst "Hallo, ich habe ein Problem
mit folgendem Javascript. " onclick="alert("test");', das wird
validieren.
wenn du letzes Beispiel aber mit Hilfe von Smarty als value für ein
Eingabefeld setzen willst und smarty nicht mitteilst das du das
gesondert escaped haben willst ist das gefährlich.
Smarty versteht die Syntax der zu erzeugenden Sprache nicht und geht,
wenn du ihm nichts anderes sagst, davon aus das du in html-text
schreiben willst.
Du kannst dich natürlich auf den Standpunkt stellen das valide Daten so
simple Typen sind wie: Integer, oder string der nur aus Klein- und
Großbuchstaben sowie Leerzeichen bestehen.
Damit wirst du aber nicht sonderlich weit kommen...
Sheeva P. schrieb:> Daniel A. schrieb:>> Sheeva P. schrieb:>>> Die Darstellung, um>>> die sich Smarty kümmert, ist allerdings nicht sicherheitsrelevant, da>>> die Daten ja bereits auf der Eingangsseite validiert worden sind.>>>> Das ist nicht immer der richtige Ort für sowas.>> Aber natürlich ist das der richtige Ort für sowas. Wo sollte der denn> sonst sein? Bevor ein Programm mit Eingabedaten arbeiten kann, muß> sichergestellt sein, daß diese valide sind. Und das kann natürlich nur> dort geschehen, wo das Programm die Daten annimmt.>>> Nehmen wier z.B. die>> Postform dieses Forums. Hier kann man wegen der Validation keinen>> HTML-Code mit einem Link-Tag posten. Das ist absolut bescheuert, weil>> dass, wenn es immer korrekt escaped wird, vollkomen unbedenklich und>> manchmal sogar notwendig ist.>> Mir ist leider nicht ganz klar, was Du mir mit diesem Beispiel sagen> möchtest. Daß die Forensoftware HTML-Links zulassen sollte?
Genau da schient dein Problem zu sein.
in diesem Forum kann und soll ich ja quellcode posten dürfen.
Warum dann nicht auch Quellcode mit einem link in html.
der Clue ist, das in der Ausgabe der link nicht 1 zu 1 ausgegeben wird,
sondern so escaped wird das der Benutzer das sieht was ich eingebe,
wenn ich <b>fett</b> tippe siehst du ja auch nicht fett sonder
<b>fett</b>.
Das ist der unterschied zwischen Validierung und escaping.
Dirk D. schrieb:> Okay, noch viel langsamer, extra für dich:
Bald sind wir hier in Zeitlupe unterwegs. ;-)
> Stell dir vor: Du willst sowas wie pastebin.com, oder ein Forum> implementieren.>> Plötzlich besteht dein Datenmodell darauf das HTML und JavaScript valide> Daten sind.
Ok, stelle ich mir vor.
> - du erwartest ein Forumspost, du bekommst "Hallo, ich habe ein Problem> mit folgendem Javascript. " onclick="alert("test");', das wird> validieren.> wenn du letzes Beispiel aber mit Hilfe von Smarty als value für ein> Eingabefeld setzen willst und smarty nicht mitteilst das du das> gesondert escaped haben willst ist das gefährlich.
Nö. In meiner Eingangsschnittstelle werden die Daten natürlich vor der
Weiterverarbeitung in etwas Ungefährliches konvertiert. Das erst am
Ausgang zu machen, halte ich für grob fahrlässig.
Das, was Du dort oben als Beispiel heranziehst, würde ich nicht weiter
verarbeiten wollen, schon wegen der Double- und Singlequotes. Mit sowas
kann man sich ziemlich fiese SQL-Injections einfangen. Deswegen möchte
ich das JavaScript aus Deinem Beispiel auch nicht in meiner Loganalyse
oder sonstwo sehen. Darum gehe ich in solchen Fällen den Umweg, die
Daten entweder zu konvertieren oder, wo das nicht möglich ist,
wenigstens in Base64 zu enkodieren.
Sheeva P. schrieb:> Nö. In meiner Eingangsschnittstelle werden die Daten natürlich vor der> Weiterverarbeitung in etwas Ungefährliches konvertiert. Das erst am> Ausgang zu machen, halte ich für grob fahrlässig.
Das könnte man auch in den Griff bekommen wenn man eine Sprache hat bei
der man zwei verschiedene String-Typen deklarieren kann die NICHT
zuweisungskompatibel sind und es dann so arrangiert daß Benutzereingaben
grundsätzlich als der eine Typ reinkommen und Ausgaben zum HTML-Template
oder zur Datenbank grundsätzlich nur den anderen Typ akzeptieren und der
einzige Weg zur Umwandlung von Typ A nach Typ B eine Funktion ist die
das Escapen erledigt, die Typ A als Parameter akzeptiert und Typ B
zurückliefert.
So kann man übriges auch unbeabsichtigte Abstürze von NASA Marssonden
verhindern indem man unterschiedliche Datentypen für metrische und
imperiale Einheiten definiert die nicht zuweisungskompatibel sind und
einen zwingen über eine Konvertierungsfunktion zu gehen. So ein Fehler
würde dann schon zuhause im Compiler knallen und nicht erst Monate
später auf der Planetenoberfläche.
Dirk D. schrieb:> wenn du letzes Beispiel aber mit Hilfe von Smarty als value für ein> Eingabefeld setzen willst und smarty nicht mitteilst das du das> gesondert escaped haben willst ist das gefährlich.
Und wo ist der Unterschied dazu, wenn Du das nun direkt in PHP via echo
ausgibst? Du teilst PHP mit "Hey, das mußt Du aber escaped echo'en"?
Wenn du das mit htmlentities() machst, kannst Du den Wert auch einfach
der Smarty Variablen zuweisen.
> Smarty versteht die Syntax der zu erzeugenden Sprache nicht und geht,> wenn du ihm nichts anderes sagst, davon aus das du in html-text> schreiben willst.
Korrigiere mich, aber wo sagst Du bitteschön Smarty was für eine Sprache
die Ausgabe hat? Du definierst Templates, und was die nun sind ist
schnurzegal. Das ist einfach Text, und darin werden Daten ausgegeben.
Was soll es Smarty kümmern daß das nun meist eben HTML ist? Du kannst
auch einfach C oder Assembler, Esperanto oder sonstwas schreiben. Den
Inhalt liefert ja PHP.
> Du kannst dich natürlich auf den Standpunkt stellen das valide Daten so> simple Typen sind wie: Integer, oder string der nur aus Klein- und> Großbuchstaben sowie Leerzeichen bestehen.> Damit wirst du aber nicht sonderlich weit kommen...
Alle Daten die von Userseite kommen haben immer auf den kleinstmöglichen
Nenner gebracht zu werden. Wenn Du zB via Browser einen Shop
durchblätterst, dann versuche nur INT für die IDs zu verwenden; das
vereinfacht die Prüfung. Klar, Text muß man leider auch annehmen.
@sheevaplug
Du machst es einfach falsch, genau mit deinem Ansatz fängt man sich SQL
Injection und co. nämlich ein, und Leute wie die Nulls haben darunter zu
leiden:
http://www.wired.com/2015/11/null/http://thenextweb.com/insider/2016/03/27/last-name-null-is-tough-for-computers/#gref
Wenn man nur die Eingabe auf Validität prüft, wird man zwangslaufig
vergessen auf irgendein Keyword zu prüfen. Nur in Base64 zu Encodieren
ist auch keine lösung, denn das macht den text um ca. 1/4 grösser,
verhindert das Durchsuchen der Datenbank und vor der Ausgabe beim
Benutzer muss man es wieder dekodieren, weil dieser kein Base64
versteht. Man sollte auch nicht vor sämtlichen Verarbeitungen die Daten
escapen, denn bei unterschiedlichen Ausgabeformaten muss anders escapt
werden, und es darf auch nichts doppelt escapt werden. Wenn du z.B. alle
'<' mit '>' und '&' mit '&' escapst, direkt nach dem Empfangen,
und du es dann in eine Datenbank schreiben würdest, dann hast du
folgende Probleme:
1) Du kannst die Daten vor der Ausgabe nichtmehr escapen, da dann aus
'>' '&gt;' würde
2) Wen jemand manuell in die DB reingeschrieben hat, ist das bei der
Ausgabe nichtmehr validiert & escapt
3) Wenn du aus den Daten dann ein PDF erstellen wills, steht überall
statt '<' nur '>'
4) Du kannst immernoch Keywords übersehen
Wenn man es Richtig machen will, sollte man folgendes tun:
* Alle Daten müssen mindestens auf der Serverseite und optional
ebenfalls auf der Clientseite direkt nach dem Versenden auf Plausiblität
geprüft werden, ohne dabei zu restriktiv zu sein (z.B. name null und
sonderzeichen erlauben)
* Die Daten werden erst direkt vor der Ausgabe für die Ausgabe escapt
(bei PHP und HTML kann man mit htmlentities nicht viel falsch machen
(ausser man nutzt es in einem script tag)) (1)
* Man nutzt geprüfte verfahren um SQL injections zu verhindern, und
lässt sich SQL Queries mittels Prepared statements escapen. (In PHP
verwende ich PDO) (2)
* Jede Funktion überprüft nocheinmal die übergebenen Werte und wirft
gegebenenfaqlls eine Exception
* Alle Exceptions werden korrekt behandelt, alles muss mit
automatisierten Tests getestet sein
* Benutzereingaben dürfen keinen Einfluss auf Pfade, Dateinamen oder
URLs haben. Sollte dies dennoch notwendig werden empfehle ich nur wenige
Zeichen zuzulassen ( Beispielsweise mit dem Regex /^[a-zA-Z0-9_-]+$/ )
* Alle Funktionen müssen korrekt mit Nullbytes in Strings umgehen
können
* Benutzereingaben dürfen nicht in Scripttags, Eval-Statements oder
Vergleichbarem auftauchen.
1) http://php.net/htmlentities
2) http://php.net/manual/de/pdo.prepared-statements.php
Daniel A. schrieb:> Du machst es einfach falsch, genau mit deinem Ansatz fängt man sich SQL> Injection und co. nämlich ein, und Leute wie die Nulls haben darunter zu> leiden:> http://www.wired.com/2015/11/null/> http://thenextweb.com/insider/2016/03/27/last-name-null-is-tough-for-computers/#gref
Nö, nö, nö, und nö. Bei mir sind die Nulls sicher.
> Wenn man nur die Eingabe auf Validität prüft, wird man zwangslaufig> vergessen auf irgendein Keyword zu prüfen.
Da hast Du wohl etwas flashc verstanden. Ich prüfe nicht auf Keywords,
wie kommst Du auf das schmale Brett? Die armen Nulls haben vor mir
überhaupt nichts zu befürchten, denn nach PHPs htmlentities() oder
Pythons encode() Funktionen sind Frau und Herr Null immer noch Frau und
Herr Null. Huch!
Ehrlich jetzt, ich weiß gar nicht, was und woher Du Deine komischen
Ideen hast, wie ich meine Eingabedaten behandle. Ich werfe gar keine
Daten weg; ich konvertiere sie nur so, daß sie keine "bösen Zeichen"
mehr enthalten, aber ansonsten noch genau dieselben Informationsgehalt
haben wie vor der Konvertierung. Der Unterschied zwischen "'1'" und "1"
ist 48, sonst nix.
> Nur in Base64 zu Encodieren ist auch keine lösung, denn das macht den> text um ca. 1/4 grösser,
Schlimmer: um mindestens ein Drittel. Na und? Speicher ist billiger als
Sicherheit UND als Entwicklungszeit. Aber, wie gesagt, das ist wirklich
nur was für ganz besondere Ausnahmefälle.
> verhindert das Durchsuchen der Datenbank und
In Deiner Datenbank vielleicht. In meiner nicht:
1
SELECT ... WHERE decode(posting, 'base64') ILIKE ...;
Und bevor Du jetzt auf den Gedanken kommst, daß das auf der DB ja
ziemlich teuer wäre: ja, aber da hat meine Datenbank einige feine
Möglichikeiten in petto, aber darum kümmere ich mich, wenn die
Performance nicht reicht oder degradiert.
> vor der Ausgabe beim Benutzer muss man es wieder dekodieren, weil dieser> kein Base64 versteht.
Was hast denn Du für komische User, die kein Base64 verstehen? ;-)
> Man sollte auch nicht vor sämtlichen Verarbeitungen die Daten> escapen, denn bei unterschiedlichen Ausgabeformaten muss anders escapt> werden, und es darf auch nichts doppelt escapt werden.
Ach, weißt Du, das Schöne an einer möglichst frühzeitigen Konvertierung
der Daten auf der Eingangsschnittstelle ist, daß ich im ganzen Programm
nur halbwegs sichere Daten habe und mir um deren Escaping nur noch dann
Gedanken machen muß, wenn ich wirklich einmal an die Rohdaten kommen
muß. Und in diesem speziellen Fall gibt es zu "htmlspecialchars()" in
PHP die wunderbare Funktion namens "htmlspecialchars_decode()", welche
das Ganze problemlos wieder rückgängig macht, aber eben nur gezielt und
ganz genau dort, wo ich Rohdaten brauche.
Wenn ich eine Forensoftware entwickle, die Codelistings ermöglichen
soll, spielt es für den Programmlauf gar keine Rolle, ob ich die Daten
auf der Eingangs- oder der Ausgangsschnittstelle konvertiere. Aber wenn
ich drei oder mehr Subsysteme (für eine sehr einfache Webaplikation etwa
Ausgabe, Datenbank und Logging) mit den Daten bedienen muß, fühle ich
mich einfach viel wohler, wenn ich nicht mehr darauf achten muß, ob da
Quotes und/oder Doublequotes oä. drin vorkommen. Billiger in Bezug auf
Ressourcen ist es auch: meine CPU muß nämlich nicht in jedem Subsystem
eine speicher- und rechenintensive Verarbeitung meiner Eingabedaten
durchrödeln, damit die Daten ins Subsystem passen.
Schau, ich mache es halt anders als Du. Dabei würde ich im Gegensatz zu
Dir aber nie auf die Idee kommen, zu behaupten, daß Du es flahcs machst.
Aber während Du bei jedem Zugriff auf Deine unsicheren Variableninhalte
jedesmal darüber nachdenken mußt, ob diese Bibliothek, jenes Subsystem,
oder der nächste Softwarelayer mit dem klarkommt, was potentiell in den
Variablen stehen könnte, bin ich da vollkommen entspannt, weil ich weiß,
daß es mit meiner Datenbank, meinem OR-Mapper, mit MongoDB, Redis, dem
Logging oder LaTeX oder sonstwas keine Probleme geben kann. Und da ich
bevorzugt WTForms benutze, kann ich die Konvertierfunktionen für meine
Eingaben gänzlich entspannt an meine Formularelemente klemmen. Für URLs
hat Flask, mein Lieblings-Microframework für Python, sogar einen ganz
eigenen Mechanismus für die einfache Validierung und Konvertierung:
Ansonsten muß ich PHP zum Glück schon lange nicht mehr benutzen. Aber
wenn ich noch müßte, würde ich den Teufel tun und so etwas Primitives
wie PDO (oder, in meiner Sprache: dbapi2) verwenden. Das führt nämlich
früher oder später dazu, daß der SQL-Code immer abhängiger von der
konkreten Datenbank wird. Deswegen greife ich, wann immer es die
Performance zuläßt, zu einem OR-Mapper; für PHP wäre das bei mir
Doctrine, in meiner Sprach gibt es da Werkzeuge wie SQLAlchemy und
SQLObject, die sich um die ganzen hirnlosen Nickeligkeiten kümmern und
im Gegensatz zu primitiven DB-APIs wie PDO und dbapi2 eine echte
Abstraktion des Datenbanklayers bieten. Jeilomat, wa?
Sheeva P. schrieb:> Wenn man nur die Eingabe auf Validität prüft, wird man zwangslaufig>> vergessen auf irgendein Keyword zu prüfen.>> Da hast Du wohl etwas flashc verstanden. Ich prüfe nicht auf Keywords,> wie kommst Du auf das schmale Brett?
...
> Ehrlich jetzt, ich weiß gar nicht, was und woher Du Deine komischen> Ideen hast, wie ich meine Eingabedaten behandle. Ich werfe gar keine> Daten weg; ich konvertiere sie nur so, daß sie keine "bösen Zeichen"> mehr enthalten, aber ansonsten noch genau dieselben Informationsgehalt> haben wie vor der Konvertierung.
Das ist dann aber keine Validation mehr, sondern etwas ähnliches wie
Escapen. In deinen ersten beiden Posts redest du nur von Validieren. Du
hast sogar folgendes geschrieben:
Sheeva P. schrieb:> Nein, das war die ganze Wahrheit. Die Daten werden auf der Eingabeseite> validiert, Smarty macht hingegen nur die Ausgabe. Die Darstellung, um> die sich Smarty kümmert, ist allerdings nicht sicherheitsrelevant, da> die Daten ja bereits auf der Eingangsseite validiert worden sind.
Dies impliziert das du nur eine Validation durchfürst. Das ist ein wenig
als würde man sagen: "Hey, ich prüfe die Daten nur einmal auf
Korrektheit, danach ist alles sicher", und dann auf Einwände Antwortet:
"Ich konvertiere es hier und hier, so überprüfe ich die Eingaben, wie
bist du auf andere Ideen gekommen?". Validieren beinhaltet nunmal nicht
Escapen. Es geht um die Terminologie.
Sheeva P. schrieb:> SELECT ... WHERE decode(posting, 'base64') ILIKE ...;
Perfekt, schon habe ich meinen ersten Angriffsvektor. Hier kann ich dir
beliebige MySQL Keywords unterjubeln, z.B. "\x9Eée" für null. Mich hält
soetwas nicht von von SQL Injection ab.
PS: Wenn du mir die URL zu deiner Homepage gibst könnte ich dort für
dich nach Sicherheitslücken suchen.
Sheeva P. schrieb:> Dirk D. schrieb:>> Okay, noch viel langsamer, extra für dich:>> Bald sind wir hier in Zeitlupe unterwegs. ;-)
--- Wenn das Nötig ist das du die Sachlage verstehst :)
>>> Stell dir vor: Du willst sowas wie pastebin.com, oder ein Forum>> implementieren.>>>> Plötzlich besteht dein Datenmodell darauf das HTML und JavaScript valide>> Daten sind.>> Ok, stelle ich mir vor.>>> - du erwartest ein Forumspost, du bekommst "Hallo, ich habe ein Problem>> mit folgendem Javascript. " onclick="alert("test");', das wird>> validieren.>> wenn du letzes Beispiel aber mit Hilfe von Smarty als value für ein>> Eingabefeld setzen willst und smarty nicht mitteilst das du das>> gesondert escaped haben willst ist das gefährlich.>> Nö. In meiner Eingangsschnittstelle werden die Daten natürlich vor der> Weiterverarbeitung in etwas Ungefährliches konvertiert. Das erst am> Ausgang zu machen, halte ich für grob fahrlässig.
Und du weißt am Eingang schon welche Subsysteme mit deinen Daten in
Berührung kommen und kennst alle Fallstricke aller Subsysteme?
>> Das, was Du dort oben als Beispiel heranziehst, würde ich nicht weiter> verarbeiten wollen, schon wegen der Double- und Singlequotes.
Du fühlst dich also nicht dazu in der Lage in Forum zu Programmieren in
dem man Code-Snipets posten darf, willst aber Ratschläge genen wie man
richtig Programmiert?
> Mit sowas> kann man sich ziemlich fiese SQL-Injections einfangen.
Aber nur wenn man Fahrlässig genug ist die Existens von Prepared
Statements zu ignorieren.
> Deswegen möchte> ich das JavaScript aus Deinem Beispiel auch nicht in meiner Loganalyse> oder sonstwo sehen.
Ist die auch von dir geschrieben?
> Darum gehe ich in solchen Fällen den Umweg, die> Daten entweder zu konvertieren oder, wo das nicht möglich ist,> wenigstens in Base64 zu enkodieren.
Oh das klingt total clever, und das löst auch nicht das
Ursprungs-Problem, nämlich das du die Daten ne nach Ausgabe-situation
anders Escapen musst.
smarter schrieb:> Dirk D. schrieb:>> wenn du letzes Beispiel aber mit Hilfe von Smarty als value für ein>> Eingabefeld setzen willst und smarty nicht mitteilst das du das>> gesondert escaped haben willst ist das gefährlich.>> Und wo ist der Unterschied dazu, wenn Du das nun direkt in PHP via echo> ausgibst?
Nirgendwo. die Ursprungsfrage vom OP war ja ob Smarty an der Stelle
hinreichend viel für in tut um solche Probleme abzuwenden.
Nein, ist es nicht, warum hab ich beschrieben.
> Du teilst PHP mit "Hey, das mußt Du aber escaped echo'en"?> Wenn du das mit htmlentities() machst, kannst Du den Wert auch einfach> der Smarty Variablen zuweisen.
htmlentities() ist eben nicht das Allheilmittel, aber ja, du kannst das
machen, da spricht auch erstmal nichts gegen.
>>> Smarty versteht die Syntax der zu erzeugenden Sprache nicht und geht,>> wenn du ihm nichts anderes sagst, davon aus das du in html-text>> schreiben willst.>> Korrigiere mich, aber wo sagst Du bitteschön Smarty was für eine Sprache> die Ausgabe hat? Du definierst Templates, und was die nun sind ist> schnurzegal. Das ist einfach Text, und darin werden Daten ausgegeben.> Was soll es Smarty kümmern daß das nun meist eben HTML ist? Du kannst> auch einfach C oder Assembler, Esperanto oder sonstwas schreiben. Den> Inhalt liefert ja PHP.
Per Default schiebt smarty alle Eingabewerte durch htmlentities(), weil
es davon ausgeht das du Ja html-text schreiben willst und nicht C
Assembler, Esperanto oder sonnstwas.
Wenn du etwas anderes willst musst du smarty das mitteilen, durch
{$var|json_decode} als beispiel für json, du musst den filter natürlich
vorher registrieren.
>>>> Du kannst dich natürlich auf den Standpunkt stellen das valide Daten so>> simple Typen sind wie: Integer, oder string der nur aus Klein- und>> Großbuchstaben sowie Leerzeichen bestehen.>> Damit wirst du aber nicht sonderlich weit kommen...> Alle Daten die von Userseite kommen haben immer auf den kleinstmöglichen> Nenner gebracht zu werden.
Natürlich, aber der Kleinstmögliche Nenner ist nun mal in dem Beispiel
Freitext der unter anderem Javascript und Html enthalten darf.
> Wenn Du zB via Browser einen Shop> durchblätterst, dann versuche nur INT für die IDs zu verwenden; das> vereinfacht die Prüfung. Klar, Text muß man leider auch annehmen.
Dirk D. schrieb:> Nirgendwo. die Ursprungsfrage vom OP war ja ob Smarty an der Stelle> hinreichend viel für in tut um solche Probleme abzuwenden.
Zur Erinnerung, denn Du schrubest:
> Smarty versteht die Syntax der zu erzeugenden Sprache nicht und geht,> wenn du ihm nichts anderes sagst, davon aus das du in html-text> schreiben willst.
Deine Aussage war also, daß Du Smarty sagen mußt was Du für Ausgabe
erzeugst (per Default HTML), was schlichtweg falsch ist.
> Per Default schiebt smarty alle Eingabewerte durch htmlentities(), weil> es davon ausgeht das du Ja html-text schreiben willst und nicht C> Assembler, Esperanto oder sonnstwas.> Wenn du etwas anderes willst musst du smarty das mitteilen, durch> {$var|json_decode} als beispiel für json, du musst den filter natürlich> vorher registrieren.
Hast Du vielleicht noch nie mit Smarty gearbeitet? Wenn ich in meinem
PHP eine Variable für Smarty mit assign('doublequote', '"') belege, dann
habe ich im Quelltext nachher was? Ja, ein " und kein ". Wie kommst
Du also bitte auf das schmale Brett das alles automatisch durch
htmlentities() gehen sollte? Das wäre der absolute Blödsinn.
Dein Beispiel ist übrigens auch etwas daneben, denn damit rufst Du
keinen Smarty Modifikator auf, sondern die PHP Funktion json_decode.
Hättest Du wenigstens |lower als Beispiel für einen Modifikator
genommen... Könnte es sein daß Du stattdessen registerFilter() meinst?
Aber andererseits nutzt man Filter nicht in Templates, sondern vorher.
Also nochmal, schon jemals Smarty benutzt, oder trollst Du hier nur?
Weil, was Du schreibst ist so hanebüchen falsch, das tut richtig weh
beim lesen und lässt Dich entsprechend dastehen.
> Natürlich, aber der Kleinstmögliche Nenner ist nun mal in dem Beispiel> Freitext der unter anderem Javascript und Html enthalten darf.
Ja und? Ich habe hier privat eine MySQL DB in der via Browser viel
Japanisch reingeschrieben wird. Auf Arbeit habe ich ein paar
selbstgeschriebene Seiten die Chinesisch enthalten, aber auch massig
Quellcodes aus C, HTML, JS, Perl, PHP, Python, usw. Damit hat die DB
jetzt seit Jahren noch nie Probleme gehabt. PDO eben, kein blödsinniges
Geschwurbsel mit zur Laufzeit gebastelten Queries. Da nutze ich noch
nicht mal htmlentities() beim Import.
>> SELECT ... WHERE decode(posting, 'base64') ILIKE ...;> Perfekt, schon habe ich meinen ersten Angriffsvektor. Hier kann ich dir> beliebige MySQL Keywords unterjubeln
Zeig doch bitte mal eine MySQL Injektion für diesen Postgres Query, bei
dem Du noch nicht mal siehst ob es evtl PDO ist...
smarter schrieb:> Dirk D. schrieb:>> Nirgendwo. die Ursprungsfrage vom OP war ja ob Smarty an der Stelle>> hinreichend viel für in tut um solche Probleme abzuwenden.>> Zur Erinnerung, denn Du schrubest:>> Smarty versteht die Syntax der zu erzeugenden Sprache nicht und geht,>> wenn du ihm nichts anderes sagst, davon aus das du in html-text>> schreiben willst.>> Deine Aussage war also, daß Du Smarty sagen mußt was Du für Ausgabe> erzeugst (per Default HTML), was schlichtweg falsch ist.
Da hab ich mich zum Teil geirrt.
twig hat per default htmlenteties als escaping, smarty nicht, zumindest
nicht bevor du das einschaltest.
Trotzdem kannst du Smarty sagen wie es escapen soll:
Aus der Smarty-Doku
(http://www.smarty.net/docsv2/de/language.modifier.escape.tpl):
{$artikelTitel}
{$artikelTitel|escape}
{$artikelTitel|escape:"html"} {* maskiert & " ' <
> *}
{$artikelTitel|escape:"htmlall"} {* maskiert ALLE html Entitäten *}
{$artikelTitel|escape:"url"}
{$artikelTitel|escape:"quotes"}
>>>> Per Default schiebt smarty alle Eingabewerte durch htmlentities(), weil>> es davon ausgeht das du Ja html-text schreiben willst und nicht C>> Assembler, Esperanto oder sonnstwas.>> Wenn du etwas anderes willst musst du smarty das mitteilen, durch>> {$var|json_decode} als beispiel für json, du musst den filter natürlich>> vorher registrieren.>> Hast Du vielleicht noch nie mit Smarty gearbeitet?
Dock, hab ich, ist aber schon einige Jahre her, zu letzt eher mit Twig,
wie gesagt, habs verwechselt, sorry.
> Wenn ich in meinem> PHP eine Variable für Smarty mit assign('doublequote', '"') belege, dann> habe ich im Quelltext nachher was? Ja, ein " und kein ". Wie kommst> Du also bitte auf das schmale Brett das alles automatisch durch> htmlentities() gehen sollte? Das wäre der absolute Blödsinn.>> Dein Beispiel ist übrigens auch etwas daneben, denn damit rufst Du> keinen Smarty Modifikator auf, sondern die PHP Funktion json_decode.> Hättest Du wenigstens |lower als Beispiel für einen Modifikator> genommen... Könnte es sein daß Du stattdessen registerFilter() meinst?> Aber andererseits nutzt man Filter nicht in Templates, sondern vorher.
Auch hier war ich wohl halb bei twig, da heißen die smarty-modifier
filter, und da gibt es einen json_encode filter.
Wenn du also Statt Filter Modifier Liest passts wieder.
json_decode hab ich in der stelle absichtlich gewählt um auf die
escape-problematik zu zeigen.
>> Also nochmal, schon jemals Smarty benutzt, oder trollst Du hier nur?
Wie gesagt, ja, habe ich, und ich hab Dinge aus der Twig-welt
verwechselt, dafür möchte ich mich auch ausdrücklich entschuldigen.
> Weil, was Du schreibst ist so hanebüchen falsch, das tut richtig weh> beim lesen und lässt Dich entsprechend dastehen.>>>> Natürlich, aber der Kleinstmögliche Nenner ist nun mal in dem Beispiel>> Freitext der unter anderem Javascript und Html enthalten darf.>> Ja und? Ich habe hier privat eine MySQL DB in der via Browser viel> Japanisch reingeschrieben wird. Auf Arbeit habe ich ein paar> selbstgeschriebene Seiten die Chinesisch enthalten, aber auch massig> Quellcodes aus C, HTML, JS, Perl, PHP, Python, usw. Damit hat die DB> jetzt seit Jahren noch nie Probleme gehabt. PDO eben, kein blödsinniges> Geschwurbsel mit zur Laufzeit gebastelten Queries. Da nutze ich noch> nicht mal htmlentities() beim Import.
Mein reden, Sheeva Plug ist der Meinung das Daten grundsätzlich
gefährlich sind, Ich, und wenn ich dich richtig verstehe, auch du bist
der Meinung das Daten nur dann gefährlich sind wenn man sie ohne
escaping ins falsche Format abkippt.
>>>>> SELECT ... WHERE decode(posting, 'base64') ILIKE ...;>> Perfekt, schon habe ich meinen ersten Angriffsvektor. Hier kann ich dir>> beliebige MySQL Keywords unterjubeln>> Zeig doch bitte mal eine MySQL Injektion für diesen Postgres Query, bei> dem Du noch nicht mal siehst ob es evtl PDO ist...
Das ist auch nicht von mir :)
Dirk D. schrieb:> Da hab ich mich zum Teil geirrt.
Respekt. Sieht man heute selten daß jemand Fehler einräumt :)
> Trotzdem kannst du Smarty sagen wie es escapen soll:
Jo, hat es, aber mMn muß sowas bereits PHP seitig passieren. Das sollte
so nur eine Notlösung sein wenn zB der Webmaster eine Variable als
Buttontext mißbraucht und Quotes sauber haben will.
> json_decode hab ich in der stelle absichtlich gewählt um auf die> escape-problematik zu zeigen.
Vielleicht stehe ich nun auf dem Schlauch, aber wieso sollte man
json_decode() in Smarty nutzen? Ich nutze JSON primär in AJAX, und da
wird alles entweder clientseiting via JS, oder backendseitig via PHP
gemacht. Smarty hatte ich da noch nie involviert.
> Mein reden, Sheeva Plug ist der Meinung das Daten grundsätzlich> gefährlich sind, Ich, und wenn ich dich richtig verstehe, auch du bist> der Meinung das Daten nur dann gefährlich sind wenn man sie ohne> escaping ins falsche Format abkippt.
Nunja, auch ich traue keinen Daten die von einem Client kommen. Eine
Prüfung auf der Seite kann nur zur Benutzerfreundlichkeit beitragen
(zB "Das ist keine Emailadresse"), aber Input muß immer serverseitig
geprüft werden. Lieber ein die() zuviel als Probleme. Alles kann man
nicht prüfen (Freitext), sondern sich nur so gut wie möglich absichern.
PDO, keine ungeprüfte Übernahme aus GET/POST, usw.
Es muß halt beim entwickeln klar sein, wo die Daten auftauchen. Wenn man
Freitext bei zB einem Forum einfach so in ein <div></div> packt wie es
reinkam, kein Wunder wenn man Ärger bekommt. Oder, was auch passiert,
Pfade zu include Files per GET zu übertragen.
>> Zeig doch bitte mal eine MySQL Injektion für diesen Postgres Query, bei>> dem Du noch nicht mal siehst ob es evtl PDO ist...> Das ist auch nicht von mir :)
Hier muß nun ich mich entschuldigen :) Hab glatt die Zeile mit dem
Urheber mitgelöscht.
smarter schrieb:> Dirk D. schrieb:>> Da hab ich mich zum Teil geirrt.>> Respekt. Sieht man heute selten daß jemand Fehler einräumt :)>>> Trotzdem kannst du Smarty sagen wie es escapen soll:> Jo, hat es, aber mMn muß sowas bereits PHP seitig passieren. Das sollte> so nur eine Notlösung sein wenn zB der Webmaster eine Variable als> Buttontext mißbraucht und Quotes sauber haben will.
Was machst du den wenn du im Temlate z.B. den Usernamen an mehren
Stellen brauchst, im Fliestext, als Attribut an nem Icon, oder so.
Gibst du dann für jede mögliche Art der Verwendung eine Version der
Daten mit? oder Entscheidest du über das escaping genau da wo du es
brauchst?
>>> json_decode hab ich in der stelle absichtlich gewählt um auf die>> escape-problematik zu zeigen.>> Vielleicht stehe ich nun auf dem Schlauch, aber wieso sollte man> json_decode() in Smarty nutzen? Ich nutze JSON primär in AJAX, und da> wird alles entweder clientseiting via JS, oder backendseitig via PHP> gemacht. Smarty hatte ich da noch nie involviert.
Ich hatte z.B. mal nen Slideshow-System, der Kunde wollte genau das. das
hat Metadaten über das bild in json an nem data-attribut erwartet.
>>> Mein reden, Sheeva Plug ist der Meinung das Daten grundsätzlich>> gefährlich sind, Ich, und wenn ich dich richtig verstehe, auch du bist>> der Meinung das Daten nur dann gefährlich sind wenn man sie ohne>> escaping ins falsche Format abkippt.>> Nunja, auch ich traue keinen Daten die von einem Client kommen. Eine> Prüfung auf der Seite kann nur zur Benutzerfreundlichkeit beitragen> (zB "Das ist keine Emailadresse"), aber Input muß immer serverseitig> geprüft werden. Lieber ein die() zuviel als Probleme. Alles kann man> nicht prüfen (Freitext), sondern sich nur so gut wie möglich absichern.> PDO, keine ungeprüfte Übernahme aus GET/POST, usw.>> Es muß halt beim entwickeln klar sein, wo die Daten auftauchen. Wenn man> Freitext bei zB einem Forum einfach so in ein <div></div> packt wie es> reinkam, kein Wunder wenn man Ärger bekommt. Oder, was auch passiert,> Pfade zu include Files per GET zu übertragen.
Klar, wenn ich weiß das in dem Datenfeld nur Integer, Boolsche, oder
texte die ich per regex auf was "einfaches" prüfen kann, weil die nicht
anders sein dürfen dann mach ich das, schon alleine um keine Daten zu
haben die invalide sind.
Trotzdem behandele ich Daten wenn ich sie Einbette, in SQL, HTML,
Javascript, css, was auch immer, immer so als könnten die Potentiell
Böse sein, auch wenn ich davon ausgehe das da nen Benutzername kommt der
nur aus Alphanumerischen bestehen sollte.
Im besten Fall passiert dann nichts anderes als wenn ich es ignoriert
hätte. im schlimmsten Fall, z.B. wenn jemand eine andere Lücke genutzt
hat um mir Daten unterzuschieben die nicht so sind wie ich sie erwarte
bin ich halt auf der sicheren Seite.
Da zeig ich lieber den Benutzername passend escaped an, und der User
liest Javascript das durch htmlentities() gerutscht ist, als das
Javascript was jetzt da ist, obwohl es nicht da sein sollte dem client
zum ausführen hin zu werfen.
Viel mehr Spaß machen an der Stelle aber Template-Systeme die die zu
erzeugende Sprache verstehen und solche Probleme selbst lösen.
Beruflich Arbeite ich Häufig mit nem System das HTML mit xslt aus
XML-Eingabedaten erzeugt.
Da ist xss Praktisch ausgeschlossen.
Ähnlich sied es mit Jade / Pug /Haml aus.
Dirk D. schrieb:> Was machst du den wenn du im Temlate z.B. den Usernamen an mehren> Stellen brauchst, im Fliestext, als Attribut an nem Icon, oder so.> Gibst du dann für jede mögliche Art der Verwendung eine Version der> Daten mit? oder Entscheidest du über das escaping genau da wo du es> brauchst?
Ein Username ist sicher, denn der kann nach der Eingangsprüfung nix
schlechtes enthalten.
> Ich hatte z.B. mal nen Slideshow-System, der Kunde wollte genau das. das> hat Metadaten über das bild in json an nem data-attribut erwartet.
Aber dann steht JSON im data Attrib, und das wertet man mit JS aus.
Sobald JSON an PHP geht, würde ich es dort in eine Variable konvertieren
und per assign() an Smarty zuweisen.
smarter schrieb:> Ein Username ist sicher, denn der kann nach der Eingangsprüfung nix> schlechtes enthalten.
Das kommt ganz drauf an wie restriktiv der Username zu sein hat...
Daniel A. schrieb:> Das ist dann aber keine Validation mehr, sondern etwas ähnliches wie> Escapen.
Ok, da hast Du Recht.
> Sheeva P. schrieb:>> SELECT ... WHERE decode(posting, 'base64') ILIKE ...;>> Perfekt, schon habe ich meinen ersten Angriffsvektor. Hier kann ich dir> beliebige MySQL Keywords unterjubeln, z.B. "\x9Eée" für null.
Bei meiner Datenbank kommst Du mit MySQL-Keywords nicht weit. ;-)
> Mich hält soetwas nicht von von SQL Injection ab.
Ich glaube schon:
Sheeva P. schrieb:>> Mich hält soetwas nicht von von SQL Injection ab.>> Ich glaube schon:> luke=# SELECT decode('\x9Eée', 'base64');> ERROR: invalid symbol
Nunja, ich geb ja zu das es nicht geht, jedoch hast du nicht ganz
erfasst was ich meinte:
1
php>echobase64_encode("\x9E\xE9e");
2
null
Natürlich nützt mir das nicht viel, weil es dann zwischen zwei '\''
Zeichen wäre, aber ich denke man sieht die Idee dahinter.
Man kann halt in codierten Daten auch nicht wirklich suchen.
Also natürlich kann man sowas machen wie
SELECT * FROM foo WHERE BASE64_DECODE(data) LIKE :suchmuster
aber dann durchwühlt die Datenbank bei jeder anfrage alle Daten und
Indizierung ist auch unmöglich.
Mir ist fraglich wie man sowas für eine gute Idee halten kann.
Dann kann ich meine Daten auch direkt in Dateien schreiben.
Da kann ich auch nicht wirklich suchen...
Daniel A. schrieb:> Sheeva P. schrieb:>> SELECT ... WHERE decode(posting, 'base64') ILIKE ...;>> Perfekt, schon habe ich meinen ersten Angriffsvektor. Hier kann ich dir> beliebige MySQL Keywords unterjubeln, z.B. "\x9Eée" für null. Mich hält> soetwas nicht von von SQL Injection ab.
Da erlaube ich mir mal, das anders zu sehen:
Dirk D. schrieb:> Mein reden, Sheeva Plug ist der Meinung das Daten grundsätzlich> gefährlich sind,
Richtig. Jedwede Daten aus nicht vertrauenswürdigen Quellen sind nicht
vertrauenswürdig und daher grundsätzlich als gefährlich zu betrachten.
> Ich, und wenn ich dich richtig verstehe, auch du bist> der Meinung das Daten nur dann gefährlich sind wenn man sie ohne> escaping ins falsche Format abkippt.
Auch richtig. Bei einer Webapplikation werden die Daten in 99% aller
Fälle -- ganz gleichgültig, wo sie zwischendrin landen -- auch wieder
als HTML ausgegeben. Also kann ich sie gleich auf der Eingangsseite
gleich nach der Validierung in ein HTML-kompatibles Format konvertieren
und muß dann nicht mehr darüber denken. Das ist auch dann sinnvoll, wenn
mehrere Entwickler gemeinsam an einem Projekt arbeiten, oder wenn die
Templates von Designern und Layoutern bearbeitet werden, die das
Escaping gern vergessen.
Oh Mann Leute es ist doch so einfach:
Oberste Regel die niemals gebrochen wird: ALLES WAS REINKOMMT GEHT DURCH
FILTER, AUSNAHMSLOS! Clientseitige Checks via Javascript dienen nur der
Anwenderergonomie und sind NIEMALS Ersatz für serverseitige Checks.
Mit was ich das mache (von Hand, per Framework,...) ist erst mal egal
solange ich weiss was der jeweilige Filter eines Frameworks macht und
ausreicht ist das ok. Da man sich da immer auf Dritte verlässt und evt.
in der nächsten Release anders arbeitet,... SCHREIBT MAN sich entspr.
FILTER BESSER SELBST. NUR ICH weiss was durchkommen darf und draussen
bleiben soll. Da kann man sich nicht auf andere verlassen.
PHP bringt entspr. Basisfilterfunktionen mit auf die man aufbauen kann:
http://php.net/manual/en/book.filter.php
PS: Ja ich LIEBE Grossbuchstaben.
PHP-Dödel in der Kaffeepause schrieb:> Oberste Regel die niemals gebrochen wird: ALLES WAS REINKOMMT GEHT DURCH> FILTER, AUSNAHMSLOS! Clientseitige Checks via Javascript dienen nur der> Anwenderergonomie und sind NIEMALS Ersatz für serverseitige Checks.
Das hat doch noch gar keiner bestritten.
PHP-Dödel in der Kaffeepause schrieb:> Mit was ich das mache (von Hand, per Framework,...) ist erst mal egal> solange ich weiss was der jeweilige Filter eines Frameworks macht und> ausreicht ist das ok.
...
> PHP bringt entspr. Basisfilterfunktionen mit auf die man aufbauen kann:
Man darf sich nicht nur auf Filter Bzw. Validation verlassen. Send mir
doch eine Mail an: &|~-'/*@danielabrecht.ch (wer weiss, was ich da sonst
noch so reinpacken könnte)
Natürlich geht es Problemlos durch den Filter:
Sheeva P. schrieb:> Auch richtig. Bei einer Webapplikation werden die Daten in 99% aller> Fälle -- ganz gleichgültig, wo sie zwischendrin landen -- auch wieder> als HTML ausgegeben. Also kann ich sie gleich auf der Eingangsseite> gleich nach der Validierung in ein HTML-kompatibles Format konvertieren> und muß dann nicht mehr darüber denken.
Und was machst du wenn du in deinen Daten suchen willst?
Deine Daten per Json an den Client übertragen willst?
Du logs schreiben willst?
Du Emails schreiben willst?
Du vieleicht pdf's erzeugen willst?
du nen Sitemap-file generieren willst?
Jedes mal wieder zurück Konvertieren? das klingt nach ner Spitzen idee.
In ne Datenbank gehören die Daten, nicht eine Representaiton der Taten
für ein Bestimmtes Ausgabeformat.
Was machst du wenn du dich entschließt deine Seite Jetzt per Angular
o.Ä. neu zu gestalten.
Konvertierst du dann deine Daten in der Datenbank dammit das wieder
klappt?
Daniel A. schrieb:>> PHP bringt entspr. Basisfilterfunktionen mit auf die man aufbauen kann:>> Man darf sich nicht nur auf Filter Bzw. Validation verlassen. Send mir> doch eine Mail an: &|~-'/*@danielabrecht.ch (wer weiss, was ich da sonst> noch so reinpacken könnte)>> Natürlich geht es Problemlos durch den Filter:php > echo> filter_var("&|~-'/*@danielabrecht.ch", FILTER_VALIDATE_EMAIL) ? "ok" :> "nope";> ok
Wieder echt PHP-Schrott: Bug schon lange bekannt und bis heute nicht
gefixed (7.0.6).
Deshalb selber schreiben und fleissig Tests schreiben.
php-dödel schrieb:> Wieder echt PHP-Schrott: Bug schon lange bekannt und bis heute nicht> gefixed (7.0.6).> Deshalb selber schreiben und fleissig Tests schreiben.
Das ist kein PHP Bug. Diese Mail Adresse ist echt und Funktionsfähig. Es
wäre ein Bug, wenn diese nicht durch die Validation käme.
Dirk D. schrieb:> Sheeva P. schrieb:>>> Auch richtig. Bei einer Webapplikation werden die Daten in 99% aller>> Fälle -- ganz gleichgültig, wo sie zwischendrin landen -- auch wieder>> als HTML ausgegeben. Also kann ich sie gleich auf der Eingangsseite>> gleich nach der Validierung in ein HTML-kompatibles Format konvertieren>> und muß dann nicht mehr darüber denken.>> Und was machst du wenn du in deinen Daten suchen willst?> Deine Daten per Json an den Client übertragen willst?> Du logs schreiben willst?> Du Emails schreiben willst?> Du vieleicht pdf's erzeugen willst?> du nen Sitemap-file generieren willst?> Jedes mal wieder zurück Konvertieren? das klingt nach ner Spitzen idee.
Hast Du das, was ich oben geschrieben habe, nicht gelesen oder hast Du
es vielleicht nicht verstanden? Ich wähle und validiere sehr genau, wie
ich Daten aus nichtvertrauenswürdigen Quellen handhabe und was dann am
Ende in meinen Datenfeldern stehen darf. Und wenn der Anwendungsfall es
vorgibt, potentiell gefährliche Inhalte verarbeiten zu müssen,
konvertiere ich sie an der Eingangsschnittstelle in ein Format, das
meinen Subsystemen soweit möglich keine Probleme bereiten kann. Mit
dieser Vorgehensweise habe ich erfolgreich mehrere professionelle
Penetration Tests, Sicherheits- und tatsächlich auch Codeaudits
absolviert.
Also laß' jetzt bitte die Luft 'raus, Dirk, und gewöhn' Dich einfach mal
an den Gedanken, daß andere Menschen einige Dinge vielleicht anders
machen als Du, und das trotzdem nicht unbedingt falsch sein muß. Ich
jedenfalls fahre mit meiner Technik, alles, was 'reinkommt, so früh und
so weit wie möglich zu entschärfen, bislang ziemlich gut.
> In ne Datenbank gehören die Daten, nicht eine Representaiton der Taten> für ein Bestimmtes Ausgabeformat.>> Was machst du wenn du dich entschließt deine Seite Jetzt per Angular> o.Ä. neu zu gestalten.> Konvertierst du dann deine Daten in der Datenbank dammit das wieder> klappt?
Ach, laß' das doch einfach mal meine Sorge sein, ja? Bisher habe ich
noch immer einen Weg gefunden, ob Du das nun wahrhaben willst oder
meinetwegen auch nicht. :-)