[PHP] Online bestanden beveiligen tegen directe benadering

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
Ik ben bezig met het opzetten van een soort persoonlijke wikipedia en wil daar graag afbeeldingen en bestanden in gebruiken. De tekstuele inhoud zit netjes in een MySQL database met een PHP frontend waarvoor je in moet loggen. Echter loop ik nu tegen een probleem aan, want wanneer ik bestanden op mijn webspace zet kun je ze gewoon direct benaderen door de volledige URL in te voeren.

Hoewel dit ergens wel security through obscurity is, voelt het toch niet zo prettig dus ben ik eens rond gaan kijken hoe ik deze bestanden hier tegen kan beveiligen.

Een eerste gedachte lag in het gebruiken van .htaccess, hiermee kan ik wel de toegang tot een directory of een aantal bestandstypen ontzeggen, alleen kleven er een aantal nadelen aan:
- Je moet een extra keer een gebruikersnaam en wachtwoord invoeren wanneer je een bestand wil downloaden
- Je kunt niet makkelijk uitloggen (voor zover ik weet kun je alleen maar je geschiedenis e.d. wissen).

Kortom, de ideale situatie zou zijn wanneer ik 1 keer met een PHP script inlog (hierbij wordt een SESSION aangemaakt) waarna ik pagina's kan bekijken waarvan de tekst uit een database komt en hier ook afbeeldingen in geplaatst kunnen worden. Verder moet ik op links kunnen klikken om bepaalde bestanden (PDF, RAR enz.) te kunnen downloaden. Wanneer iemand niet ingelogd is moet hij/zij niet bij de afbeeldingen en bestanden kunnen komen.

Ik heb het vermoeden dat de oplossing toch ergens in .htaccess ligt, maar ik weet niet of je botweg alle toegang kunt ontzeggen en met .htaccess de SESSION kunt uitlezen, om zo uitzonderingen te maken.

Wie heeft er een ingenieus idee, of ziet iets dat ik over het hoofd zie?

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Bestanden buiten je webroot zetten en via een php-script door laten lussen naar de gebruiker.

Acties:
  • 0 Henk 'm!

  • CrabbyData
  • Registratie: Oktober 2006
  • Laatst online: 15-09 23:04

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
@Gomez12: Ik snap je idee, ik zie alleen even niet in hoe ik met PHP dat bestand naar buiten toe beschikbaar kan maken, de browser kan immers niet bij de content buiten de webroot komen.

@CrabbyData: Volgens mij gaat dat anti-hotlinken niet werken, want ik kan de betreffende afbeeldingen dan wel gewoon op het domijn zelf opvragen als ik de "geheime" directory zou weten. Wat dus in principe het directe benaderen niet onmogelijk maakt...

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 09:38

MueR

Admin Tweakers Discord

is niet lief

De browser niet, een php script wel. Die kan dus gewoon het bestand openen en de inhoud daarvan (met de juiste headers) naar de browser sturen.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Shapeshifter schreef op woensdag 06 januari 2010 @ 01:22:
@Gomez12: Ik snap je idee, ik zie alleen even niet in hoe ik met PHP dat bestand naar buiten toe beschikbaar kan maken, de browser kan immers niet bij de content buiten de webroot komen.
PHP kan wel buiten de webroot komen.

Andere methode is voor HTTP-authenticatie kiezen binnen PHP, en .htaccess gebruiken voor de overige files. Hoef je ook maar 1x in te loggen, alleen als je users aanmaakt moet je .htpasswd bijwerken.

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
@MueR: Ah, dat je iets doe met bijvoorbeeld fread(), maar is dat niet desastreus voor grote bestanden? Die moeten dan eerst helemaal door PHP geladen worden voordat ze naar de gebruiker kunnen worden gestuurd...

