[PHP] Plaatje beveiligen

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

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MilaNL
  • Registratie: Augustus 2005
  • Laatst online: 09:32
Gegroet!
Ik heb het volgende in html staan in plaatje.php:
code:
1
<img src="plaatjephp.php?id=<? echo $_GET["id"]; ?>" />


$_GET["id"] bepaalt welk plaatje geladen moet worden in plaatjephp.php.
En plaatjephp.php bevat het volgende:

PHP:
1
2
3
4
<? 
header("Content-type: image/jpeg");
include("afbeeldingen/" . $_GET["id"] . ".jpg"); 
?>


Nu wil ik dus voorkomen dat als mensen zelf plaatjephp.php in de browser intikken, ze dat de afbeelding te zien krijgen. Ik wil dat het alleen lukt als ze plaatje.php openen.

Wellicht wat verwarrend met plaatje.php en plaatjephp.php ;)

Ik hoop dat jullie iets weten. Ik heb geprobeerd om een check te maken door in plaatje.php een sessie aan te maken en te checken of die er is in plaatjephp.php... Maar dat ging niet helemaal goed. Er kwam gewoon een wit scherm. Heb ook al op google gezocht naar een mogelijkheid om variabelen door te passen naar andere pagina's, maar ik kan alleen maar vinden hoe dat met GET gaat, en dat heeft geen zin in dit geval.

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
MilaNL schreef op vrijdag 20 juli 2007 @ 23:20:
Ik heb geprobeerd om een check te maken door in plaatje.php een sessie aan te maken en te checken of die er is in plaatjephp.php... Maar dat ging niet helemaal goed. Er kwam gewoon een wit scherm.
Heb je de code daarvan nog?
PHP-code kun je trouwens neerzetten tussen [php]-tags, dan worden ze mooi gehighlight.

Bedenk je wel dat wanneer je van sessions gebruik maakt, iemand die op plaatje.php komt en vlak daarna alsnog handmatig plaatjephp.php opent, niet wordt tegengehouden. Additioneel kun je daarvoor een referercheck inbouwen, maar die is niet waterdicht. Ander alternatief is te zorgen dat de sessioncheck niet langer dan x seconden werkt, omdat na x seconden het plaatje wel is ingeladen (of in ieder geval de check is gedaan).

In zowel plaatje.php als plaatjephp.php zou ik overigens de check toevoegen of $_GET['id'] wel echt een numeriek getal is. In plaatje.php kun je anders allerlei javascripts laten uitvoeren, in plaatjephp.php kun je anders willekeurige bestanden openen (ook die niet op .jpg eindigen).

[ Voor 14% gewijzigd door GlowMouse op 20-07-2007 23:30 ]


Acties:
  • 0 Henk 'm!

  • MilaNL
  • Registratie: Augustus 2005
  • Laatst online: 09:32
met de sessioncheck:

plaatje.php:
code:
1
2
3
<? session_start(); ?>
<? $_SESSION['chk'] = "goed"; ?>
<img src="plaatjephp.php?id=<? echo $_GET["id"]; ?>" />


plaatjephp.php:
PHP:
1
2
3
4
5
<? 
if(!$_SESSION['chk'] == "goed") { exit; }
header("Content-type: image/jpeg");
include("afbeeldingen/" . $_GET["id"] . ".jpg"); 
?>

[ Voor 4% gewijzigd door MilaNL op 21-07-2007 00:13 ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Boven ieder script dien je sessions_start(); te gebruiken. Dat zal je probleem verhelpen.
In mijn vorige post had ik nog wat toegevoegd over het gebruik van $_GET['id'].
Je gebruikt nu include in plaats van readfile. Include is bedoeld om PHP-scripts te includen, niet om plaatjes door te geven.

Acties:
  • 0 Henk 'm!

  • Jogai
  • Registratie: Juni 2004
  • Laatst online: 19-09 08:37
kun je niet iets met mod_rewrite doen?
dat bij opvragen van www.site.nl/plaatjes/foto1.jpg automagisch omgezet wordt naar www.site.nl/plaatjes /foto1.php waar de php dan foto1 als waarde neemt om in de html foto1.jpg uit te poepen.

Klik hier om op linkedIn lid te worden van de Freelance Tweakers groep.


Acties:
  • 0 Henk 'm!

  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 20:15

Onbekend

...

Als je een eigen site hebt kan je controleren of de aanvraag voor het plaatje ook van jouw eigen site afkomt. Als de referer dus niet overeen komt met het adres van jouw site geef je een 404-error o.i.d. :)

