Slik forhindres hacking ved bruk av engangs tokens

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å.



































Bra tiltak å informere om sånt
Hva med å bruke POST istenden for GET, da vil du unngå dette problemet.
Ops, glemte å spørre, hva er problemet med POST?
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!
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.
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?
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.
@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.
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.
@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
[...] 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. [...]
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…
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
@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?
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.
@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.
[...] vei til å skrive en kommentar på teksten, hvor jeg foreslår at neste innlegg skal handle om 15 smarte ting nyetablerte bloggere [...]
[...] Ved å bruke engangs tokens, kan slike csrf( cross site request forgery) angrep bli [...]