21 november 2006
Bij tal van installaties van software als PHPBB, Drupal e.d. krijg je foutmeldingen die gebaseerd zijn op het gebruik van safe mode. Welke programmeur die op meerdere servers werkt herkent niet de melding ?Warning: SAFE MODE Restriction in effect?? Keer op keer vergt dat een bezoekje aan de support site van deze third party tools. Op fora wordt nogal eens het voorstel gedaan ?de server van safe mode? af te halen, zodat de software wel werkt, maar die safe mode zal er toch niet voor niets op zitten? In dit artikel gaan we eens kijken naar het nut en de nadelen van safe mode. Concreet bespreken we deze vragen:
Op veel servers draaien meerdere sites. Dit betekent dat instellingen die site A op de server aanpast gevolgen hebben voor hoe site B (die op dezelfde server staat) werkt. Dit is natuurlijk niet wenselijk. Eigenlijk zou de server dit moeten kunnen voorkomen, maar in de praktijk is dat niet altijd even goed geregeld. Om toch te kunnen voorkomen dat ik de site van mijn ?buurman? plat leg, heeft PHP een functionaliteit welke ?safe mode? heet. Net als bij de ?veilige modus? van Windows beperkt deze instelling het aantal handelingen wat je kan uitvoeren. In zoverre is safe mode een beperking; de andere kant is echter dat je ?buurman? op dezelfde server ook minder mogelijkheden heeft om jou lastig te vallen ? en dat geeft toch zeker ook reden tot vreugde.
Safe mode is een restrictie die ervoor zorgt dat bepaalde functies alleen in een beperkt gebied mogen worden uitgevoerd, zodat het script alleen schade kan aanrichten in dat gebied. Beknopt gezegd: je kan wel je eigen site vernachelen, maar niet die van je ?buurman? op dezelfde server. Dit werkt door middel van het controleren of de eigenaar van het huidige script gelijk is aan de eigenaar van het bestand (of de directory waar het bestand in staat) gelijk is. De eigenaar van een directory kan bijvoorbeeld root zijn. Als je deze file via PHP wilt lezen, zal dit niet gaan omdat je niet de eigenaar van de file bent. Alleen files die ?van jezelf zijn? mag je lezen, kun je verwijderen, kun je in een map zetten enz.
Het zal duidelijk zijn dat m.n. de file bestandssysteemfuncties problemen kunnen ondervinden als safe mode aan staat. Denk hierbij aan functies als fopen(), mkdir(), unlink() en chmod(). Een completere lijst is te vinden op PHP.net.
Er is een mogelijkheid om safe_mode uit te zetten, maar een paar functies of classes toch uit te schakelen als de eigenaar van het script niet de eigenaar is van het bestand wat geopend, verwijderd of wat dan ook worden. Dit kan door het plaatsen van bepaalde functies of classes in disable_functions respectievelijk disable_classes in de php.ini. Dit is uiteraard een opvallende manier van werken. Je zegt dan dat je niet de veiligheid van de (uitgeschakelde) safe mode wilt gebruiken, maar toch een paar uitzonderingen wil maken omdat dat nu eenmaal veiliger is. Daarnaast geldt dat deze waarden in de php.ini moeten worden bepaald. Oftewel, alle sites op deze server hebben dezelfde functies of classes die niet gebruikt mogen worden. Hier al te zeer in variëren maakt het gebruik van deze functies op een server waar meerdere sites op staan niet handig.
Bekende foutmeldingen zijn deze:
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not allowed to access /etc/passwd owned by uid 0 in /docroot/script.php on line 2
Deze foutmelding ontstaat als je een file of directory wilt openen waarvan de eigenaar niet gelijk is aan de eigenaar van het script. Deze error krijg je bijvoorbeeld als je Drupal installeert op een server waar de safe mode aan staat. In dat geval worden er een paar mappen aangemaakt door Drupal, o.a. een map voor de avatars van de leden. Als je echter later d.m.v. een formulier een plaatje in deze map wilt zetten, blijken de eigenaren niet overeen te komen. Een oplossing is in dit geval het opnieuw aanmaken van de map, maar dan via je FTP programma.
Warning: open_basedir restriction in effect. File is in wrong directory in /docroot/script.php on line 2
De open_basedir() is een Apache variabele. Alleen files in deze map of in één van haar submappen mogen geopend worden door het script. Een oplossing zou natuurlijk zijn het aanpassen van je open_basedir(), maar deze variabele heeft waarschijnlijk niet voor niets de waarde die hij heeft. Oftewel, deze fout zul je bij normaal PHP gebruik niet snel tegenkomen.
Warning: readfile() has been disabled for security reasons in /docroot/script.php on line 2
Deze foutmelding zegt precies wat er staat. In dit geval zal de functie readfile() in de variabele disable_functions geplaatst zijn. Oftewel, deze functie mag niet gebruikt worden als de eigenaar van het script niet overeen komt met de eigenaar van de file.
In zijn algemeenheid kun je zeggen dat het aanzetten van safe mode altijd het veiligste is: het dwingt de programmeur tot het correct programmeren. Aan de andere kant, stond PHP juist niet bekend om zijn flexibiliteit? De praktijk is en blijft echter dat je door goed gebruik van de eigenaarsrechten van de verschillende files en directories binnen safe mode veiliger kan werken. Als je echter voor het gemak ? en soms de snelheid ? van programmeren gaat, is het mogelijk hem uit te zetten.
In PHP 6 (toekomstmuziek) zal safe mode niet meer aanwezig zijn. In een blogpost van Sitepoint meldt Harry Fuecks al cynisch dat alleen als de safe mode daadwerkelijk safe zal gaan worden, PHP de kans heeft om groot te worden ? of in ieder geval groter dan nu. Maar PHP 6, daar zijn we nog niet…