@GlowMouse, als ik het goed begrijp moet je voor jouw methode via .htacces inloggen, waarna PHP dit oppakt. Het is wel jammer dat de encryptie van .htaccess niet al te best is (en onversleuteld wordt verstuurd).

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
GlowMouse schreef op woensdag 06 januari 2010 @ 01:28:
[...]
Andere methode is voor HTTP-authenticatie kiezen binnen PHP, en .htaccess gebruiken voor de overige files. Hoef je ook maar 1x in te loggen, alleen als je users aanmaakt moet je .htpasswd bijwerken.
En dat .htpasswd bijwerken is uiteraard maar een klein obstakel ;)

Nog even daargelaten dat als je een uitgebreidere beveiliging wilt ( op bestandsniveau ) dat ik me dan afvraag of htaccess dat wel aankan. En als het het aankan, of het echt nog wel zo lekker performt als je 10.000 users in je htpasswd gaat zetten gekoppeld aan een htaccess op user/file-niveau
Shapeshifter schreef op woensdag 06 januari 2010 @ 01:40:
@MueR: Ah, dat je iets doe met bijvoorbeeld fread(), maar is dat niet desastreus voor grote bestanden? Die moeten dan eerst helemaal door PHP geladen worden voordat ze naar de gebruiker kunnen worden gestuurd...
Ach, je hebt naast fread ook andere streaming mechanismen binnen php.
Uiteindelijk zal het uiteraard iets van performance kosten ( je roept minimaal een php aan ) maar dit kan echt redelijk 0,0000000000000000000000001 zijn.

Het enige wat je moet onthouden is dat je het wel goed moet toepassen, die 0,0000000000000000001 is niet boeiend voor 1 foto met 1000 hits per dag, maar kan wel gaan aantikken als je bijv je logo ( wat je op elke pagina toont ) erachter hangt, of je icoontjes of ...

Persoonlijk zou ik gewoon je bestanden scheiden in beveiligd en onbeveiligd, als je home-page ongecached 50 icoontjes / kleine design plaatjes aanroept dan zou ik geen 50 hits op dat ene php-bestand willen.
Enkel de beveiliging gebruiken voor de bestanden waarvoor het nodig is.

[ Voor 44% gewijzigd door Gomez12 op 06-01-2010 01:48 ]


Acties:
  • 0 Henk 'm!

  • senery
  • Registratie: Augustus 2009
  • Laatst online: 16-07-2023
In htaccess kan je het volgende proberen:

<FilesMatch ".\.jpg$">
Deny from all
</FilesMatch>

Op script niveau kan je dan wel de files openen, als ik het goed heb ;)

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
@Gomez12: Hoewel er waarschijnlijk maar een paar gebruikers zijn, is het wel een beetje omslachtig. Ik opereer liever met een MySQL database waar de gebruikers in staan met sha1 hashes van de wachtwoorden.

@senery: Helaas, dat werkt niet, op scriptniveau heb je dan ook geen toegang...

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Shapeshifter schreef op woensdag 06 januari 2010 @ 01:48:
@senery: Helaas, dat werkt niet, op scriptniveau heb je dan ook geen toegang...
??? Geen idee welke scripttaal jij hanteert, maar degene die ik ken gaan toch echt gewoon op local file-system nivo te werk en benaderen geen apache om een bestand op te halen.

Het enige is dat je nu alsnog een php-file moet hebben die het doorstuurt, ik zou er dan gewoon voor kiezen om de bestanden helemaal buiten de webroot te zetten. Iets minder risico op f*ckups als iemand besluit wat met wat opties van apache oid te spelen.

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
Ik heb een .htaccess met de deny in een test directory gezet, daarin zit een images directory. Als ik vervolgens een PHP-bestand in de test directory de volgende HTML laat genereren:

<img src="images/test.jpg" />

Doet hij het niet.

Ik vond net dit:

It is not possible to directly access files outside of the webroot; this is a builtin security restriction that is there for good reason.

