• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Files ueber URL inkludieren - Wie? Gefahren?

Status
Für weitere Antworten geschlossen.

raphaelp

Neues Mitglied
Achtung, dieses Tutorial wurde aktualisiert und ist jetzt Teil der FAQ :
http://www.html.de/fpost58456.html#58456


Da in diesem forum oft das selbe gefragt wird, wir fuer diese frage aber nur mehrere halbfertige Threads zur verfuegung stellen, habe ich diesen Thread fuer eine einfuehrung in die Methodik der inkludierung von dateien ueber die URL geschrieben. Folgendes fallbeispiel:

Ich habe ne Seite mit 4 dateien, kontakt.php - news.php - haupt.php - index.php, und will nun ueber die index.php, welche mein Template enthaelt, moeglichst sicher und wartungsarm die haupt.php, news.php und kontakt.php inkludieren, und zwar ueber die URL.

Wie man es nicht machen sollte

Meistens wird dies ueber PHP Switch geloest, doch hier erstmal der grund weshalb man diesen ganzen aufwand betreibt. Man koennte ja eigentlich auch einfach nur sagen:

  • index.php?datei=kontakt.php oder
    index.php?datei=news.php oder
    index.php?datei=haupt.php
und schon waere das problem durch einen ein-zeiler geloest:

Code:
<?php
include $_GET['datei'];
?>

naja, wenn das leben bloss so schoen waere: Dadurch kann ein "Hacker" einfach auch folgendes eingeben:

index.php?datei=/etc/passwd

und schon kann unter umstaenden dem Angreiffer wichtige information ueber dein System gegeben werden. Jetzt gaebe es z.b. noch die moeglichkeit:

index.php?datei=haupt

und ueber

Code:
<?php
include($_GET['datei'].".php");
?>

das ganze auf dateien mit der endung .php zu beschraenken. Jedoch kann unter umstaenden passieren, dass wenn PHP skripte an falschen stellen inkludiert werden, auch wichtige informationen ueber ein system preisgeben. Deshalb werden BEIDE methoden NICHT EMPFOHLEN!. Eine sichere methode waere ein sogenannter PHP Switch

Die Lösung mit switch

index.php?datei=kontakt

und das PHP Skript dazu:

Code:
<?php
switch ($_GET['datei']) {
	case "kontakt": 
		include 'kontakt.php';
		break;
	case "news":
		include 'news.php';
		break;
	// ... mehrere dateien in der selben art anreihen
	
	// die standard datei
	default: 
		include 'haupt.php';
}
?>

jetzt ist es hier aber so, dass sowas ziemlichen aufwand bedeutet, wenn du mehrere dateien hinzufuegen willst (du muesstest ja immer wieder das selbe tippen - NICHT EFFIZIENT). Deshalb hier 2 effizientere methoden:

Auf ein Verzeichnis beschränken

Indem du das include auf ein verzeichnis beschraenkst, aus dem der besucher nicht "ausbrechen" kann - somit kannst du dort alle zu inkludierenden dateien rein tun, und bist hiermit abgesichert. Beispiel: Deine dateien sind wie folgt abgespeichert:

  • index.php
    include\kontakt.php
    include\haupt.php
    include\news.php
Jetzt kannst du ueber index.php?datei=kontakt und dem folgenden PHP code sicher inkludieren:

Code:
<?php
// den besucher im aktuellen Verzeichnis "einsperren":
include 'include/' . basename($_GET['datei']) . '.php';
?>


Eine andere, und meine persoenliche lieblingsmethode ist eine umschreibung, bzw. reduzierung eines switches auf einen array. klingt jetzt mega-kompliziert, aber ist viel einfacher als alles andere :)

Reduzierung auf ein Array

index.php?datei=kontakt

und das PHP skript dazu:

Code:
<?php
// hier kann man beliebig viele dateien anhaengen!
// die standard-seite ist an erster stelle.
$whiteList = array('haupt','news','kontakt'); 

if (in_array($_GET['datei'],$whiteList)) {
 include $_GET['datei'].'.php';
}
else {
 include $whiteList[0].'php';
}
?>

Das prinzip einer sogenannten "White-List" (http://de.wikipedia.org/wiki/Whitelist) ist hier besonders effizient und bedienerfreundlich angewendet. Wenn ich eine seite mit 200 zu inkludierenden dateinamen habe, muss ich nur jedes mal den dateinamen in die array schreiben, nicht das ganze 'case "dateiname"' ... usw usw. Die zwei zeilen darunter bleiben bestehen, und muessen nicht erweitert werden.

So, das war's, hoffe der thread bringt einigen was.

PS: waere dir dankbar cracki wennde den sticky machen koenntest oder so, hab mir so viel muehe gegeben! :D

Anmerkungen
1) Falls keinerlei php code "includiert" werden soll bietet sich die Benutzung von readfile() [ www.php.net/readfile ] an um Sicherheitslücken zu vermeiden.