offtopic:
[quote]GlowMouse schreef op vrijdag 20 juli 2007 @ 23:24:
[...]
Additioneel kun je daarvoor een referercheck inbouwen, maar die is niet waterdicht.[/quote]
Is dit te omzeilen via de bovenstaande manier?

Speel ook Balls Connect en Repeat


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
[quote]Onbekend schreef op vrijdag 20 juli 2007 @ 23:45:
GlowMouse schreef op vrijdag 20 juli 2007 @ 23:24:
[...]
Additioneel kun je daarvoor een referercheck inbouwen, maar die is niet waterdicht.[/quote]
Is dit te omzeilen via de bovenstaande manier?
De referercheck dient slechts additioneel te zijn, en je moet dus sowieso al een geldige $_SESSION['chk'] te hebben om het plaatje op te halen. Wat de referercheck voorkomt (op een onbetrouwbare manier) is dat iemand met al een geldige $_SESSION['chk'] alsnog direct plaatjephp.php kan openen. Het voordeel zie ik niet, maar het is wel waar TS om vraagt.
Een geheel waterdichte methode bestaat niet (ook $_SESSION['chk'] unsetten na 1x tonen niet) om te voorkomen dat iemand die in plaatje.php kan, ook plaatjephp.php kan openen op een of andere manier. Dat is ook logisch, anders zou het plaatje nooit op zijn scherm krijgen :)
Jogai schreef op vrijdag 20 juli 2007 @ 23:42:
kun je niet iets met mod_rewrite doen?
dat bij opvragen van www.site.nl/plaatjes/foto1.jpg automagisch omgezet wordt naar www.site.nl/plaatjes /foto1.php waar de php dan foto1 als waarde neemt om in de html foto1.jpg uit te poepen.
Dat is hier niet nodig omdat het plaatje sowieso al via php wordt opgevraagd. Jouw post doet me echter wel vermoeden dat TS de mapnaam 'aeiopudsiov' heeft gekozen zodat niemand die kan raden. Dit is een slechte beveiliging. Die hele map kan TS beter via .htaccess onbereikbaar maken.

[ Voor 24% gewijzigd door GlowMouse op 21-07-2007 00:44 . Reden: mapnaampje gewijzigd ]


Acties:
  • 0 Henk 'm!

  • Jogai
  • Registratie: Juni 2004
  • Laatst online: 19-09 08:37
ik zit zelf ook aan zoiets te denken om te maken en daar had ik dit voor bedacht, maar als ik mappen via .htacces ontoegankelijk maak dan kan ook niemand meer linken naar direct het plaatje in die map?

Klik hier om op linkedIn lid te worden van de Freelance Tweakers groep.


Acties:
  • 0 Henk 'm!

  • MilaNL
  • Registratie: Augustus 2005
  • Laatst online: 09:32