It is however possible to use a PHP-script to serve these images for you. This way you can call an image like:
/image.php?file=myfile.jpg

and use file_get_contents() to get the file contents and print them to your browser. You should also send the headers to the client, in this case using PHP's header() function.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

    $file = $_GET['file'];
    $fileDir = '/path/to/files/';

    if (file_exists($fileDir . $file))
    {
        // Note: You should probably do some more checks 
        // on the filetype, size, etc.
        $contents = file_get_contents($fileDir . $file);

        // Note: You should probably implement some kind 
        // of check on filetype
        header('Content-type: image/jpeg');

        echo $contents;
    }
?>

[ Voor 61% gewijzigd door Shapeshifter op 06-01-2010 02:06 ]

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

Verwijderd

dat is volgens mij idd de methode...

je zet de files ergens buiten je www root (of in je www root beveiligd met httaccess deny all).

vervolgens maak je de php scriptjes

(eerst moet je inloggen(met gegevens die je dan uit je database haalt))

=> ingelogd => dan doe je een directorylisting mbv php (readdir/opendir),

=> klik op bestand (a href= blablalba.php?bestand=bestandsnaam)

=> blablabla.php = (checklogin) => en dan iets omtrent de code die je daarnet had...

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 09:31
Je wilt het bestand waarschijnlijk niet steeds geheel in je buffer laden dus is iets als: http://php.net/manual/en/function.fpassthru.php of fread wellicht een betere oplossing. Die kan je zo instellen dat je steeds een deel van de file laadt en een deel doorstuurt. Ik kwam o.a. dit voorbeeld tegen op de fread pagina op php.net:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

$total     = filesize($filepath);
$blocksize = (2 << 20); //2M chunks
$sent      = 0;
$handle    = fopen($filepath, "r");

// Push headers that tell what kind of file is coming down the pike
header('Content-type: '.$content_type);
header('Content-Disposition: attachment; filename='.$filename);
header('Content-length: '.$filesize * 1024);
                
// Now we need to loop through the file and echo out chunks of file data
// Dumping the whole file fails at > 30M!
while($sent < $total){
    echo fread($handle, $blocksize);
    $sent += $blocksize;
}
            
exit(0);

?>

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
djluc schreef op woensdag 06 januari 2010 @ 11:08:
Je wilt het bestand waarschijnlijk niet steeds geheel in je buffer laden dus is iets als: http://php.net/manual/en/function.fpassthru.php of fread wellicht een betere oplossing. Die kan je zo instellen dat je steeds een deel van de file laadt en een deel doorstuurt. Ik kwam o.a. dit voorbeeld tegen op de fread pagina op php.net:
Ik vermoed dat je een regeltje vergeten bent te copy/pasten?

Want het enige wat volgens mij dit script doet is alles in het geheugen inlezen en niets outputten.

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
En dan nog is http://www.php.net/manual/en/function.readfile.php 'de' aangewezen functie hiervoor.

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
Ik heb het onderstaande als testcode gebruikt en dat werkt zoals ik dat graag zou willen.

File.php:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?
session_start();

if(isset($_SESSION['Logged'])){
    $Name = $_GET['Name'];
    
    if(substr($Name, -3) == 'png'){
        header ('Content-length: ' .filesize('/private/Images/'.$Name));
        header ('Content-type: image/png');
        readfile ('/private/Images/'.$Name);
    } elseif(substr($Name, -3) == 'jpg'){
        header ('Content-length: ' .filesize('/private/Images/'.$Name));
        header ('Content-type: image/jpeg');
        readfile ('/private/Images/'.$Name);
    } elseif(substr($Name, -3) == 'pdf'){
        header ('Content-length: ' .filesize('/private/Docs/'.$Name));
        header ('Content-type: application/pdf');
        header ('Content-Disposition: filename='.$Name);
        readfile ('/private/Docs/'.$Name);
    }
} else {
    header("Location: Login.php");
}
?>


Ik kan afbeeldingen plaatsen door bijvoorbeeld:

HTML:
1
<img src="File.php?Name=Afbeelding.png" alt="Dit is een afbeelding" />


Of een PDF bestand met:

HTML:
1
<a href="File.php?Name=Bestand.pdf">Download PDF</a>


Als verbetering zouden eventueel regular expressions gebruikt kunnen worden om de bestandsextensies beter te vatten. Soms komt het voor dat de extensie in hoofdletters wordt opgeslagen (bijv: .JPG) of dat een extensie 4 tekens beslaat (bijv: jpeg). Op dat soort dingen loopt dit script stuk (maar ik zorg er zelf voor dat alles netjes lowercase 3 tekens is...). Bedankt voor de tips iedereen.

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • Grum
  • Registratie: Juni 2001
  • Niet online
En wat nu als iemand een relatief pad opgeeft?

Name=../../NotSoPrivate/Database.php.inc\0pdf

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
Dat levert verder geen problemen op. Bijvoorbeeld: ik heb in /private/Images 3 directories:
  • Contacts
  • Movies
  • Music
En ik kan een afbeelding in de map Movies dus zo aanroepen (met de eerder geposte FIle.php):

HTML:
1
<img src="File.php?Name=Movies/Transformers.jpg" alt="Transformers" />


En technisch gezien kan het ook zo (getest en werkt):

HTML:
1
<img src="File.php?Name=Music/../Movies/Transformers.jpg" alt="Transformers" />


Ik neem aan dat je doelt op de veiligheid van het script, omdat iemand zelf directories kan opgeven en andere PHP-documenten kan openen? Dat is op zich een valide punt, alleen ben ik de enige gebruiker van het systeem en werkt File.php alleen als ik ingelogd ben, dus is het voor mij juist handig (omdat ik overal bijkan).

Het is wel goed dat je het noemt voor mensen die dit willen gebruiken in een meer publieke setting (ikzelf zou de oplossing zoeken in het definieren van $_SESSION['Logged'] met een soort AccesLevel in elk PHP document. Dan kan iemand wel een PHP document aanroepen, maar wordt het niet uitgevoerd, omdat die iemand niet de benodigde rechten heeft.

[ Voor 40% gewijzigd door Shapeshifter op 07-01-2010 11:18 . Reden: Snapte later het doel van de post pas :p ]

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • Kaasplank
  • Registratie: Februari 2001
  • Niet online
Shapeshifter schreef op donderdag 07 januari 2010 @ 03:23:
Ik heb het onderstaande als testcode gebruikt en dat werkt zoals ik dat graag zou willen.
Soms komt het voor dat de extensie in hoofdletters wordt opgeslagen (bijv: .JPG)
dan doe je toch even een strtolower in de if/elseif's? Dan vang je dat probleem al af.

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
Goed punt, dat werkt inderdaad prima. Het geval wil dat ik met sommige dingen haast autistisch ben en ik het gewoon fijn vind als al mijn bestanden lowercase extensies hebben. Dus voor mij is het gelijk een soort controle (als een afbeelding het niet doet is de extensie uppercase en kan ik dat "fiksen").

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • Hipska
  • Registratie: Mei 2008
  • Laatst online: 15-09 21:08
Verder kun je nog het volgende in je .htaccess zetten zodat je nog mooiere links maken.
code:
1
2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ File.php?Name=$1 [L]


Hierdoor kan je File.php?Name=Movies/Transformers.jpg vervangen door Movies/Transformers.jpg
De eerste regel zorgt ervoor dat hij dit enkel doet wanneer het bestand niet gevonden werd in de www root.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Grum schreef op donderdag 07 januari 2010 @ 10:02:
En wat nu als iemand een relatief pad opgeeft?

Name=../../NotSoPrivate/Database.php.inc\0pdf
Ook mijn eerste gedachte :) Code wijd open voor een security hole...

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
Maar zoals ik al zei ben ik de enige gebruiker en kun je File.php alleen gebruiken als je ingelogd bent.

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Laatst online: 10:27
Shapeshifter schreef op donderdag 07 januari 2010 @ 16:42:
Maar zoals ik al zei ben ik de enige gebruiker en kun je File.php alleen gebruiken als je ingelogd bent.
Wat als er een lekje in je inlogsysteem zit? Niks mis met een beetje extra beveiliging toch.

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
Als er een lek in mijn beveiligingssysteem zou zitten kun je in principe via de website ook al overal bij, dus erg veel verschil maakt het dan ook niet meer :p

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • joostvanpinxten
  • Registratie: Maart 2007
  • Laatst online: 03-09 12:50
Shapeshifter schreef op donderdag 07 januari 2010 @ 17:05:
Als er een lek in mijn beveiligingssysteem zou zitten kun je in principe via de website ook al overal bij, dus erg veel verschil maakt het dan ook niet meer :p
Dat is nou net het punt wat ze proberen te maken, dat is niet zo! De root van je website is normaal het laagste wat je kan komen, daar zorgt apache wel voor. Alleen als je nu via PHP bestanden gaat openen, dan krijg je het probleem dat je lager dan de root van je website kan komen en dus bijvoorbeeld ook naar een map met je persoonlijke foto's kan, die misschien ook op diezelfde server aanwezig is. Wel degelijk een lek dus!

Acties:
  • 0 Henk 'm!

  • joostvanpinxten
  • Registratie: Maart 2007
  • Laatst online: 03-09 12:50
Shapeshifter schreef op donderdag 07 januari 2010 @ 17:05:
Als er een lek in mijn beveiligingssysteem zou zitten kun je in principe via de website ook al overal bij, dus erg veel verschil maakt het dan ook niet meer :p
Dat is nou net het punt wat ze proberen te maken, dat is niet zo! De root van je website is normaal het laagste wat je kan komen, daar zorgt apache wel voor. Alleen als je nu via PHP bestanden gaat openen, dan krijg je het probleem dat je lager dan de root van je website kan komen en dus bijvoorbeeld ook naar een map met je persoonlijke foto's kan, die misschien ook op diezelfde server aanwezig is. Wel degelijk een lek dus!