2) Die Lösung mit den Arrays lässt sich noch aufbohren:
Code:
<?php
// hier kann man beliebig viele dateien anhaengen!
// die standard-seite ist an erster stelle.
$whiteList = array(
    'haupt' => '../includes/data/main.content',
    'news' => '../includes/database/news.php',
    'kontakt' => '../includes/static/contact.content'
); 
if(array_key_exists('datei', $_GET)) {
  if (array_key_exists($_GET['datei'],$whiteList)) {
    include $whiteList[$_GET['datei']];
  }
  else {
    include $whiteList['haupt'];
  }
}
else {
    include $whiteList['haupt'];
}
?>

MOD-EDIT: [ php ] tags durch [ code ] ersetzt wegen fehler des forums & Anmerkungen
 
Werbung:
Ich verwende folgendes System: (Hab ich aus einem Tutorial)
[php:1:504a5d6039]<?php
// Die Konfigurationsdatei:
$inhalt['home'] = 'index.php'
$inhalt['test'] = "test/test.php'
// Weitere Einträge möglich

?>[/php:1:504a5d6039]

Und in der Datei, in der die Sektion abgefragt wird steht folgendes:
[php:1:504a5d6039]
<?php
// Der Inhalt der Seite
if(isset($_GET['section']) AND isset($inhalt[$_GET['section']])) {
include $inhalt[$_GET['section']];
} else {
include $inhalt['home'];
}
?>
[/php:1:504a5d6039]

Das kann man auch für Sidebars, usw. machen. Und wenn man neue Seite hinzufügt, muss man sie nur in die config.php eintragen
 
Werbung:
ist genau derselbe code wie mein letzter code (von der funktion her), ausser dass du den namen dort 2x schreiben musst :)
 
Ich finde halt, dass es komfortabler ist, die Seiten in eine config datei einzutragen, als in einen switch..case block. Aber das Ergebniss ist bei beiden Skripten gleich, da hast du recht! :mrgreen:
 
<?php
// hier kann man beliebig viele dateien anhaengen!
// die standard-seite ist an erster stelle.
$whiteList = array('haupt','news','kontakt');

if (in_array($_GET['datei'],$whiteList)) include($_GET['datei'].".php");
else include($whiteList[0]."php");
?>

du kannst die whitelist hier genauso in eine konfigurationsdatei auslagern, und diese dann inkludieren. das ist aber nicht bestandteil meiner aussage gewesen, das waere dann ein neuer thread: "Wie lagere verdopplungen aus?" aber darueber habe ich schon eine nervenraubende diskussion hinter mir, und bis das hier mal einer wirklich checkt hab ich gar keine haare mehr auf'm kopf :|
 
Werbung:
Vllt hab ich ja was falsch gemacht aber das glaube ich nicht...
Ich habe deinen Code hergenommen aber ich bekommen ne fehlermeldung
[qoute]
Warning: main(.php) [function.main]: failed to open stream: No such file or directory in C:\apachefriends\xampp\htdocs\htdocs\legatio-mortis\index.php on line 224

