Versuche der "feindlichen Übernahme"?
Christoph Schnauß
- php
hallo Forum,
seit ungefähr zwei Wochen beobachte ich an den logs einer Site, die ich zu betreuen habe, zunehmend logeinträge, nach denen Indexseiten (index.php) mit einem Parameter und einer angehängten URL aufgerufen werden. Beispiele:
http://www.spycorp-labs.com/echo.txt?
http://usuarios.arnet.com.ar/larry123/safe.txt?
http://studio.blacklodge.org/blog/backend/help.txt?
Letzten Endes ist es immer derselbe Versuch, ein PHP-Script, das zu diesem Zweck glücklicherweise als Text übermittelt werden muß, anzuhängen. Nur habe ich bisher nicht genau herausgefunden, was diese Scripts eigentlich wollen.
Versucht wird es mit Parametern in der Art
index.php?site=[URL]
index.php?inhalt=[URL]
index.php?links=[URL]
index.php?url=[URL]
Alles bisher Parameter, die ich sowieso nicht verwende, also kann eigentlich auch nichts passiert sein. Eigentlich - oder?
Wie sind solche Aufrufe zu bewerten?
Grüße aus Berlin
Christoph S.
Hallo Christoph,
Du bist nicht der einzige, der davon betroffen ist, siehe https://forum.selfhtml.org/?t=158494&m=1030510
Wie sind solche Aufrufe zu bewerten?
Wie in dem Thread zu lesen wird wohl versucht, einen Wurm über die Seite zu verbreiten. Scheint etwas größeres zur Zeit zu sein und es wird gezielt auf schlecht abgesicherte Seiten zu gehen.
Grüße
David
hallo David,
Du bist nicht der einzige, der davon betroffen ist, siehe https://forum.selfhtml.org/?t=158494&m=1030510
Ups, das war mir entgangen. Dann hätte ich ja, wenn auch unabsichtlich, ein Doppelposting verfaßt. Hm.
Grüße aus Berlin
Christoph S.
Hi,
Ups, das war mir entgangen. Dann hätte ich ja, wenn auch unabsichtlich, ein Doppelposting verfaßt. Hm.
<lifeofbrian>
Naja, dann nehme ich 2 spitze... und ääh... zwei flache.... und ein Paket Kies.....
</lifeofbrian>
*SCNR*
hallo Karin,
... und ein Paket Kies...
öhm, den nehme ich nur (feinkörnig, versteht sich), wenn ich einen Weinballon saubermachen möchte, so daß wieder neuer Holunderwein eingefüllt werden kann - womit wir glücklicherweise bei einem viel interessanteren Thema wären ;-)
Grüße aus Berlin
Christoph S.
Hi,
[...] - womit wir glücklicherweise bei einem viel interessanteren Thema wären ;-)
höhö, mal wieder mit der Spezialität des Hauses die Kurve gekriegt... *g*
Wird der eigentlich durch den vielen Zucker trotz der herben Frucht süß? Ich habe mal
einen Heidelbeerwein getrunken, war zwar lecker aber elend süß (nicht so mein Fall).
Naja gut, waren wohl auch keine Waldheidelbeeren sondern eine von den Zuchtsorten...
LG
hallo Karin,
Wird der eigentlich durch den vielen Zucker trotz der herben Frucht süß?
Das hängt von der zugesetzten Zuckermenge ab. Ich selber mag keinen "süßen" Wein, sondern will ihn "halbtrocken" haben - und das ist problemlos machbar.
einen Heidelbeerwein getrunken
Das sollten wir bei Bedarf in der Lounge weiterdiskutieren, weil Heidelbeeren etwas heikel sind.
Grüße aus Berlin
Christoph S.
Hi,
Das sollten wir bei Bedarf ...
zur Zeit leider nicht, ich kenne in der Umgebung keine Stellen zum Sammeln und habe auch
kein Auto mehr zum rausfahren. Hatte mich nur mal so interessiert. Vielleicht komm' ich
irgendwann darauf zurück ;-)
LG
PS.:
...weil Heidelbeeren etwas heikel sind.
Für Marmelade sind sie unschlagbar :-)
Hiho!
Das kannst Du mit ziemlicher Sicherheit so bewerten:
https://forum.selfhtml.org/?t=158494&m=1030510
Hallo Christoph,
http://www.spycorp-labs.com/echo.txt?
http://usuarios.arnet.com.ar/larry123/safe.txt?
http://studio.blacklodge.org/blog/backend/help.txt?
Nur habe ich bisher nicht genau herausgefunden, was diese Scripts eigentlich wollen.
Das zweite ist das gleiche Script, wie in diesem Thread, versucht also die Zielseite als Wurmschleuder zu missbrauchen.
Ich habe mich dort übrigens vertan, die iframes werden angehängt, die ürsprünglichen Daten
bleiben also erhalten.
Die anderen beiden geben nur Systeminformationen aus (soweit ich das zu dieser Uhrzeit überblicke...),
aber die soll ja nun auch nicht jeder lesen, könnte ausserdem den Zweck haben, Informationen für
weitere Angriffe zu sammeln (OS, www-user...).
Alles bisher Parameter, die ich sowieso nicht verwende, also kann eigentlich auch nichts passiert sein. Eigentlich - oder?
Nein, eigentlich nicht. Theoretisch: register_globals sind on und Du verwendest eine Variable
mit passendem Namen, die Du nicht initialisiert hast... (und weitere Prämissen...)
Ich geh bei Dir mal davon aus, dass das nicht der Fall ist ;-)
Grüße aus Berlin
Christoph S.
Grüße aus Bremen
Karin
hallo Karin,
Alles bisher Parameter, die ich sowieso nicht verwende, also kann eigentlich auch nichts passiert sein. Eigentlich - oder?
Nein, eigentlich nicht. Theoretisch: register_globals sind on und Du verwendest eine Variable
mit passendem Namen, die Du nicht initialisiert hast... (und weitere Prämissen...)
Ich geh bei Dir mal davon aus, dass das nicht der Fall ist ;-)
danke für die Blumen - aber manchmal ist es auch Sache des Providers. In diesem Fall liegt die Seite bei einem Provider, der PHP 4.4.3 verwendet und tatsächlich register_globals auf on gestellt hat. Variablen mit "passendem Namen" gibt es allerdings nicht, auch kein unkontrolliertes Einbinden von "include($_REQUEST['seite'])"
Grüße aus Berlin
Christoph S.
Hallo zusammen,
bin zufällig auf diesen Thread gestoßen.
Ich verwende allerdings Perl.
Gibt es da ähnliche Probleme / einen thread dazu?
Gruß
Gerti
hallo,
Ich verwende allerdings Perl.
Gibt es da ähnliche Probleme / einen thread dazu?
Prinzipiell könnte es jemand auch bei Perl-Scripts probieren, und zwar mit denselben Methoden (habe ich bei den Perl-Scripts, die ich aktuell auch einsetze, aber nicht bemerken können bisher). Meines Wissens gibt es dazu bisher keinen Thread in diesem Forum.
Grüße aus Berlin
Christoph S.
Meines Wissens gibt es dazu bisher keinen Thread in diesem Forum.
Daraus schließe ich, dass in Perl das Problem nicht (oder nicht so gravierend) existiert.
Ich bleibe daher besser bei meinem Perl.
Gruß
Gerti
Hallo Gerti,
Meines Wissens gibt es dazu bisher keinen Thread in diesem Forum.
Daraus schließe ich, dass in Perl das Problem nicht (oder nicht so gravierend) existiert.
Vielleicht liegt es aber auch nur daran, dass es nicht so viele Perl-Benutzer gibt, die vom Programmieren keine Ahnung haben, bzw. dass Perl insgesamt weniger eingesetzt wird.
Ich bleibe daher besser bei meinem Perl.
Das ist kein Problem von PHP, sondern von Leuten, die Benutzereingaben nicht überprüfen, bevor sie irgendwelche weiteren Dinge damit anstellen.
Schöne Grüße,
Johannes
Hallo Forum,
Das ist kein Problem von PHP, sondern von Leuten, die Benutzereingaben nicht überprüfen, bevor sie irgendwelche weiteren Dinge damit anstellen.
Die Möglichkeit, zur Laufzeit Scripte von externen Servern einzubinden sind evil. allow_url_fopen sollte eigentlich immer aus sein, genau wie register_globals, short_tags. Und Variablen initialisiert man zwangsweise, wenn error_reporting auf E_ALL steht und display_errors an ist, letzteres nur in der Entwicklung, produktiv gibt es dafür error_log.
Gruß
Alexander Brock
Glück auf!
Habe nach dem Posting von Christoph das erste mal einen Blick in die Logs meines - seit etwa einem Jahr bestehenden - Webprojektes geworfen. Wirklich schlauer bin ich durch die Einsicht jetzt nicht. Ist es eurer Meinung nach erforderlich, dass ich mich informiere, was die Inhalte der Logs zu bedeuten haben und diese dann regelmäßig einsehe?
Freundliche Grüße
zwerg Alex
Morgen!
Habe nach dem Posting von Christoph das erste mal einen Blick in die Logs meines - seit etwa einem Jahr bestehenden - Webprojektes geworfen.
Das ist relativ spät, aber bei einem gemieteten Webspace denke ich, kann man das wohl verschmerzen. Die wirklich gravierenden Probleme wird der Webhoster auch selbst feststellen; er muss eigentlich davon ausgehen, dass seine Kunden "keine Ahnung" von der Server-Administration haben.
Wirklich schlauer bin ich durch die Einsicht jetzt nicht.
Warum nicht?
Du erkennst aus den Logs immerhin, wie stark deine Website überhaupt frequentiert wird, zu welchen Tageszeiten die meisten Zugriffe kommen, welche Seiten am häufigsten abgerufen werden - und auch, welche nicht existierenden Ressourcen angefordert wurden. Und gerade diese Einträge können hochinteressant sein, da sie oft erkennen lassen, dass da jemand rumstochert und nach losen Brettern im Zaun (i.e. Sicherheitslücken) sucht.
Ist es eurer Meinung nach erforderlich, dass ich mich informiere, was die Inhalte der Logs zu bedeuten haben und diese dann regelmäßig einsehe?
Erforderlich ... ? Hmmm, ich würde es dir zumindest wärmstens empfehlen.
Schönes Wochenende,
Martin
Hallo zwerg!
was die Inhalte der Logs zu bedeuten haben
Martin hat zu der Notwendigkeit eines regelmäßigen Nachschauens schon ausfürhlich geantwortet, ich knöpfe deswegen am ersten Teil Deiner Frage an.
Wichtig ist zu wissen, wie so genannten Access-Logs aufgebaut sind. Die gängige Formate sind das Common Log Format oder das »Extended Log Format«. Üblicherweise sieht eine Log-Zeile so aus:
IP-Adresse - - [15/Sep/2007:12:34:56 -0500] "GET /index.html HTTP/1.1" 200 2376 "Referrer" "User-Agent"
1. IP-Adresse dürfte klar sein
2. - aus diesem ersten Bindestrich (leerer Wert) werde ich nicht ganz schlau (vielleicht kann uns jemand das besser erklären)
3. - der zweite Bindestrich enthält dann einen Wert, wenn ein User über HTTP-Authentification Ressourcen anfordert, der Wert ist der Username
4. Datum/Zeit-Gruppe
5. Methode (z.B. GET oder POST), angeforderte Ressource, HTTP-Protokoll
6. Status-Code
7. Größe der Ressource in Bytes
8. Referrer (wenn übermittelt)
9. User-Agent (wenn übermittelt)
Einige Provider fügen Items hinzu, so ist bei meinem 1&1-Paket zusätzlich die angeforderte Domain/Subdomain zwischen Ressource-Größe (7.) und Referrer (8.) vermerkt und ganz am Zeilenende noch die IP-Adresse eines evtl. Proxy-Servers:
255.255.255.255 - - [15/Sep/2007:00:07:11 +0200] "POST http://selfspezial.atomic-eggs.com/cgi-bin/selfugb/ugb.pl?mod=write HTTP/1.1" 200 3312 selfspezial.atomic-eggs.com "http://selfspezial.atomic-eggs.com/selfugb.html" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50717)" "-"
1. IP-Adresse
2. -
3. User (hier: -, leer)
4. Datum/Zeit-Gruppe (hier: heute morgen um null Uhr sieben)
5. Methode (z.B. GET oder POST), angeforderte Ressource, HTTP-Protokoll
6. Status-Code (hier: 200, OK)
7. Größe der Ressource in Bytes (hier: 3312 Bytes)
8. Domain/Subdomain. (hier: selfspezial.atomic-eggs.com)
9. Referrer
10. User-Agent
11. Proxy (hier: leer)
Mit Hilfe einer serverseitigen Sprache wie Perl oder PHP kannst Du diese Logs auswerten und Dir gezielt bestimmte Infos anzeigen lassen.
Viele Grüße aus Frankfurt/Main,
Patrick
Re!
und ganz am Zeilenende noch die IP-Adresse eines evtl. Proxy-Servers:
» 11. Proxy (hier: leer)
Da hatte ich mich falsch ausgedrückt... Unter 1. ist die IP-Adresse des Proxys, unter 11. die IP des tatsächlichen anfordernden Rechners, wenn diese vom Proxy übermittelt (Auszug aus den 1&1-FAQ):
»Werden Webseiten nicht direkt vom eigenen Rechner aufgerufen, sondern über einen sogenannten Proxy, so wird von diesem eine Verbindung zu der gewünschten Webseite hergestellt und an den eigenen Rechner weitergegeben. Proxy-Server kommen z.B. an der Schnittstelle von Firmennetzwerken zum Internet, aber auch bei Zugangsprovidern zum Einsatz.
Der Proxy-Server fungiert dabei quasi als Stellvertreter, der die Seiten anfordert und an den Benutzer weiterleitet. Folglich steht im Logfile der aufgerufenen Präsenz dann aber die IP-Adresse des Proxys und nicht die Adresse des ursprünglich die Seite anfordernden Arbeitsplatzrechners.
Damit die Möglichkeit besteht, bei Zugriffen über Proxies nachzuvollziehen, woher eine Anfrage ursprünglich kam, schicken einige (!) Proxies im HTTP-Request (Seitenanfrage) ein Headerfeld namens 'X-Forwarded-For' mit, in dem dann die Ursprungs-IP eingetragen ist. Dieser X-Forwarded-For-Header wird neuerdings bei 1&1 WebHosting (sofern im Paket enthalten) ans Ende jedes Eintrags im Logfile angehängt.
In der Regel steht an diesem natürlich ein "-", weil der Zugriff nicht über einen Proxy erfolgte oder wenn ein Proxy diese Information nicht übermittelt. Bei Verwendung des 1&1 SSL Proxys (möglich ab dem Business Pro Paket oder bei den 1&1 E-Shops) sowie bei Proxy-Aufrufen, die die entsprechende Information übermitteln, steht übrigens die IP des tatsächlich anfordernden Rechners in der letzten Spalte jeder Logzeile. Damit verbessert sich die Möglichkeit, eine aussagekräftige Besucher-Statistik zu erstellen.«
Viele Grüße aus Frankfurt/Main,
Patrick
hallo Patrick,
Üblicherweise sieht eine Log-Zeile so aus: [...]
Freundlich erklärt, kriegst einen Pluspunkt. Ergänzend dazu ein kleiner Hinweis auf den entsprechenden Passus in meinem Artikel.
Grüße aus Berlin
Christoph S.
Glück auf Patrick!
Vielen lieben Dank für deine ausführliche und hilfreiche Antwort. Werd nun öfter mal einen Blick in die Logs werfen, sind ja doch ein paar interessante Infos dabei :-)
Dankeschön auch an Martin und Christoph für ihre Antworten.
Freundliche Grüße
zwerg Alex
Hallo,
Alles bisher Parameter, die ich sowieso nicht verwende, also kann eigentlich auch nichts passiert sein. Eigentlich - oder?
hat jemand einen Link auf eine Seite mit übersichtlichen aktuellen und
guten Tipps zu nötigen Sicherheitseinstellungen?
Bei meinem WAMP-Testserver scheint es per default möglich zu sein, mit
$HTTP_SERVER_VARS['PHP_SELF'] auszukommen, das liegt dann aber wohl an
register_long_arrays und nicht an register_globals?
Grüsse
Cyx23
hallo Cyx23,
hat jemand einen Link auf eine Seite mit übersichtlichen aktuellen und
guten Tipps zu nötigen Sicherheitseinstellungen?
Ich weiß nicht genau, was du mit Sicherheitseinstellungen meinst. Ich hatte es bei dem Provider, bei dem die Seite liegt, über .htacces bisher so versucht:
php_flag magic_quotes_gpc Off
php_flag register_globals Off
php_flag date.timezone Europe/Berlin
php_flag disable_classes Off
Da ich ja die php.ini nicht selbst ändern kann, hielt ich diesen Weg für sinnvoll, um die "problematischen" Vorgaben des Providers zu entschärfen.
Grüße aus Berlin
Christoph S.
Hallo Christoph,
php_flag magic_quotes_gpc Off
Bei schlampiger Programmierung kann das gefährlich werden - ich würde mal vermuten, dass einige Sicherheitslöcher durch diese Einstellung entschärft werden ...
php_flag date.timezone Europe/Berlin
php_flag ist (wie der Name schon sagt) für Flags, date.timezone ist aber ein String, hier sollte also php_value verwendet werden.
php_flag disable_classes Off
Mal abgesehen davon, dass disable_classes ein String ist (und damit php_value zu verwenden wäre): der Wert ist ausschließlich in der php.ini änderbar, mit einer .htaccess kannst du an der Einstellung nichts ändern.
Grüße aus Nürnberg
Tobias
hallo Tobias,
php_flag magic_quotes_gpc Off
Bei schlampiger Programmierung kann das gefährlich werden
Dessen war ich mir bewußt.
- ich würde mal vermuten, dass einige Sicherheitslöcher durch diese Einstellung entschärft werden ...
Und das will ich doch stark hoffen.
Ich will jetzt auf die beiden anderen Anmerkungen nicht näher eingehen - ich kann mich gut erinnern, daß ich vor rund einem Jahr, als ich an dieser Seite herumgebastelt habe, viel experimentieren mußte und die Angaben tatsächlich etwas bewirkt haben - obwohl sie, wie du richtig sagst, "eigentlich" nicht ganz korrekt sind. Abr ich kam damals mit php_value nicht weiter.
Vermutlich ist eben _auch_ von Bedeutung, welche PHP-Version der jeweilige Provider bereitstellt.
Grüße aus Berlin
Christoph S.
Moin!
php_flag magic_quotes_gpc Off
Bei schlampiger Programmierung kann das gefährlich werden - ich würde mal vermuten, dass einige Sicherheitslöcher durch diese Einstellung entschärft werden ...
Bei schlampiger Programmierung kann alles gefährlich werden. Aber magic_quotes_gpc richten bei unschlampiger Programmierung mehr Schaden an, als sie verhindern.
- Sven Rautenberg
hallo Sven,
Aber magic_quotes_gpc richten bei unschlampiger Programmierung mehr Schaden an, als sie verhindern.
Kannst du das begründen? Ich habe das damals hineingenommen aufgrund einer Fehlermeldung.
Grüße aus Berlin
Christoph S.
Moin!
Aber magic_quotes_gpc richten bei unschlampiger Programmierung mehr Schaden an, als sie verhindern.
Kannst du das begründen? Ich habe das damals hineingenommen aufgrund einer Fehlermeldung.
Zunächst mal: Quoting gibts ja nicht umsonst, sondern es erfordert eine gewisse Anzahl an CPU-Zyklen. Das wäre also der materielle Schaden. Außerdem muß man dieses Escaping zwingend rückgängig machen, um sein eigenes Escaping für die jeweils benötigte Aufgabe anwenden zu können. Also gleich doppelter Schaden.
Dann: Das magic_quotes_gpc erzeugt leider nur ein sehr generisches Quoting, dass gefährlicherweise für alle Aufgaben nur halb paßt. Dummerweise kennen dies aber nur darüber informierte Programmierer. Sprich: Das Resultat der Funktion addslashes(), welche von magic_quotes_gpc angewandt wird, sieht ohne genaues Hinsehen sehr ähnlich aus, wie die Resultate spezialisierter Escaping-Funktionen. Das Problem liegt aber gerade in den Zeichen, bei denen das Escaping abweicht, wodurch eventuell unerwünschter Code eingeschleppt werden kann.
Mit anderen Worten: Man muß sich explizit mit dem Rückgängigmachen der magic_quotes herumschlagen, weil man auf spezialisiertes Escaping nicht verzichten kann. Also haut man entweder ein Unescaping-Modul rein, oder deaktiviert die magic_quotes_gpc.
- Sven Rautenberg
hallo Sven,
Zunächst mal: Quoting gibts ja nicht umsonst, sondern es erfordert eine gewisse Anzahl an CPU-Zyklen.
Das ist richtig.
Das wäre also der materielle Schaden.
Wieso "materieller Schaden"? CPU-Beanspruchung bei einem Provider kann natürlich gemessen werden. Und der Provider verrechnet das selbstverstandlich mit seinem Angebot.
Außerdem muß man dieses Escaping zwingend rückgängig machen
Was ist nun der Unterschied zwischen "quoting" und "escaping"?
Dann: Das magic_quotes_gpc erzeugt leider nur ein sehr generisches Quoting
Einverstanden
, dass
<fußnote privat>
'tschuldigung, aber _hier_ kann ich nicht anders: wieso kannst du nicht mehr zwischen "das" und "dass" unterscheiden? Wir erleben es dutzendemale jeden Tag, daß es die "next generation" wirklich nicht mehr kann, weil sie von diversen Rechtschreibreformen während ihrer Schulzeit erheblich verunsichert wurde. Aber du bist nicht "next generation", sondern (gerade mal noch so) "my generation" und solltest zwischen "das" und "dass" unterscheiden können.
</fußnote privat>
gefährlicherweise für alle Aufgaben nur halb paßt.
Genau _das_ war meine Frage. Deine Erläuterung reicht mir nicht aus und wäre vermutlich auch im Sinn anderer Forumsleser noch zu vervollkommnen.
Dummerweise kennen dies aber nur darüber informierte Programmierer.
Ich weiß nicht, was ein "informierter Programmierer" für ein Typ ist. Ich selber verfüge mittlerweile über mehrere Jahre Übung, würde mich aber niemals als "Programmierer" oder gar "geübten Programmierer" bezeichnen. Du weißt doch: je mehr man von der Materie tatsächlich versteht und je mehr man geübt hat, desto mehr weiß man auch, was man eben noch nicht weiß - was du darzustellen versuchst (sofern ich es denn richtig kapiert habe), war mir aber schon vor einem Jahr bekannt, als ich aufgrund von Fehlermeldungen eben an "magic_quotas" herumzufummeln begonnen habe. Und um es deutlich auszusagen: ich bin keineswegs überzeugt, damit ein generell gültiges Konzept gefunden zu haben. Ich bekam lediglich deutlich weniger Fehlermeldungen, nachdem ich eben an den "magic_quotas" herumgemurkelt hatte.
Das Resultat der Funktion addslashes(), welche von magic_quotes_gpc angewandt wird, sieht ohne genaues Hinsehen sehr ähnlich aus, wie die Resultate spezialisierter Escaping-Funktionen. Das Problem liegt aber gerade in den Zeichen, bei denen das Escaping abweicht, wodurch eventuell unerwünschter Code eingeschleppt werden kann.
Dieser Hinweis ist allerdings wichtig.
Mit anderen Worten: Man muß sich explizit mit dem Rückgängigmachen der magic_quotes herumschlagen, weil man auf spezialisiertes Escaping nicht verzichten kann. Also haut man entweder ein Unescaping-Modul rein, oder deaktiviert die magic_quotes_gpc.
Aber diesem Hinweis resp. dieser Schlußfolgerung kann ich mich leider nicht wirklich anschließen.
Grüße aus Berlin
Christoph S.
Hallo Christoph ,
Ich weiß nicht genau, was du mit Sicherheitseinstellungen meinst.
zunächst empfehlenswerte sicherheitsrelevante Einstellungen durch Einträge
in der php.ini.
Ich hatte es bei dem Provider, bei dem die Seite liegt, über .htacces bisher so versucht:
php_flag magic_quotes_gpc Off
php_flag register_globals Off
php_flag date.timezone Europe/Berlin
php_flag disable_classes OffDa ich ja die php.ini nicht selbst ändern kann,
Stimmt, das ist oft nicht möglich. Um so interessanter, wenn es Alternativen
per .htaccess gibt.
Grüsse
Cyx23
Hallo Cyx23,
hat jemand einen Link auf eine Seite mit übersichtlichen aktuellen und
guten Tipps zu nötigen Sicherheitseinstellungen?
Einen Link habe ich leider nicht parat, aber die c't hat neulich einen guten Artikel zum Thema PHP und sichere php.ini-Einstellungen gemacht.
Unter anderem sind die folgenden Einstellungen empfehlenswert:
<snip>
; verhindert, dass externe URLs über fopen geöffnet werden können - braucht
; man meistens sowieso nicht und bietet Angreifern eine einfache Möglichkeit,
; Schadcode nachzuladen
allow_url_fopen = Off
; Ab PHP 5.2.0: Verhindert das Einbinden von externem PHP-Code
allow_url_include = Off
; Der Klassiker
register_globals = Off
; Hiermit werden Funktionen deaktiviert, die man meist nicht braucht und Angreifern
; das Leben viel leichter machen können
disable_functions = exec,system,passthru,shell_exec,escapeshellcmd,proc_open,proc_nice,ini_restore,popen
</snip>
Falls jemand weitere Vorschläge hat - die Liste ist natürlich noch nicht vollständig. :-)
Jedoch ist diese Konfiguration ein guter Start für einen sichereren Server.
Ich fände es wünschenswert, wenn mit PHP 6 alle zweifelhaften Funktionen standardmäßig (php.ini) deaktiviert sind, und man sie einfach durch Editieren der php.ini aktivieren kann.
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo Marc,
Falls jemand weitere Vorschläge hat - die Liste ist natürlich noch nicht vollständig. :-)
Jedoch ist diese Konfiguration ein guter Start für einen sichereren Server.
danke, ist doch schonmal was!
Sonst fällt mir erstmal auf die Schnelle noch ein, ggf. mit Mitteln wie
strip_tags() möglichst gründlich zu filtern.
Optimal ist es aber wohl, wenn schon vorher die größten Risiken verläßlich
ausgeschaltet sind.
Grüsse
Cyx23
Moin!
Sonst fällt mir erstmal auf die Schnelle noch ein, ggf. mit Mitteln wie
strip_tags() möglichst gründlich zu filtern.
Strip_tags() hilft dir in der Regel gar nichts.
Escaping sollte zum selbstverständlichen Handwerkszeug gehören, das realisiert man aber nicht mit strip_tags() - sondern abhängig davon, wohin man die Ausgabe realisiert, mit der passenden Escaping-Funktion:
Ausgabe in HTML: htmlspecialchars()
Ausgabe in MySQL: mysql_real_escape_string()
Ausgabe auf die Shell: escapeshellarg() et al.
usw...
- Sven Rautenberg
Hallo,
vielleicht müßte analysiert werden, wo Code hereinkommen kann, und
wie er -möglichst einfach- behandelt werden kann.
Eingabefelder, übergebene Parameter, abgefragte Eigenschaften, womöglich
auch was vom Browser, Useragent für Weichen (jetzt erstmal unabhängig davon
wie sinnvoll sowas ist), referrer; u.U gibts noch mehr Möglichkeiten?
Grüsse
Cyx23
Moin!
vielleicht müßte analysiert werden, wo Code hereinkommen kann, und
wie er -möglichst einfach- behandelt werden kann.
Bei was?
Automatisch kommt "Code", d.h. fremddefinierte Datenmenge, nur über die Variablen mit $_CAPSLOCK ins Skript hinein.
Alle anderen Quellen müssen vom Skript explizit angezapft werden (Datenbanken, Dateien, etc.).
Eingabefelder, übergebene Parameter, abgefragte Eigenschaften, womöglich
auch was vom Browser, Useragent für Weichen (jetzt erstmal unabhängig davon
wie sinnvoll sowas ist), referrer; u.U gibts noch mehr Möglichkeiten?
Das sind alles Werte aus $_CAPSLOCK-Variablen.
Die darin befindlichen Werte sind innerhalb dieser Variablen ungefährlich. Die Gefahr kommt erst dann, wenn diese Werte für irgendeine Ausgabe verwendet werden sollen. An diesem Punkt ist Escaping zwingend erforderlich.
- Sven Rautenberg
Hallo Sven,
Das sind alles Werte aus $_CAPSLOCK-Variablen.
Die darin befindlichen Werte sind innerhalb dieser Variablen ungefährlich. Die Gefahr kommt erst dann, wenn diese Werte für irgendeine Ausgabe verwendet werden sollen. An diesem Punkt ist Escaping zwingend erforderlich.
vielleicht sollten die von dir verwendeten Begriffe erst mal geklärt werden?
Zu $_CAPSLOCK finde ich bei Google zuwenig, zu Escaping leider zu viel um da
auf die Schnelle was passendes zu finden oder zu verlinken/posten.
Mit Escaping meinst du wohl das (automatische) auskommentieren bestimmter
Zeichen per Backslash, damit Eingaben nicht unbeabsichtigt als Script
ausgeführt werden, statt irgendwelche Filter zu versuchen?
Ansonsten kommt es mir eigentlich übersichtlicher vor, solche o.g. Variablen
möglichst früh einmal zu bearbeiten.
Grüsse
Cyx23
Moin!
vielleicht sollten die von dir verwendeten Begriffe erst mal geklärt werden?
Zu $_CAPSLOCK finde ich bei Google zuwenig,
$_GET, $_POST, $_SERVER, $_COOKIES, $_FILES, $_ENV - was haben alle diese Variablennamen gemeinsam? Nutzt du PHP so wenig, dass dir die Zusammenfassung als $_CAPSLOCK entgangen ist?
Mit Escaping meinst du wohl das (automatische) auskommentieren bestimmter
Zeichen per Backslash, damit Eingaben nicht unbeabsichtigt als Script
ausgeführt werden, statt irgendwelche Filter zu versuchen?
Man muß es generischer formulieren, weil es generischer funktioniert. Denn nicht immer ist der Backslash das Escape-Zeichen. Escaping im HTML-Kontext bedeutet beispielsweise, dass das Zeichen < als Entity < ausgegeben wird - also frei von irgendeinem Backslash.
Escaping ist der Vorgang, der einen Textstring (im Kontext "Text") beim Übergang in einen anderen Kontext (Beispiele: HTML, SQL, Kommandozeile) so behandelt, dass in diesem neuen Kontext seine ursprüngliche Textbedeutung erhalten bleibt und keinerlei Bedeutungen des neuen Kontextes aktiv werden können. Das Zielsystem versteht also den Text weiterhin komplett als Text. Und da Text keine Gefahr darstellt, ist man sicher.
Ansonsten kommt es mir eigentlich übersichtlicher vor, solche o.g. Variablen
möglichst früh einmal zu bearbeiten.
Nein, das ist ja gerade das gefährliche daran.
Gefährlicher Code muß gefährlich aussehen. Ungefährlicher Code muß ungefährlich aussehen. Nur wenn man diese optische Differenzierung lernt zu programmieren und beim Debugging dann ausnutzt, macht man sich das Leben wirklich leichter.
Ein Beispiel. Eine lange PHP-Datei, mit mehreren Includes in anderen Dateien. Du hast den größten Teil des Codes nicht selbst geschrieben. Irgendwo mittendrin eine Ausgabe:
echo "<p>Ihr Name: ".$name."</p>";
Preisfrage: Besteht hier die Gefahr von HTML-Cross-Site-Skripting?
Antwort: Ja! Die einzige Sicherheit gegen Skripting besteht darin, dass irgendwoanders im Code eine Prüfung vorgenommen wurde, die verhindert, dass $name mit "bösen Zeichen" verschmutzt wird.
Dasselbe Stückchen Code nochmal anders:
echo "<p>Ihr Name: ".htmlspecialchars($name)."</p>";
Preisfrage: Besteht hier die Gefahr von HTML-Cross-Site-Skripting?
Antwort: Absolut NEIN! Egal was in $name drinsteht oder durchgelassen wird.
Das erste Codebeispiel muß man als "gefährlich" optisch speichern. Die Ausgabe einer Variablen ohne drumherumgelegte Escaping-Funktion sollte einem Gänsehaut und aufgerollte Zehennägel bescheren.
Das zweite Codebeispiel hingegen ist absolut sicher, was auch immer passiert.
- Sven Rautenberg
Hallo Sven,
$_CAPSLOCK ist mir nicht in Erinnerung, vielleicht nutze ich PHP zuviel oder
schon zu lange?
Dasselbe Stückchen Code nochmal anders:
echo "<p>Ihr Name: ".htmlspecialchars($name)."</p>";
Bislang habe ich solche Variablen eher möglichst früh bearbeitet (wenn es sich
anbot auch über eine Funktion), und dann als Kennung anders bezeichnet.
Entspr. deinem Beispiel würde es wohl so ausschauen:
~~~php
$sauber_name = htmlspecialchars($name);
echo "<p>Ihr Name: ".$sauber_name."</p>";
Grüsse
Cyx23
Hi,
Bislang habe ich solche Variablen eher möglichst früh bearbeitet (wenn es sich
anbot auch über eine Funktion), und dann als Kennung anders bezeichnet.Entspr. deinem Beispiel würde es wohl so ausschauen:
$sauber_name = htmlspecialchars($name);
echo "<p>Ihr Name: ".$sauber_name."</p>";
>
Schön und gut. Aber nimm nochmal Svens Beispiel (Du kennst nicht den ganzen Code).
Das macht das "Aussehen", wie Sven sich ausdrückt, von
~~~php
echo "<p>Ihr Name: ".$sauber_name."</p>";
nicht sicherer, nur weil da ein "sauber" im Namen ist. Du weißt nicht, bzgl. welchen
Kontextes dieser Wert denn nun sauber ist. Vielleicht stand ja ein mysql_real_escape_string
davor...
Und meistens brauchst Du Variableninhalte ja auch in mehreren Kontexten.
LG
Hallo
$_CAPSLOCK ist mir nicht in Erinnerung, vielleicht nutze ich PHP zuviel oder
schon zu lange?
Ich kannte es bisher auch nicht. Allerdings war mir die bedeutung gerade im Zusammenhang dieses Threads sofort klar, als ich den Begriff bei Sven las.
Bislang habe ich solche Variablen eher möglichst früh bearbeitet (wenn es sich
anbot auch über eine Funktion), und dann als Kennung anders bezeichnet.Entspr. deinem Beispiel würde es wohl so ausschauen:
Aber doch erst dann, wenn es relevant ist, oder? Sprich: mysql_real_escape_string()
, wenn es um den Eintrag in eine MySQL-Datenbank geht oder htmlspecialchars()
, wenn es zur HTML-Ausgabe kommen soll. Oder verstehe ich dich da falsch?
Tschö, Auge
Hallo,
Allerdings war mir die bedeutung gerade im Zusammenhang dieses Threads sofort klar, als ich den Begriff bei Sven las.
sicher mag das mehr oder weniger nachvollziehbar sein. Aber ohne entspr.
Vereinbarung und dazu hier in einem Forum m.E. nicht so geeignet?-)
Aber doch erst dann, wenn es relevant ist, oder? Sprich:
mysql_real_escape_string()
, wenn es um den Eintrag in eine MySQL-Datenbank geht oderhtmlspecialchars()
, wenn es zur HTML-Ausgabe kommen soll. Oder verstehe ich dich da falsch?
Das würde dann womöglich zwei Varianten erfordern, a la "sauber_html_.." und
"sauber_sql_..". Gleich für alle Variablen alle denkbaren Varianten
vorsorglich zu erzeugen wäre vielleicht doch etwas aufwändig, trotzdem kommt
mir eigentlich eine Stelle für solche Schritte übersichtlicher vor.
Andere Umwandlungen etwa wegen UTF-8 oder Sonderzeichen für URIs usw.
sind wohl auch öfters nötig. Ob sich daraus auch folgern läßt, doch besser
alles dezentral nur nach Bedarf und dann ggf. mehrfach durchzuführen?
Grüsse
Cyx23
Hallo
Das würde dann womöglich zwei Varianten erfordern, a la "sauber_html_.." und
"sauber_sql_..". Gleich für alle Variablen alle denkbaren Varianten
vorsorglich zu erzeugen wäre vielleicht doch etwas aufwändig, trotzdem kommt
mir eigentlich eine Stelle für solche Schritte übersichtlicher vor.
Ich nehme dafür eine Stelle vor bzw. am Beginn des Abschnitts, in dem die entsprechende Maskierung notwendig ist.
Andere Umwandlungen etwa wegen UTF-8 oder Sonderzeichen für URIs usw.
sind wohl auch öfters nötig. Ob sich daraus auch folgern läßt, doch besser
alles dezentral nur nach Bedarf und dann ggf. mehrfach durchzuführen?
Mein Ansatz wäre (in etwa) "dezentral zentral". Alles zu seiner Zeit (dezentral), dann aber gleich alle betroffenen Variablen (zentral).
... sozusagen, das Ganze.
Tschö, Auge
echo $begrüßung;
Ich nehme dafür eine Stelle vor bzw. am Beginn des Abschnitts, in dem die entsprechende Maskierung notwendig ist.
Das heißt, du legst extra eine neue Variable an, mit dem geänderten Wert, auf die du dann (in den vermutlich meisten Fällen) nur einmal zugreifst?
$var1_esc = escape($var1);
(alle Beispiele in Pseudocode)
Oder änderst du die bestehende Variable, so dass deren Inhalt für andere Zwecke quasi wertlos geworden ist (nicht immer gibt es eine eindeutige Umkehrfunktion)?
$var1 = escape($var1);
Mein Ansatz wäre (in etwa) "dezentral zentral". Alles zu seiner Zeit (dezentral), dann aber gleich alle betroffenen Variablen (zentral).
Also im Prinzip so, und von der zweiten der obigen Variante ausgehend:
$table = escape($table);
$var1 = escape($var1);
$var2 = escape($var2);
$var3 = escape($var3);
$var4 = escape($var4);
...
$sql = "INSERT INTO $table (col1,col2,col3,col4,eingefügt) VALUES " .
"($var1,$var2,$var3,$var4,$vergessen)";
Auch bei dieser Vorgehensweise muss man sich (unnötigerweise) merken, dass eine Bearbeitung bereits stattgefunden hat, auch wenn das nur wenige Zeilen weiter oben geschieht. Und vor allem muss man es auch sicherstellen. Was ist, wenn du "unten" etwas ergänzen willst, und im Eifer des Gefechts vergisst, "oben" die Bearbeitung einzufügen? Ist es nicht wesentlich auffälliger, wenn stattdessen bei einer Anzahl von mit Escape-Funktionen eingefügten Variablen plötzlich eine solo dasteht?
$sql = sprintf("INSERT INTO %s (col1,col2,col3,col4,eingefügt) VALUES (%s,%s,%s,%s,%s)",
escape($table),
escape($var1),
escape($var2),
escape($var3),
escape($var4),
$vergessen);
echo "$verabschiedung $name";
Hallo
Ich nehme dafür eine Stelle vor bzw. am Beginn des Abschnitts, in dem die entsprechende Maskierung notwendig ist.
Das heißt, du legst extra eine neue Variable an, mit dem geänderten Wert, auf die du dann (in den vermutlich meisten Fällen) nur einmal zugreifst?
$var1_esc = escape($var1);
(alle Beispiele in Pseudocode)
Oder änderst du die bestehende Variable, so dass deren Inhalt für andere Zwecke quasi wertlos geworden ist (nicht immer gibt es eine eindeutige Umkehrfunktion)?
$var1 = escape($var1);
Meist verwende ich die letztere Möglichkeit. Da ich das aber innerhalb von Funktionen mache, entwerte ich den String in der ursprünglichen Variable nicht.
function funktion_zum_sql_inserten($var) {
global ...;
$sql = funktion_zum_verbindungsaufbau();
if ($sql===false)
{
# Fehler
$r = false;
}
else
{
# Maskierungen und weitere eventuelle Aufbereitungen
$var = mysql_real_escape_string($var);
$frage = "INSERT INTO tabelle (eintrag) VALUES '".$var."'";
$r = funktion_zur_abfrage_und_ausgabe($frage,$sql);
}
return $r;
} # Ende: funktion_zum_sql_inserten($var1)
$var1 = "String mit allerhand Text.";
$sql_return = funktion_zum_sql_inserten($var1);
Auch bei dieser Vorgehensweise [Version 2] muss man sich (unnötigerweise) merken, dass eine Bearbeitung bereits stattgefunden hat, auch wenn das nur wenige Zeilen weiter oben geschieht. Und vor allem muss man es auch sicherstellen. Was ist, wenn du "unten" etwas ergänzen willst, und im Eifer des Gefechts vergisst, "oben" die Bearbeitung einzufügen? Ist es nicht wesentlich auffälliger, wenn stattdessen bei einer Anzahl von mit Escape-Funktionen eingefügten Variablen plötzlich eine solo dasteht?
Ja, die Gefahr ist gegeben. Dem kann ich auch nichts als ein "Da muss ich halt aufpassen." entgegenhalten. Und ich weiß, dass das nicht wirklich überzeugend klingt.
Tschö, Auge
Moin!
Das würde dann womöglich zwei Varianten erfordern, a la "sauber_html_.." und
"sauber_sql_..". Gleich für alle Variablen alle denkbaren Varianten
vorsorglich zu erzeugen wäre vielleicht doch etwas aufwändig, trotzdem kommt
mir eigentlich eine Stelle für solche Schritte übersichtlicher vor.
Zugegeben, sofern du oben im Skript aus $_POST[xy] eine Variable $sauber_html_xy machst, kannst du dieser dann natürlich auch in
echo $sauber_html_xy;
ansehen, dass sie anscheinend behandelt wurde.
Aber Programmierung besteht ja nun nich nur aus Hauptprogramm, sondern hat auch Funktionen, denen Parameter übergeben werden. Manche Funktionen erzeugen dann auch Ausgaben, ins HTML oder ins SQL oder sonst wohin.
Das bedeutet: Du muß sowohl sicherstellen, dass du in jedem Fall die Variable $sauber_html_xy in deinen Funktionsparameter steckst, und nicht aus Versehen doch $_POST[xy], und du mußt innerhalb deiner Funktion natürlich die Namensbezeichnung beibehalten, um zu kennzeichnen, dass die Variable als sauber zu gelten hat.
function whatever($sauber_html_param) {...}
Dann hast du aber wieder, oder eigentlich erst richtig, das Problem, dass du eine spezialisiert escapte Variable in der Funktion hast, die für keine andere Verwendung mehr nutzbar ist.
Mal angenommen, du schreibst dir ein Datenbank-Backend. Der Funktion zum Schreiben in die DB übergibst du vorgefertigt escapte Strings.
Und dann schreibst du noch ein Backend zur Speicherung in Flatfiles. Das kann mit dem DB-Escaping absolut nichts anfangen. Die zwei Backends sind also nicht austauschbar. Ganz schlechte Idee also. :)
Und noch eines ist relevant: Um mysql_real_escape_string() anwenden zu können, muß mindestens eine Datenbankverbindung _bestehen_, denn das Escaping orientiert sich an der für diese Verbindung vereinbarten Zeichencodierung. Es ist nun zwar nicht ungewöhnlich, dass ein Skript direkt zum Start die DB verbindet, aber so rein von einer vernünftigen Programmlogik her gesehen wäre es doch wahrscheinlicher, dass eher ein Singleton verwendet wird, so dass die DB-Verbindung erstmalig erst beim ersten db-relevanten Methodenaufruf hergestellt wird. Folglich kannst du vor diesem Zeitpunkt noch gar kein Escaping durchführen.
Abgesehen davon halte ich es für Speicherverschwendung, wenn man Daten mehr oder weniger sinnlos im Vorraus dupliziert, nur falls sie mal gebraucht werden könnten. Das führt nur zu Problemen bei der Verarbeitung, weil Änderungen an dem einen String natürlich auch im anderen String nachgeführt werden müßten.
Andere Umwandlungen etwa wegen UTF-8 oder Sonderzeichen für URIs usw.
sind wohl auch öfters nötig. Ob sich daraus auch folgern läßt, doch besser
alles dezentral nur nach Bedarf und dann ggf. mehrfach durchzuführen?
Aber sicher läßt sich sowas folgern. Im Vorraus weißt du, dass du eigentlich alle denkbaren Escaping-Varianten irgendwo mal gebrauchen könntest. Aber erst wenn wirklich eine gebraucht wird, hast du Gewißheit. Warum aber für alle Fälle Escaping vorproduzieren, wenn es sich "on-demand" durch Funktionsaufruf herstellen läßt?
- Sven Rautenberg
echo $begrüßung;
Zu $_CAPSLOCK finde ich bei Google zuwenig,
$_GET, $_POST, $_SERVER, $_COOKIES, $_FILES, $_ENV - was haben alle diese Variablennamen gemeinsam? Nutzt du PHP so wenig, dass dir die Zusammenfassung als $_CAPSLOCK entgangen ist?
Kleine Ergänzung: Im PHP-Jargon werden diese auch als EGPCS-Variablen bezeichnet. EGPCS ist der Default-Wert für variables_order. ($_SESSION und $_REQUEST ist in der Aufzählung nicht enthalten. $_REQUEST ist nur eine Zusammenfassung und $_SESSION wird erst bei session_start() angelegt, also nicht zusammen mit den EGPCS-Variablen behandelt.)
echo "$verabschiedung $name";
Hallo nochmals,
disable_functions = exec,system,passthru,shell_exec,escapeshellcmd,proc_open,proc_nice,ini_restore,popen
einen weiteren Kandidaten für disable_functions habe ich noch: eval().
Die Funktion braucht man meist überhaupt nicht und kann ebenso dazu genutzt werden, PHP-Code einzuschleusen.
Hat noch jemand Funktionen parat, die man gerne sperren möchte?
Vielleicht können wir ja eine schöne PHP-Security-Default-Config erstellen... :-)
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo,
Vielleicht können wir ja eine schöne PHP-Security-Default-Config erstellen... :-)
vielleicht findet sich ja mal jemand und schreibt einen kompakten und doch
hinreichend umfassenden Artikel zum Thema PHP-Sicherheit.
Bei den möglichen Auswirkungen unsicherer Scripte und angesichts der engen
Verflechtungen von PHP und HTML wäre sowas bei SelfHTML doch recht gut
untergebracht.
Ansonsten nochmal der Link bzw. http://de.php.net/manual/de/security.php
Grüsse
Cyx23
Hallo Cyx23,
Vielleicht können wir ja eine schöne PHP-Security-Default-Config erstellen... :-)
vielleicht findet sich ja mal jemand und schreibt einen kompakten und doch
hinreichend umfassenden Artikel zum Thema PHP-Sicherheit.
Bei den möglichen Auswirkungen unsicherer Scripte und angesichts der engen
Verflechtungen von PHP und HTML wäre sowas bei SelfHTML doch recht gut
untergebracht.
Lust, einen solchen Artikel zu schreiben, hätte ich auf jeden Fall. :-)
Mal sehen, ob ich in den nächsten Wochen Zeit dazu bekomme...
Grüße
Marc *<I>* Reichelt || http://www.marcreichelt.de/
echo $begrüßung;
hat jemand einen Link auf eine Seite mit übersichtlichen aktuellen und
guten Tipps zu nötigen Sicherheitseinstellungen?
Die wichtigte Einstellung zum Thema Sicherheit kann man nicht verlinken, denn das ist die, die man selbst haben sollte. Und sie sollte von der viel zu häufig vorkommenden Einstellung "Ich habe keine Ahnung und auch keine Lust/Zeit, mich damit zu beschäftigen." deutlich abweichen.
Alles andere steht im Kapitel Security des PHP-Handbuchs.
echo "$verabschiedung $name";