Beskyt dine formularer mod automatisk udfyldelse

af Birger Sørensen

Problemet:

Har man en (eller flere) formular(er) på sit site, løber man en risiko for at de(n) bliver misbrugt. Det gælder alle formularer - kontaktsider, gæstebøger, blogs, osv. Og resultatet kan være, at man får et hav af spam - pornosider, små blå piller, casinoer - hvis man ikke beskytter formen.

En formular kalder et script på serveren og overfører de data der er indtastet til det, og det er så meningen, at scriptet på serveren skal behandle disse data - sende en eller flere email, gemme data i en database til senere brug, eller hvad det nu kan være. Og problemet er, at når en "besøgende" een gang har brugt formularen, kan hyn registrere hvilke data der sendes, og derefter automatisk udfylde formen, ved at kalde det script der behandler data direkte, og på den måde oversvømme din email eller gæstebog med indlæg, der ikke hører til - uden overhovedet at bruge den tilhørende formular.


Løsningen:

Der findes forskellige måder at beskytte sine formularer på. Den mest udbredte er en "Captcha" - som i virkeligheden er et ekstra felt i formularen, den besøgende skal udfylde med nogle bestemte karakterer, for at de indsendte data bliver accepteret. Den slags findes i mange udformninger - fra billeder, der indholder en tekst, der alt for ofte skal gættes i stedet for læses, til simple tekster, der blot skal gentages.

Problemet med den slags er, at det i virkeligheden ikke kommer en "rigtig" besøgende ved - men alligevel skal der indtastes nogle data. Det er et irritationsmoment - og for nogle af disse systemer, risikerer den besøgende, at formens indhold bliver afvist, selvom hyn gør sit yderste.


En løsning, der ikke involverer den besøgende:

Den her viste løsning, gør det samme som en "Captcha" - men uden at den besøgende ser det, eller overhovedet bliver involveret; der er ikke nogen ekstra felter der skal udfyldes.

Princippet er relativt enkelt. Der indsættes et ekstra felt i formularen, men dette skjules for den besøgende. Dette skjulte felt udfyldes med en kendt værdi, men sådan at vædien er forskellig for hver gang. Samtidig gemmes værdien på serveren. Når formularens data herefter sendes til scriptet der behandler data, sammenlignes de to værdier - den der blev gemt og den der bliver sendt med data - hvis de er ens, godkendes data; ellers afvises de.

Forsøger nogen at kalde scriptet direkte, vil de to værdier være forskellige (eller een af dem slet ikke eksistere), hvorfor data vil blive afvist. Den eneste måde at få data accpteret er at faktisk bruge formularen, som en almindelig bruger ville gøre det.


Et eksempel:

Princippet beskrevet ovenfor, kan anvendes i alle scriptsprog - her vises et eksempel i PHP.

Der er to trin: Først genereres en tilfældig kode, der både gemmes på serveren og indsættes i formularen.

<?php
session_start(); // Muliggør at data kan gemmes i $_SESSION, mellem forskellige besøg af samme besøgende
$_SESSION['kode'] = GetKode(); // Genererer en tilfældig kode, og gemmer den på serveren
?>

<form action="check.php" method="post">
<input type="hidden" name="kode" value="<?php echo md5($_SESSION['kode']); ?>">
// Resten af formen her
</form>
<?php

function GetKode() { // Generer en tilfældig kode på mellem 10 og 25 karakterer; æøåÆØÅ kan give problemer på nogle systemer, så undgå dem
$chars = 'abcdefghijklmnopqrstuvwxyz0987654321ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$max = strlen($chars);
$len = rand[10, 25];
$kode = '';
while (strlen($kode) < $len) {
$ch = $chars[rand(0, $max-1)];
if (strpos($kode, $ch) === false) {
$kode .= $ch;
}
}
return $kode;
}
?>

Kommentarer: Det angivne i dette eksempel, er det der skal anvendes ud over de felter man vil have i formen. Man kan også bemærke, at til forskel fra beskrivelsen ovenover, indeholder formen ikke koden, men en md5 krypteret version af den. Det gør det umuligt for "den besøgende", at gætte på værdien; md5 er altid en 32 karakter lang unik streg, så "den besøgende" altså ikke engang får at vide, hvilken slags data der skal bruges. I tilgift, er der ingen omvendt funktion til md5 kryptering - man kan ikke regne baglæns. Yderligere har den genererede kode variabel længde - her mellem 10 og 25 karakterer.

Andet trin er at checke koden (altså i check.php for formen vist ovenfor):

<?php
session_start();
if (isset($_SESSION['kode']) && isset($_POST['kode']) && (md5($_SESSION['kode']) == (string)$_POST['kode'])) {
// behandling af form data - beskrivelse af, hvad der skal ske, hvis data stemmer
}
else {
echo 'Yeah, well, sorry...';
}
unset($_SESSION['kode']);
?>

Kommentarer: En vigtig del af pointen her, er faktisk den sidste linie, der sletter den kode, der er gemt på serveren. Det gør at koden hvis "den besøgende" forsøger at kalde scriptet til behandling af data direkte, vil det altid blive afvist, fordi der ingen kode eksisterer på serveren, hvis ikke formen har været vist siden sidste kald til behandlingen af data. Og checket fortages netop på om data findes, både på serveren og blandt de medsendte data. Derudover skal md5 koden af data på serveren, være den samme som den der medsendes i data. Vil man sikre sig endnu mere, kan man tilføje den sidste linie - unset($_SESSION['kode']); - på andre sider på sitet, så vil ingen få accepteret data, uden de kommer direkte fra siden der indeholder formen.

Er du ikke velbevandret i PHP, så bemærk linierne med session_start(); først i begge filer. Det er disse, der muliggør at man kan gemme data for en given besøgende på serveren, og således have dem, næste gang den samme besøgende kommer til en af sitets sider. Linierne skal stå først (det kan debatteres; de skal stå før $_SESSION bruges, og før der sendes noget til clienten - hvilket gør FØRST til en vældig god huskeregel).


Konklusion:

Med ovenstående princip, kan man sikre sig, at data fra en given form kun accepteres, hvis formen har været vist umiddelbart inden data indsendes. Yderligere, er den anvendte kode forskellig fra gang til gang, og det vil være umuligt at kalde scriptet der behandler data direkte, uden af formen hentes af den samme "besøgende", umiddelbart før data sendes - og så er det enklere at bruge formens egen submit funktion.

Det kan ikke forhindre misbrug - men det kan kræve, at misbrugere opfører sig som almindelige brugere. Og det har misbrugerne sjældent tålmodighed til. Derfor vil det kunne være medvirkende til en minimering af misbruget på dine sites - i mange tilfælde helt forhindre det.

^ Tilbage til sidens top

Valid XHTML og CSS / Copyright © Hjemmesideskolen september 2012
Hjemmesideskolen
Du er her: Forsiden - scripts - captcha uden brugermedvirken
Brugere lige nu: 1
Home Mail