Warning: main() [function.include]: Failed opening '.php' for inclusion (include_path='.;c:\apachefriends\xampp\php\pear\') in C:\apachefriends\xampp\htdocs\htdocs\legatio-mortis\index.php on line 224
[/quote]
Und hier der Code:
PHP:
<?php
$whiteList = array('News','Member','Lan','Downloads','About','Links','Impressum','Joined','Einloggen','Ausloggen','Newspost','Posted','Join-us','Member-Edit','Added','Edited','Voting');
if (in_array($_GET['Section'],$whiteList)) include($_GET['datei'].".php");
else include($whiteList[0]."php"); 
?>
Edit:
Ich haber vergessen das 2. GET zu ändern
Edit:
Hmm geht irgendwie immer noch nich...
 
@CrackPod wie rufst du denn die file auf? Bitte beruecksichtigen dass die dateien case-sensitiv sind, also Downloads != downloads !! Wenn du jetzt also die datei "downloads.php" inkludieren willst, dann schreibst du "downloads" in die whiteList array.
 
Werbung:
ja ich hatte ein anderes Problem...
Nämlich dass die dateien in einem anderem ordner waren...
Habe es schon gelöst...
Sry wegen dummer frage...
 
ich weis nicht ob da hier schon steht wenn ja sry wegen dem post aber ic hab das immer mit frames bis jetzt gemacht will jetzt auch PHP SWITCH nehmen weil das geht ja auch im internet explorer
wie mache ich denn das desing darein dann???
VG T-sneak
 
Werbung:
jaja schon aber ich meine wie soll ich das design machen auch includen??
oder soll ich das so machen in die index.php datei rein


Code:
<style type="text/css">
<!--

body {
	background-image: url(menu.jpg); 
	background-repeat:repeat; 
	background-attachment:fixed
}

* { 
	margin: 0px 0px 0px 0px; 
}

.over {
	font-family: Verdana, Arial, Helvetica, sans-serif; 
	text-align: center
}

.text, td {
	font-family: Verdana, Arial, Helvetica, sans-serif; 
	font-size: 15px; 
}

.err2 {
	font-family: Verdana, Arial, Helvetica, sans-serif; 
	font-size: 15px; 
	color: red;
	font-weight: bold;
}

.link {
	font-family: Verdana, Arial, Helvetica, sans-serif; 
	font-size: 15px; 
	font-weight: bold; 
}

.err {
	font-size: 4px; 
}

.bereich {
	font-family: Verdana, Arial, Helvetica, sans-serif; 
	font-size: 13px; 
	color:#FFFFFF;  
	font-weight:bold
}

a:link {
	color: #FF0000;
}

a:visited {
	color: #FF0000;
}

a:hover {
	color: #FFcc33;
}

a:active {
	color: #FFFFFF;
}

hr {
	color:#FFFFFF; size:3; 
}

input { 
	width:100px; border-style:solid; 
	border-color:#FFFFFF; 
	border-width:2px; 
	font-weight:bold 
}


-->
</style>

HIER DANN DIE INCLUDES REIN
 
ich habe einfach eine index site, bei der mehrere teili includet werden...
der mittel-teil-include-code ( :mrgreen: ) sieht folgendermasssen aus:
[php:1:0e40f0b7e4]<?php
if(file_exists("haupt/" . $seite . ".php")) {
include "haupt/" . $seite . ".php";
} else {
include "haupt/404.php";
}
?>[/php:1:0e40f0b7e4]
 
Werbung:
warum eig so kompiziert? ich mach das immer so
[php:1:5b5f3bc776]
<?php
if($_GET[action]=="pics") { include("./pics.php") ; }
if($_GET[action]=="home") { include("./home.php") ; }
if($_GET[action]=="bannerchange") { include("./bannertausch.php") ; }
if($_GET[action]=="rechtliches") { include("./rechtl.php") ; }
if($_GET[action]=="impress") { include("./impressum.php") ; }
if($_GET[action]=="disclaimer") { include("./disclaimer.php") ; }
if($_GET[action]=="about") { include("./about.php") ; }
if($_GET[action]=="gbook") { include("./gaeste/gbook.php") ; }
if($_GET[action]=="links") { include("./links.php") ; }
if($_GET[action]=="banner") { include("./banner.php") ; }
if($_GET[action]=="dl") { include("./dl.php") ; }
if($_GET[action]=="contact") { include("./mail.php") ; }
if($_GET[action]=="stuff") { include("./stuff.php") ; }
?>
[/php:1:5b5f3bc776]

Aufruf dann über "www.adresse.de/datei.php?action=home"

hat den vorteil dass man halt nur dateien aufrufen kann, die hier definiert werden, und keine htpasswd zb ;)
 
super nur streckt sich das wenn deine site ca 150 php seiten hat(wie meine)...
Dann hätt ich 150 zeilen code!!!
Und wenn ich mal den ordner ändern würde..... OMFG
Alles umschreiben also da is der code mit dem array vom raphaelp schon am besten!!!
Aber das Kann ja jeder machen wie er will
 
Werbung:
auch für kleiner würde ich nur den von raphaelp nehmen oder den mit Switch, aber nicht deinen, da du 1 großen fehler hast:

Wenn du beim 1. aufruf deiner site auf www.bla.de gehst, hat der User verloren, da du kein standard Include hast! Und deswegen muss der User immer action=bla eingeben, aber da viele darauf keine lust haben und egtl keiner wissen kann wenn er das 1. mal auf deine Site ist wie der get code ist, wird er wieder von der site gehen
 
oh sry ich hab ein stücken code vergessen :roll:

es soll heissen
[php:1:122c5f3e7e]
<?php
if($_GET[action]=="pics") { include("./pics.php") ; }
if($_GET[action]=="home") { include("./home.php") ; }
if($_GET[action]=="bannerchange") { include("./bannertausch.php") ; }
if($_GET[action]=="rechtliches") { include("./rechtl.php") ; }
if($_GET[action]=="impress") { include("./impressum.php") ; }
if($_GET[action]=="disclaimer") { include("./disclaimer.php") ; }
if($_GET[action]=="about") { include("./about.php") ; }
if($_GET[action]=="gbook") { include("./gaeste/gbook.php") ; }
if($_GET[action]=="links") { include("./links.php") ; }
if($_GET[action]=="banner") { include("./banner.php") ; }
if($_GET[action]=="dl") { include("./dl.php") ; }
if($_GET[action]=="contact") { include("./mail.php") ; }
if($_GET[action]=="stuff") { include("./stuff.php") ; }
else { include("./home.php"); }
?>
[/php:1:122c5f3e7e]
Am schluss noch das Else, das heisst ja, dass auch wenn kein "action=bla" eingeben wurde wird die home.php inkludiert
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben