Slik forhindres hacking ved bruk av engangs tokens

hacke bilde, lolz

Jeg har snakka såvidt om csrf tidligere. Og nå skal jeg vise dere hvordan forhindre slik uønsket aktivitet med engangstokens.

Først skal jeg komme med et eksempel script, som viser hvorfor engangstokens er nødvendig.

<form action="slett.php" method="GET">
<p>Hvilken bruker skal vi slette?: <input type="text" name="bruker" /></p>
<p><input type="submit" value="Slett" /></p>
</form>;

Og her er slett.php:

$bruker = $_GET['bruker'];
slettBruker($bruker);

For å slette brukeren "arne", kan man lure eieren av siden til å besøke følgende lenke:

slett.php?bruker=arne

Dette kan gjøres på en rekke måter, slik at admin som klikker på den, ikke vet det selv engang. Men her skal jeg bruke det enkleste eksempelet, en lenke:

http://victim/slett.php?bruker=arne

Man kan sende lenken via chatteprogrammer, forum, epost eller andre ting.
Og når admin klikker på lenken, vil den uskyldige brukeren arne bli slettet fra nettstedet.

Dette forutsetter at admin er pålogget på nettstedet naturligvis.

Det er denne type angrep som kalles for cross site request forgery( csrf), og kan og bør forhindres ved å bruke engangs tokens. Jeg vil ikke høre klaging på at POST er tryggere enn GET, for det er det ikke.

Slik forhindrer man at arne blir slettet

Studer følgende modifikasjoner:

<?php
session_start();
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
?>
<form action="slett.php" method="GET">
<p>Hvilken bruker skal vi slette?: <input type="text" name="bruker" /></p>
<input type="hidden" name="token" value="<?php echo $token; ?>">
<p><input type="submit" value="Buy" /></p>
</form>

Og slett.php:

<?php
session_start();
if ($_GET['token'] == $_SESSION['token'])
{
$bruker = $_GET['bruker'];
slettBruker($bruker);
}
else
{
echo "Feil token";
}
?>

For hver sletting admin gjør, kreves det at $token fra forrige side matcher den som er i PHP's sessions. Detter betyr at følgende lenke ikke lenger vil slette brukeren arne:

http://victim/slett.php?bruker=arne

Nettopp fordi riktig token mangler. Denne typen engangstokens brukes kun i store og proffe php applikasjoner som phpbb, wordpress og lignende. Hobbyprogrammerer eller amatører bruker det ikke. Grunnen er rett og slett at de ikke vet hva csrf er, og hvorfor det er så farlig.

Har prøvd å forklare så enkelt som mulig. Bare spør hvis det er noe du stusser på.

Del på Facebook
Del på Twitter
Legg til på Nettby









Dette innlegget ble skrevet på Wednesday, February 25th, 2009. Og er lagret under Deilige tekster. Skumma gjennom av 3643 stykker.

