Guide: PHP- & MySQL-innføring: Kapittel 6
Ta imot data fra brukeren
For å lage dynamiske websider i PHP er man nødt til å ta imot og behandle data fra brukeren. Bare slik kan man tilpasse nettsiden til brukeren.
Sikkerhet
Mantraet til enhver programmerer må være "aldri stol på brukeren." Dette gjelder spesielt webapplikasjoner, som på grunn av at de alltid er tilgjengelig fra hele verden er spesielt sårbare for sikkerhetshull. Et angrep mot din webapplikasjon kan ta den ned fra nettet, bytte den ut med andre nettsider, eller i verste fall bli benyttet i phishing-svindler.
De følgende funksjonene kan hjelpe deg godt på vei, men er ikke det eneste du må tenke på.
stripslashes()
Dette er strengt tatt ingen sikkerhetsfunksjon, men den blir brukt for å forhindre at data sendt fra brukeren blir forandret i oversendelsen. Data som blir oversendt fra brukeren som inneholder tegn som ' (enkelt anførselstegn) eller " (dobbelt anførselstegn) vil få en skråstrek lagt til foran hvert av disse tegnene. stripslashes() fjerner disse igjen.
Det er vanskelig å demonstrere dette på en god måte fra et enkelt PHP-skript, siden denne endringen bare oppstår når man får data fra brukeren eller når man bruker addslashes(). Her er i alle fall et forsøk på å vise hva som skjer. $tekst1 og $tekst2 representerer data slik man får det inn fra en bruker.
<?php
$tekst1 = addslashes("It was James' toy. He told John \"No!\"");
$tekst2 = addslashes('It was James\' toy. He told John "No!"');
echo $tekst1."\n";
echo $tekst2."\n";
echo stripslashes($tekst1)."\n";
echo stripslashes($tekst2);
?>
Utdata fra dette skriptet blir
It was James\' toy. He told John \"No!\" It was James\' toy. He told John \"No!\" It was James' toy. He told John "No!" It was James' toy. He told John "No!"
Legg merke til at de to første linjene er helt like (dvs. at $tekst1 og $tekst2 er to måter å skrive samme strengen på).
strip_tags()
strip_tags() brukes for å fjerne HTML-tagger fra en streng. Det er viktig av mange grunner, spesielt siden data fra en bruker kan inneholde blant annet JavaScript. JavaScript kan benyttes til å sende brukeren til en annen nettside, så folk tror de besøker din nettside (fordi adressen er jo helt lik som adressen til din side), men så sender noe JavaScript-kode dem videre.
<?php
$tekst[] = "<b>Vegard</b> er <em>kul!</em>";
// for å forhindre at vi faktisk blir videresendt,
// er det en feil i JavaScriptet under
$tekst[] = "<script type=\"text/javascript\">windows.".
"location = \"http://www.hardware.no/\";</script>";
$tekst[] = "vanlig tekst";
foreach ($tekst as $t)
{
echo "\n". $t . " -> " . strip_tags($t);
}
?>
Legg merke til at vi var nødt til å legge inn en skrivefeil i JavaScript-koden for at den ikke skulle videresende oss til Hardware.no med en gang vi lastet siden. Om vi ser på kildekoden som dette PHP-skriptet produserer, så ser det omtrent slik ut (vi la til to linjeskift);
<b>Vegard</b> er <em>kul!</em> -> Vegard er kul!
<script type="text/javascript">windows.location =
"http://www.hardware.no/";</script>
-> windows.location = "http://www.hardware.no/";
vanlig tekst -> vanlig tekst
Ondsinnet angrepskode som JavaScriptet ble nå nøytralisert, og brukere som tror de er smarte og registrerer brukernavn med HTML-tagger får et brukernavn som ikke er like kult som de trodde!
htmlentities()
htmlentities() konverterer tegn som kan føre til trøbbel i HTML, slik som < og de særnorske bokstavene til HTML-sekvenser som <& og å (å). Det er viktig for å unngå trøbbel med tegnsett, siden nettsiden kan vises i et annet tegnsett enn brukeren sender inn, og særnorske tegn har en tendens til å være de første som lider av det.
Denne funksjonen slår også ut evt. HTML-kode i input-dataene, men på en litt annen måte enn strip_tags(). Forskjellen er at selve HTML-koden blir synlig når du bruker htmlentities(), mens den blir fjernet med strip_tags(). Her er et lite eksempel på bruk av htmlentities() (omtrent det samme som over);
<?php
$tekst[] = "<b>Vegard</b> er <em>kul!</em>";
// for å forhindre at vi faktisk blir videresendt,
// er det en feil i JavaScriptet under
$tekst[] = "<script type=\"text/javascript\">windows.".
"location = \"http://www.hardware.no/\";</script>";
$tekst[] = "vanlig tekst";
foreach ($tekst as $t)
{
echo "\n". $t . " -> " . htmlentities($t);
}
?>
Resultatet blir som følger. Det er gjerne litt vanskelig å lese, og dette viser nøyaktig utskrift fra skriptet. Om du ser på resultatet i en nettleser blir det annerledes.
<b>Vegard</b> er <em>kul!</em> ->
<b>Vegard</b> er <em>kul!</em>
<script type="text/javascript">windows.location =
"http://www.hardware.no/";</script> ->
<script type="text/javascript">windows.location =
"http://www.hardware.no/";</script>
vanlig tekst -> vanlig tekst
Sammenhengen
Vi brukerstripslashes(); først for å fjerne eventuelle artefakter som har oppstått under overføringen fra brukeren. Deretter bruker vi strip_tags() for å fjerne eventuell ondsinnet HTML-kode fra brukerens side. Til slutt bruker vi htmlentities() for å gjøre om tegn som ikke finnes i ASCII til HTML-koder som tilsvarer det samme.
Dette er stort sett ting du bruker når det er snakk om frie tekst-strenger. Om det er snakk om ting som e-postadresser er det verdt bryet å definere nøyaktig hva som er en gyldig e-postadresse. Til det bruker vi gjerne såkalte regular expressions (regulære uttrykk, ofte forkortet regexp). Det skal vi ta for oss på neste side.