session_start(); ook boven plaatjephp.php zetten werkte helaas niet :(
en... hoe wist je dat mijn map zo heette!? (edit: aha, post)

[ Voor 7% gewijzigd door MilaNL op 21-07-2007 00:13 ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
MilaNL schreef op zaterdag 21 juli 2007 @ 00:13:
session_start(); ook boven plaatjephp.php zetten werkte helaas niet :(
en... hoe wist je dat mijn map zo heette!? (edit: aha, post)
Bij mij werkt dat wel. Kijk maar eens of je ergens errors krijgt met error_reporting(E_ALL).

Acties:
  • 0 Henk 'm!

  • Chesta
  • Registratie: November 2004
  • Laatst online: 27-08 06:55
Jogai schreef op vrijdag 20 juli 2007 @ 23:59:
ik zit zelf ook aan zoiets te denken om te maken en daar had ik dit voor bedacht, maar als ik mappen via .htacces ontoegankelijk maak dan kan ook niemand meer linken naar direct het plaatje in die map?
dat is toch precies wat je wilt?

End of Transmission


Acties:
  • 0 Henk 'm!

  • Precision
  • Registratie: November 2006
  • Laatst online: 12-08 21:08
Wat is het nu precies dat je niet wenst? hotlinking?

Crisis? Koop slim op Dagoffer - Op zoek naar een tof cadeau?


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
misschien heeft je host in een controlpanel wel hotlink protection (heb ik in cpanel 10 bijv.). Maar de session methode zou ook goed moeten werken. Je zit er wel mee dat als iemand 1 keer n plaatje heeft opgevraagd de rest wel direct kan opvragen omdat de session gezet is.

Acties:
  • 0 Henk 'm!

  • sjolmers
  • Registratie: September 2000
  • Laatst online: 30-06 17:05

sjolmers

het leven is té kort, geniet!

Onbekend schreef op vrijdag 20 juli 2007 @ 23:45:
Als je een eigen site hebt kan je controleren of de aanvraag voor het plaatje ook van jouw eigen site afkomt. Als de referer dus niet overeen komt met het adres van jouw site geef je een 404-error o.i.d. :)

offtopic:
[quote]GlowMouse schreef op vrijdag 20 juli 2007 @ 23:24:
[...]
Additioneel kun je daarvoor een referercheck inbouwen, maar die is niet waterdicht.[/quote]
Is dit te omzeilen via de bovenstaande manier?
Dit lijkt mij ook de meest doeltreffende methode. Ipv een 404error zou ik of een -don't leech- plaatje laten verschijnen of de bezoekers terugsturen naar de site waarvan ze vandaan komen.

adr opleidingen en meer adr opleidingen


Acties:
  • 0 Henk 'm!

  • MilaNL
  • Registratie: Augustus 2005
  • Laatst online: 09:32
Ik wil niet dat als mensen plaatjephp.php openen, ze dan het plaatje te zien krijgen. Ik wil dat dat alleen lukt als ze plaatje.php openen.

Als je dat controleert of de aanvraag van je eigen site af komt, is dat dus ook zo bij plaatjephp.php...
Ik ga nog even het een en ander proberen met de sessions...

Acties:
  • 0 Henk 'm!

  • MilaNL
  • Registratie: Augustus 2005
  • Laatst online: 09:32
Dit is hoe ik het heb:
plaatje.php
code:
1
2
3
<? session_start(); ?>
<? $_SESSION['chk'] = "goed"; ?>
<img src="plaatjephp.php?id=<? echo $_GET["id"]; ?>" />

plaatjephp.php
PHP:
1
2
3
4
5
6
<? 
session_start();
if(!$_SESSION['chk'] == "goed") { exit; }
header("Content-type: image/jpeg");
include("afbeeldingen/" . $_GET["id"] . ".jpg"); 
?>

Werkt niet .. blijft wit. error_reporting(E_ALL) geeft geen errors.
Maar als ik dan in de broncode kijk van plaatjephp.php zie ik het volgende:
code:
1
<b>Parse error</b>:  syntax error, unexpected T_STRING in <b>/home/hostyour/domains/*mijn domein*/public_html/afbeeldingen/124.jpg</b> on line <b>57</b><br />

en 124.jpg is een afbeelding :(

Acties:
  • 0 Henk 'm!

  • Eusebius
  • Registratie: November 2001
  • Niet online
flanderssoft schreef op zaterdag 21 juli 2007 @ 14:30:
Wat is het nu precies dat je niet wenst? hotlinking?
Als je nu eerst eens aangeeft wat je reden is (niet het symptoon), dan kunnen we mss een andere / betere oplossing geven.

Het lijkt mij dat je hotlinking wil tegengaan. Dat kun je volgens mij beter met htaccess regelen.

==
hoi


Acties:
  • 0 Henk 'm!

  • MilaNL
  • Registratie: Augustus 2005
  • Laatst online: 09:32
Nee ik hoef hotlinking niet tegen te gaan. Het is de bedoeling dat mensen, willen ze het plaatje zien, altijd plaatje.php moeten openen, en niet direct plaatjephp.php!

Reden is: op plaatje.php staat er reclame bij het plaatje, op plaatjephp.php niet!

[ Voor 20% gewijzigd door MilaNL op 21-07-2007 16:57 ]


Acties:
  • 0 Henk 'm!

  • AndriesLouw
  • Registratie: December 2005
  • Laatst online: 19-09 02:45
PHP:
1
2
3
4
5
6
<?php
session_start();
$_SESSION['chk'] = 'ok';

//Hierna img tag
?>


En dan:
PHP:
1
2
3
4
5
6
7
8
9
<?php
session_start();
if($_SESSION['chk'] == 'ok'){
    $_SESSION['chk'] = 'notok';
    //Hierna plaatje laden
}else{
    die('Zeg, we gaan niet direct toegang verkrijgen tot de afbeelding..');
}
?>


Zo kun je maar 1 keer de afbeelding openen per bezoek aan het script wat de img tag toont.

[ Voor 6% gewijzigd door AndriesLouw op 21-07-2007 17:01 ]

Specificaties | AndriesLouw.nl


Acties:
  • 0 Henk 'm!

  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 20:15

Onbekend

...

Dit misschien?

plaatjephp.php:
PHP:
1
2
3
4
5
6
7
8
9
<?php

    if ( !defined('GoodStartpoint') )
    {
        die("No image");
    }

// Hier de rest
?>


plaatje.php:
PHP:
1
2
3
4
5
6
7
8
<?php

define('GoodStartpoint',True);

include 'plaatjephp.php';

// Hier de rest
?>

Speel ook Balls Connect en Repeat


Acties:
  • 0 Henk 'm!

  • MilaNL
  • Registratie: Augustus 2005
  • Laatst online: 09:32
Ik snap er niks van, maar dat werkt :)
Bedankt iedereen die gereageerd heeft en vooral Onbekend AndriesLouw :)
_/-\o_
edit: en nu ist weer wit :(, dit zoek ik zelf wel uit dat gaat wel lukken ;)

Ok, lukt dus niet. Het werkt nu bij alle plaatjes onder de 100kB, alles daarboven geeft de volgende error:
Parse error: syntax error, unexpected T_STRING in /home/hostyour/domains/*mijn domein*/public_html/afbeeldingen/139.jpg on line 57

Google geeft alleen maar oplossingen die met " en ' te maken hebben, maar dat kan het hier niet zijn aangezien het bij plaatjes onder de 100kB wel gewoon lukt.
Is er misschien een limiet aan geinclude pagina's?
Als ik bij google zoek op "include size limit" oid, komt er ook weinig zinnigs uit.

[ Voor 86% gewijzigd door MilaNL op 21-07-2007 21:58 ]


Acties:
  • 0 Henk 'm!

  • AndriesLouw
  • Registratie: December 2005
  • Laatst online: 19-09 02:45
Gewoon readfile() gebruiken..

Specificaties | AndriesLouw.nl


Acties:
  • 0 Henk 'm!

  • MilaNL
  • Registratie: Augustus 2005
  • Laatst online: 09:32
Bedankt! Dan werkt het nu officieel :)