18 Responses to “Slik forhindres hacking ved bruk av engangs tokens”

  1. dieselmusa on February 28th, 2009 at 7:48 pm

    Bra tiltak å informere om sånt :)

  2. Anonym on March 1st, 2009 at 2:23 am

    Hva med å bruke POST istenden for GET, da vil du unngå dette problemet.

  3. Anonym on March 1st, 2009 at 2:24 am

    Ops, glemte å spørre, hva er problemet med POST?

  4. admin on March 1st, 2009 at 3:39 am

    POST forespørsler er like lett å lage som GET forespørsler. Det krever kun litt javascript kunnskaper. Ergo løser man ikke problemet med å bruke POST istedenfor GET, det er en myte!

  5. Anonym on March 1st, 2009 at 4:23 pm

    Sett litt på koden du brukte til slik hacking på norbits, det viser seg at du fint kan unngå iFrames bruk ved hjelp av denne koden:

    if (top!=self) top.location.replace(location.href);

    Og med POST kan du ikke sende infoen med en enkel link.

  6. admin on March 1st, 2009 at 4:40 pm

    Ja iframes kan unngåes. Men å sende POST forespørsler kan også gjøres med javascript. Og du har rett i at POST ikke kan sendes på en lenke, men man kan jo lenke til et html dokument du kontrollerer som der bruker javascript og sender POST forespørsel?

  7. Rabbitz on March 1st, 2009 at 5:34 pm

    Når man bruker form’s, bruker man sjeldent GET, POST som gjelder da.

    I tillegg til dette er vell som regel admin sider passord beskyttet, og dermed gjelder ikke dette lenger. Trenger ikke noe engangs tokens da.

  8. Audun Larsen on March 4th, 2009 at 5:59 pm

    @Rabbitz,
    CSRF er like aktuelt om man bruker POST, det er ikke noe problem å “lure” en bruker til å sende en POST request han ikke er klar over, og dersom han også allerede er logget inn så vil jo den bli utført også.
    Engangs tokens må alltid brukes dersom man skal utføre en handling.

  9. Krister on March 5th, 2009 at 5:16 pm

    Hvis denne slette-funksjonen er en admin funksjon, pleier jeg alltid å legge til at brukeren må autorisere seg for å kunne fullføre funksjonen. Enten ved session, cookies eller med å skrive inn passordet på nytt.

    Er det en brukerfunksjon så må brukeren være autorisert for å slette akkurat den brukeren (Antageligvis sin egen)

    Og for å sørge for at man ikke kan sende MSN lenker med slettefunksjon, er det bare å sørge for at funksjonen kun kan lastes hvis brukeren trykker på knappen på slettesiden, men alt dette kan overskrides med javascript.

    Husk at hvis man skal ha en slik funksjon så vil man kanskje gjøre det så vanskelig som overhodet mulig for brukeren å slette seg selv. Kanskje til og med kreve at brukeren sender en e-post til admin.

    Enda en ide, er at brukeren vil bli slettet etter ett par dager, slik at brukeren har sjangse til å angre på valget sitt.

  10. Rabbitz on March 11th, 2009 at 1:44 am

    @Audun Larsen

    Såklart er det like lett, ikke det som var poenget :)
    Uansett, nei. Engangstokens må ikke alltid brukes. Jeg har i alle mine script, beskyttet alle filer som kjører feks. slettfunksjoner, leggtilfunksjoner osv. Dvs, at er du ikke logget inn får du ikke kjørt noen av disse funksjonene. Hva skal jeg da med engangstokens? Kan ikke bruke CSRF da :)

  11. Skogtrollet » Vi avslører 3 sikkerhetsfeil på 3 store norske nettsteder on March 12th, 2009 at 1:05 am

    [...] Skal vi løse problemet? Ja det burde vi absolutt gjøre. Jeg foreslår folket å lese teksten min om hvordan forhindre xss og hvordan forhindre hacking ved hjelp av engangstokens. [...]

  12. Bjørn on March 15th, 2009 at 1:53 pm

    Det er en liten feil i koden du viser over. Du må huske på å slette session etter at den er brukt. Hvis ikke er det bare å bytte ut bruker for å slette andre…

  13. Nicole on March 22nd, 2009 at 7:04 pm

    Sv. Takk for kommentar på bloggen min :) ) Helt enig i det du sier at det må ha litt kvalitet også :) ) Kom gjerne innom flere ganger :) )

    xoxo

  14. Audun Larsen on March 28th, 2009 at 5:12 pm

    @Rabbitz

    Det er der du tar så skammelig feil. Og missforstår hele problemstillingen. Hva om brukeren allerede er logget inn, og så blir lurt inn på ondsinnet side?

  15. Pål on April 5th, 2009 at 6:48 am

    Sverre Huseby skrev mange gode artikler rundt dette tema alt på starten av 2000-tallet. I artikkelen “Client Side Trojans” fra 2001 (http://shh.thathost.com/text/client-side-trojans.txt) beskriver han et ticket-system med engang-tokens for hver request mot en webserver.

    Sverres tekster er like aktuelle i dag som i 2001.

  16. Van The Man on April 12th, 2009 at 1:43 pm

    @Audun: Dersom personen som i dette tilfellet har tilgang til “Slett Bruker” og blir _LURT_ inn på en ondsinnet side, kan de ikke forvente noe annet.
    Gjelder vell gjerne ha kompetente administratorer, som faktisk vet hva de driver med.

  17. Skogtrollet » 15 smarte ting nyetablerte bloggere gjør on April 16th, 2009 at 6:22 am

    [...] vei til å skrive en kommentar på teksten, hvor jeg foreslår at neste innlegg skal handle om 15 smarte ting nyetablerte bloggere [...]

  18. Skogtrollet » En referrer sjekk hjelper ikke mot hackere on September 2nd, 2009 at 10:41 pm

    [...] Ved å bruke engangs tokens, kan slike csrf( cross site request forgery) angrep bli [...]

Legg igjen en kommentar