Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Webprogrammeren & scripting

Veiligheid $_GET in paginasysteem

yendis
15 antwoorden
  • Hey allemaal,

    Ben nog altijd bezig met m'n website, maar nu ik ben begonnen met alle veiligheid op orde te brengen. Laatst las ik iets over $_GET, en dat je de gebruiker nooit de include() mag laten bepalen. Voor mijn paginasysteem had ik echter het volgende bedacht:
    [code:1:458774f1af]
    <?
    if(isset($_GET['ID']))
    {
    $page = $_GET['ID'];
    include("site/".$page);
    }
    else
    {
    include("site/home/home.php");
    }
    ?>
    [/code:1:458774f1af]
    Het is in dit geval (volgens mij) niet mogelijk om een externe pagina te includen, maar alsnog vraag ik me af of dit geheel veilig is.

    Sowieso zou ik wel willen weten hoe ik moet zorgen dat de betreffende pagina (bijvoorbeeld home.php) alleen via de index.php te bereiken is. Zodat je niet in kan typen http://www.site.com/home.php maar dat je echt moet doen: http://www.site.com/index.php?ID=home.php ofzo.

    Alvast bedankt in ieder geval!

    Erik
  • Geen goed idee, je kan nu http://site.com/index.php?ID=$bestand alle willekeurige bestanden van de server opvragen, zoals http://site.com/index.php?ID=../../../../../etc/passwd

    met

    [code:1:69d9db6f4e]
    $page = str_replace('/', '', $page);
    [/code:1:69d9db6f4e]

    kan je de boel wel wat veiliger maken, maar echt veilig is het niet.

    Het beste is denk ik te werken met een vaste lijst mogenlijkheden als items in een array en expliciet checken of de ID 1 van die items uit een array is.
  • Is dat (met zo'n array) wat ze op de meeste websites doen? Ik zat zelf ook aan zoiets te denken, maar het is natuurlijk een hoop werk alle links om te bouwen.

    Het moet inderdaad wel veiliger zijn, want op deze manier zijn met het ID slechts de pagina's op te vragen die ik beschikbaar stel. Ik zal het dus gaan veranderen, bedankt voor je antwoord :)

    Nu is het natuurlijk nog wel zo, dat alle pagina's alsnog op te vragen zijn door: www.site.com/bla/hoi/paginamap/home.php bijvoorbeeld. Zou ik dit tegen kunnen gaan door een .htacces bestand of iets dergelijks?
  • Wellicht is het een optie om een array te vullen (al dan niet geautomatiseerd) met alle toegestane waarden? Vervolgens controleer je of de waarde die je via $_GET[] binnenhengelt in de array voorkomt. Ja, dan pagina laden. Nee, dan naar home (of een 404). Het hebben van een whitelist is een relatief makkelijke methode om de veiligheid significant te vergroten.

    - Bas
  • Inderdaad, dat soort dingen doe ik ook altijd met een array. Dergelijke injectie-mogelijkheden moet je altijd uitsluiten. Never trust user input, zoals het mantra van elke programmeur zou moeten luiden.
  • Aha okee :)

    Ik ben er nu mee bezig, ik maak er zoiets van:
    [code:1:b86c8a8327]
    $pages = array('agenda.php','home.php','fotoalbum.php');

    if(isset($_GET['id']))
    {
    $id = $_GET['id'];
    $pagina = $pages[$id];
    }
    else
    { $pagina = $pages['1']; }

    include("pagemap/".$pagina);
    [/code:1:b86c8a8327]
    Afgezien van enkele typefoutjes hierboven moet dit goed werken, toch?

    Ik moet nu alleen alle links waarin voorheen voorkwam: index.php?id=pagina.php verbouwen naar index.php?id=3, maar als het om veiligheid gaat moet je er wat voor over hebben natuurlijk :)

    EDIT: Ik hoef natuurlijk niet alle links om te bouwen, ik moet gewoon zorgen dat ik de waarde uit $_GET nakijk op aanwezigheid in de array :D
  • Ok, nu heb ik het onderstaande:
    [code:1:702a17ba7c]
    <?
    $pagina_array = array("home.php", "nieuws.php", "niews_toevoegen.php.php", "agenda.php", "agenda_details.php", "agenda_toevoegen.php", "fotoboek.php", "fotoboek_dia.php", "fotoboek_toevoegen.php", "login_profile.php", "login_registreer.php", "login_uitloggen.php", "sorry_administrator.php", "sorry_inloggen.php", "sorry_cookie.php");

    if(isset($_GET['PageID']))
    {
    $page = $_GET['PageID'];
    if(array_key_exists($page, $pagina_array))
    {
    include("content/".$_GET['PageID']);
    }
    else
    {
    include("404.php");
    }
    }
    else
    {
    include("content/home.php");
    }
    ?>
    [/code:1:702a17ba7c]
    En driemaal raden, het werkt niet! Hij wil hoe dan ook (en ik ben er zeker van dat de PageID die ik invoer in de array staat) naar 404.php. Ik heb het ondertussen een heel groot aantal keer doorgelezen, maar kan de fout echt niet vinden. Hebben jullie enig idee waar het aan kan liggen?

    EDIT: Laat maar, had de array_key_exists niet helemaal begrepen. Met in_array werkt het wel :) Bedankt voor de overige reacties in ieder geval! :)
  • Nu ik het eigenlijk nog steeds over die $_GET heb, wil ik nog iets vragen.

    Zou het mogelijk zijn, en is dat dan ook veilig (want volgens mij werkt het wel), om met behulp van $_SERVER het onmogelijk te maken om een pagina zo te benaderen: http://www.site.com/home.php

    Zo ongeveer:
    [code:1:88b38a06cb]
    if($_SERVER[PHP_SELF] !== "index.php")
    {
    echo "Helaas makker, dit is niet de manier om deze pagina te gebruiken!!";
    }
    elseif($_SERVER[PHP_SELF] == "index.php")
    {
    //Hier de pagina
    }
    [/code:1:88b38a06cb]
    Ik weet eigenlijk wel zeker, zonder te testen, dát het werkt, maar valt dit makkelijk te omzeilen?
  • Dat zou zonder veel problemen of nare bijverschijnselen moeten werken. Hooguit moet je op iets meer URI's controleren, zoals bijvoorbeeld ook "/".

    - Bas.
  • Ik begrijp niet precies wat je bedoelt, zou je een voorbeeld kunnen geven?

    Ik heb het net even geprobeerd op het bestand test.php, welke te vinden is in http://localhost/test/test.php.

    Ik kan het bestand nu alleen nog maar benaderen met
    http://localhost/index.php?ID=test.php
    en niet meer via
    http://localhost/test/test.php

    Op internet kwam ik iets als dit tegen:
    http://localhost/index.php/test.php
    En dat gaf in de eerste instantie een erg aparte versie van de pagina. Door het stukje code ook in index.php te voegen, kon deze URI ook niet meer gebruikt worden, en werd de foutmelding gegeven :)

    Ik ga er dus van uit dat dat in ieder geval werkt.
  • Krijg je wel een site te zien als je alleen dit doet:
    http://localhost/

    - Bas
  • Jup, die doet het gewoon :) Althans, ik moet 127.0.0.1 gebruiken, localhost wil hier niet werken(maar dat is geen probleem). Maar het werkt wel gewoon.
    Ook op de server waar de website gehost is, doet die het.
  • Bedankt voor dit topic… ik heb er nooit echt over na gedacht, maar nu zie ik ineens hoe 'lek' een van mijn websites is… Scheelt me weer een hoop in de toekomst. In plaats van een $page='' systeem kan je natuurlijk ook gewoon aparte pagina's maken met een header.php en footer.php, maar dit heeft natuurlijk wel weer beperkende eigenschappen.
  • Ik loop een beetje achter de feiten aan.. maar ik zou toch graag de volgende even zeggen.

    Het gebruiken van index.php?page=home heeft een slecht effect op je website met betrekking tot de vindbaarheid in de zoekmachine's… en het is nog eens gebruiker onvriendelijk ook (jij en ik snappen het wel.. maar voor mensen die minder van het web weten heeft het soms een afschrikkend effect).

    Je kan deze problemen oplossing door "url rewriting" te gebruiken. Feitelijk wat er gebeurd is dat de web server (apache vaak) een andere url laad dan er eigenlijk aan geroepen wordt. Zo kan je het maken dat de gebruiker naar www.jousite.nl/producten/ gaat en dat www.jousite.nl/index.php?page=producten of www.jousite.nl/producten.php geladen wordt. Zoals vermeld heeft dit meerdere voordelen.

    Met betrekking tot bwelmers's opmerking dat het mogelijk is om privacy gevoelige bestanden van de server te bekijken wil ik graag zeggen dat het zeldzaam is dat je op een (shared) host toegang krijgt op bestanden buiten de webroot. Als je zelf een server een beetje redelijk opzet is dit ook het geval. Dergelijke lekken komen dus eigenlijk niet voor.

    Wanneer je meer controle wil hebben over wat er bij een bepaalde 'view' gebeurd kun je ook overwegen een switch() te gebruiken en daar de include statisch in te zetten.

    Hopelijk heeft iemand hier wat aan ;)

    Yendis
  • Hiervoor gebruik je toch bijv apache mod_rewrite?

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.