Acties:
  • 0 Henk 'm!

  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 20:15

Onbekend

...

MilaNL schreef op zaterdag 21 juli 2007 @ 17:16:
Ok, lukt dus niet. Het werkt nu bij alle plaatjes onder de 100kB, alles daarboven geeft de volgende error:
Parse error: syntax error, unexpected T_STRING in /home/hostyour/domains/*mijn domein*/public_html/afbeeldingen/139.jpg on line 57
Misschien ligt het aan het plaatje.

Anders kan je proberen om include te vervangen voor require;

Speel ook Balls Connect en Repeat


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Onbekend schreef op zaterdag 21 juli 2007 @ 18:29:
[...]

Misschien ligt het aan het plaatje.

Anders kan je proberen om include te vervangen voor require;
De code die jij eerder postte werkt niet, en is niet wat MilaNL nu gebruikt. In plaats van <img src="blah.php"> kun je niet zomaar include('blah.php') doen om het plaatje op het scherm te zetten. En als include niet werkt, doet require dat ook niet.
mompelt nog wat over paarlen en milanl

[ Voor 5% gewijzigd door GlowMouse op 21-07-2007 20:44 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Zet die plaatjes dir buiten je web directory! Anders kan je nog gewoon http://www.domein.nl/plaatjes/blaat.jpg aanroepen.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 21:01
Je hoeft geen sessies te gebruiken; je kunt ook tokens weggeven die een beperkte tijd geldig zijn. Dan moet de browser dus binnen X seconden na een pageview het plaatje opvragen. Dat voorkomt nog steeds niet dat mensen View Image doen in hun browser, maar dat is redelijkerwijs ook niet te voorkomen.

Het idee is dus dat je pagina een URL genereert naar een plaatje, waarin de id van het plaatje en de tijd waarop de pagina is gegenereerd opgeslagen staat. Om te voorkomen dat client-side de id of tijd wordt aangepast, stuur je een hash mee van die gegevens gecombineerd met een secret key (die alleen server side beschikbaar is); logischerwijs kan de client dan geen gevens meer wijzigen want het is dan niet mogelijk een geldige authenticatietoken te generen (bij gebrek aan de secret key).

Je kunt zo ook eenvoudig een IP-beveiliging toevoegen, maar doe dat maar niet, want dat is niet proxy safe. Sowieso maak je op deze manier caches stuk, in die zin dat als de pagina niet gecachet is het plaatje dat ook niet is.

Voorbeeld:
PHP:
1
2
3
4
5
6
7
8
/* pagina.php */
$secret = 'random geheime string';
$id = 'plaatje123.jpg';          // id van plaatje
$t  = time();            // tijd van pageview
$token = md5($id.$t.$secret);    // token

echo sprintf('<img src="plaatje.php?id=%s&amp;t=%d&amp;token=%s',
    urlencode($id), $t, $token);


PHP:
1
2
3
4
5
6
7
8
/* plaatje.php */
$secret = 'random geheime string'; // zelfde als hierboven
if($_GET['token'] != md5($_GET['id'].$_GET['t'].$_GET['secret'])
    die();  /* ongeldige token */
if($_GET['t'] < time() - 60 || $_GET['t'] > time())
    die();  /* tijd ongeldig of verlopen */

// serve plaatje


Een paar kanttekening: het is aan te raden om een duidelijke foutmelding te geven in plaatje.php (liefst met GD in een plaatje gerenderd zodat de gebruiker het ook kan zien) en niet zomaar een leeg/ongeldig document te genereren. Verder kun de authenticatie token wat netter genereren als HMAC, en zou je eigenlijkt scheidingstekens moeten toevoegen tussen de componenten waaruit je 'm samenstelt ("id\0tijd\0secret" ofzoiets).

[ Voor 3% gewijzigd door Soultaker op 22-07-2007 19:01 ]


Acties:
  • 0 Henk 'm!

  • soulrider
  • Registratie: April 2005
  • Laatst online: 27-11-2017
ne alsnog een tip die al een paar keer is aangehaald:

chech je $_GET-variabelen voordat je ze gebruikt in een php-functie
zekers bij een file-open-en-toon-inhoud-functie.

anders lezen ze zo je php-source-code, of hang je eraan met cross-site-include's en exploits mss.
(zekers zodra je veel volk richting je site krijg)
Het hotlinken voorkomen is ook altijd de moeite als je je bezoekers altijd de reclame wilt meegeven.
(als je je bezoekers zo al 'straft', moet je een hotlinker niet ermee laten wegkomen eh - alhoewel de code van soultaker hierboven dat wrs ook al oplost.)
Pagina: 1