<img src="File.php?Name=../../../../../../Fotos/vriendinineenpikantesituatie.jpg" alt="Leuke foto!" /> bv dus. Of als je op een gedeelde server zit, dan kan het zijn dat je bij andermans applicatie in kan loggen, of daar 'beveiligde' informatie op kan halen. (Maar dat zou eigenlijk de hoster goed ingesteld moeten hebben, waar je eigenlijk niet vanuit mag gaan?)

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
En het punt dat ik probeer te maken is dat die PHP documenten er voor een reden zijn, namelijk om mij op een eenvoudige manier toegang te geven tot mijn bestanden (zoals foto's). Dus het zou raar zijn als iemand door mijn beveiliging breekt en vervolgens mijn intuitieve gebruikersinterface links laat liggen en zelf moeilijk gaat doen om in de root te komen...

Overigens zijn de bestanden (zoals foto's e.d.) in PDF opgeslagen met een wachtwoord, ik weet dat de graad van beveiliging daarvan niet bijzonder hoog is, maar het is toch weer een extra barrriere.

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Shapeshifter schreef op donderdag 07 januari 2010 @ 17:26:
En het punt dat ik probeer te maken is dat die PHP documenten er voor een reden zijn, namelijk om mij op een eenvoudige manier toegang te geven tot mijn bestanden (zoals foto's).
Is daar geen sftp/ssh voor uitgevonden?

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Zoijar schreef op donderdag 07 januari 2010 @ 19:06:
[...]

Is daar geen sftp/ssh voor uitgevonden?
Oeh, heb jij een sftp / ssh client die automatisch server-side thumbnails aanmaakt zodat je snel kan zien welk bestand wat is, en die vanuit dezelfde interface ook nog eens door exif data kan zoeken etc?
Doe mij eens een linkje naar die client...

Een webinterface kan meer voordelen hebben :)

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09:15

Janoz

Moderator Devschuur®

!litemod

Tja, zolang iedereen zich focust op de mogelijk pikante foto's dringt de werkelijke impact nog niet helemaal bij ShapeShifter door.

ALLE bestanden zijn op te vragen. Ook de sourcecode van je php site (het wordt immers as is doorgegeven en dus niet geparsed) met hierin uiteraard ook je database inlog gegevens. /etc/passwd zal ook wel niet zo moeilijk zijn.

Het is nu eenmaal niet voor niks dat er nogal 'heftig' gereageerd wordt op dergelijke security flaws. Dit zijn precies die aannames (och, het valt allemaal wel mee) die je uiteindelijk de das om gaan doen. Met een paar regeltjes extra code is het lek dicht, het beargumenteren waarom je verzuimt dit security gat te fixen heeft je tot nu toe meer inspanning gekost.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Maar wat probeer je nou te bereiken?

Dat niemand plaatjes van je website kan downloaden, of dat ze er niet via http://www.website.nl/plaatje.jpg bij kunnen?

Het eerste is simpelweg niet mogelijk, voor het tweede zou je hier misschien iets mee kunnen.

Freelance Unity3D developer


Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
Janoz schreef op donderdag 07 januari 2010 @ 20:48:
Tja, zolang iedereen zich focust op de mogelijk pikante foto's dringt de werkelijke impact nog niet helemaal bij ShapeShifter door.

ALLE bestanden zijn op te vragen. Ook de sourcecode van je php site (het wordt immers as is doorgegeven en dus niet geparsed) met hierin uiteraard ook je database inlog gegevens. /etc/passwd zal ook wel niet zo moeilijk zijn.

Het is nu eenmaal niet voor niks dat er nogal 'heftig' gereageerd wordt op dergelijke security flaws. Dit zijn precies die aannames (och, het valt allemaal wel mee) die je uiteindelijk de das om gaan doen. Met een paar regeltjes extra code is het lek dicht, het beargumenteren waarom je verzuimt dit security gat te fixen heeft je tot nu toe meer inspanning gekost.
Je hebt een punt, maar het is niet zo dat alle bestanden op te vragen zijn. Enkel alle .png, .jpg en .pdf bestanden (andere bestanden komen niet door de elseif loop heen). Verder is het voor mij juist handig omdat ik juist gebruik wil maken van directories. Ik zou natuurlijk een blacklist kunnen maken voor directories waar niet in gekeken mag worden...

@CyCloneNL: dat is echt bedoeld voor kleine bestanden (voornamelijk afbeeldingen dus), terwijl ik er ook PDF documenten mee wil kunnen parsen.

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Shapeshifter schreef op vrijdag 08 januari 2010 @ 19:06:
[...]


Je hebt een punt, maar het is niet zo dat alle bestanden op te vragen zijn.
Jawel, je gooit jpg / png / pdf als laatste 3 karakters om door de elseif heen te komen en ergens daarvoor gooi je een \0 zodat readfile het bestand pakt.

Staat letterlijk ergens in dit topic genoemd...

En is nou ook niet echt de meest obscure bug ooit te noemen als je bedenkt dat dit soort scripts veelal wel .jpg / .png serveren en "last" hebben van de \0.

Ik gok dat er genoeg scriptkits zijn die gewoon standaard iets als ../../../../../../../../../../etc/passwd\0.jpg in het arsenaal hebben zitten

Acties:
  • 0 Henk 'm!

  • Shapeshifter
  • Registratie: Januari 2004
  • Laatst online: 07-09 21:38

Shapeshifter

Get it over with

Topicstarter
Hmm, die krijg ik niet gereproduceerd. Opera en IE proberen in dat geval een jpg weer te geven die niet bestaat. Misschien dat het door mijn hostingprovider weggefilterd wordt?

HP ZBook Studio G3 - Hyundai Ioniq EV Classic - Opel Vivaro-e 75kWh - 22x Prusa i3 MK3S - 8x Prusa MINI+ - Ooznest Workbee 1,5m x 1,5m


Acties:
  • 0 Henk 'm!

  • kokx
  • Registratie: Augustus 2006
  • Laatst online: 13-09 20:30

kokx

WIN

En hoe heb je die null-byte ingevoerd in je browser?

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
kokx schreef op vrijdag 08 januari 2010 @ 22:06:
En hoe heb je die null-byte ingevoerd in je browser?
Invoeren is het probleem niet, de request kun je ook met een script de deur uit doen. Of is er in veelgebruikte webservers of in PHP iets dat voorkomt dat de null-byte in $_GET terechtkomt?

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Shapeshifter schreef op vrijdag 08 januari 2010 @ 21:41:
Hmm, die krijg ik niet gereproduceerd. Opera en IE proberen in dat geval een jpg weer te geven die niet bestaat. Misschien dat het door mijn hostingprovider weggefilterd wordt?
kokx schreef op vrijdag 08 januari 2010 @ 22:06:
En hoe heb je die null-byte ingevoerd in je browser?
Tja, en daar gaat mijn vertrouwen weer in websecurity.
HTTP is echt geen rocket-science, met telnet krijg je zo handmatig een file losgepeuterd.

Maarja, misschien dat een browser hem eruit haalt. Dan ben je uiteraard 100% veilig...

Voor de tip : http://php.net/manual/en/security.filesystem.nullbytes.php
Voor de 2e tip : http://www.google.com/sea...he+php+null-byte+handling

Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 05:44
Je kan met realpath() kijken of je bestand wel of niet in /private/ staat, zaken als ../ worden dan voor je opgelost.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<? 
session_start(); 

if(isset($_SESSION['Logged'])){ 
    $Name = $_GET['Name']; 
     
    if(substr($Name, -3) == 'png' && strpos(realpath('/private/Images/'.$Name),'/private/Images/') === 0){ 
        header ('Content-length: ' .filesize('/private/Images/'.$Name)); 
        header ('Content-type: image/png'); 
        readfile ('/private/Images/'.$Name); 
    } elseif(substr($Name, -3) == 'jpg' && strpos(realpath('/private/Images/'.$Name),'/private/Images/') === 0){ 
        header ('Content-length: ' .filesize('/private/Images/'.$Name)); 
        header ('Content-type: image/jpeg'); 
        readfile ('/private/Images/'.$Name); 
    } elseif(substr($Name, -3) == 'pdf' && strpos(realpath('/private/Docs/'.$Name),'/private/Images/') === 0){ 
        header ('Content-length: ' .filesize('/private/Docs/'.$Name)); 
        header ('Content-type: application/pdf'); 
        header ('Content-Disposition: filename='.$Name); 
        readfile ('/private/Docs/'.$Name); 
    } 
} else { 
    header("Location: Login.php"); 
} 
?>


Klein testje:
http://peter-server.homelinux.net/realpath.php
Shapeshifter schreef op vrijdag 08 januari 2010 @ 21:41:
Hmm, die krijg ik niet gereproduceerd. Opera en IE proberen in dat geval een jpg weer te geven die niet bestaat. Misschien dat het door mijn hostingprovider weggefilterd wordt?
Dat is de inhoud van dat bestandje dat door de headers wordt weergegeven als corrupt bestandje. Vul die url hier maar eens in: http://web-sniffer.net/ Dan zie je de ruwe data en alle headers.

[ Voor 16% gewijzigd door Peetz0r op 09-01-2010 09:14 ]

Pagina: 1