21. april 2010 - 15:48Der er
20 kommentarer og 1 løsning
Hvor sikker er min beskyttelse?
Jeg er på det sidste kommet til at tænke på hvor sikker min kode beskyttelse egentlig er.
Selve siden er kodet i .PHP, data gemmes i MySQL.
Her er lidt facts: Kodeord er gemt som md5 krypterede. Når jeg tjekker om brugerens login er rigtigt krypterer jeg md5 og holder op imod koden i MySQL. Jeg sætter så en session med brugernavnet. På de beskyttede sider tjekker jeg om session til brugernavn er tom.
Men hvor sikkert er det egentligt? Hvis det skal forbedres skal det så tweakes, eller skal jeg kode et nyt system (hvilket) fra bunden?
point gives til den/dem der er kommet med de(n) bedste kommentar(er)
I forhold til dine Sessions, kunne du måske sætte en ekstra variabel som feks is_logged_in = 1 så har du da en lille ekstra smule at tjekke om sessionen kommer fra login siden...
#1 Jeg er enig i konceptet om at det at salte sine hashede kode øger sikkerheden hvad angår brugerens sikkerhed såfremt at databasen hvor disse opbevares er sårbar og der er risiko for at koderne er læsbare. Så kan de trods alt ikke bare slås op i rainbow tables uden videre.
Hvad angår dit forslag om at sætte endnu en variabel, må jeg erkende at jeg ikke forstår idéen med - det er da helt fint med en enkelt variabel om den så indeholder et tal eller et brugernavn. Det er simpelt - hvis sessionen brugernavn er sat er man logget ind, ellers ikke. Sikkerheden øges ikke af at have to session variabler som du kan kontrollere på (i den forstand som der omtales her).
#0 Som #1 omtaler er hashing en måde at beskytte dine brugeres data på - det øger dog ikke sikkerheden; det afhænger stærkt af den kode der ligger udenom, så at give et bud på om din 'sikkerhed er god nok' bliver et skud i tågen på baggrund af den information du giver. Jeg har lavet et brugersystem - ment som en slags tilføjelse til hvad man nu er igang med at lave, som du kan hente her http://catalystcode.net/ - der kan du se eksempler på hvordan jeg logger brugere ind og ud, kontrollerer deres adgang og så videre. Det er mit bud på hvad der er sikkert. Og husk - der er ikke et facit til sådan noget her - der er mange forskellige løsninger. Men lad os se noget kode, så kan vi bedre vurdere det...
Sikkerheden ligger heller ikke kun i hvordan du gemmer password og brugere samt hvordan du logger dem ind. Det handler lige så meget om hvordan du håndtere en hver form for brug input på din side. En enkelt åbenhed i din håndtering af brugerdata kan nemt koste dig din side.
Validere du alle bruger input ? Bruger du prepared statement i til inde mysql query's ? (mysqli) eller husker du at bruge mysql_real_escape_string(), hvis du bruger mysql, på alle bruger input som du bruger i dine query's ?
Bruger du $_GLOBAL ? Er dit system sat med register_globals til on ?
beskyttet_side.php <? if($_SESSION['user'] == ""){ ?> Du skal være logget ind for at se denne side. <? } else { ?> Tekst til brugeren der er logget ind <? } ?>
#4 Har aldrig hørt om mysqli? xD Jeg har arbejdet lidt mid mysql_real_escape_string(), men bruger det, som du kan se, ikke, selvom jeg helt sikkert burde. Jeg har haft lidt problemer med at finde en tutorial jeg kunne forstå. Jeg bruger ikke $_GLOBAL og register er sat til off. Det kan jeg dog ikke ændre med, da det er et gratis host, der benytter samme php.ini filer til alle, og den kan ikke ændres.
Grunden til at jeg stiller det her spørgsmål er at jeg ikke rigtig har forbedret det i lang tid, og gerne vil have forslag til at gøre det sikrere.
$hent_db = mysql_query("SELECT * FROM `users` WHERE `brugernavn` = '$brugernavn' ORDER BY `id` DESC");
Her kan jeg skrive $brugernavn som ' or 'a' = 'a ... så den SQL bliver til:
SELECT * FROM `users` WHERE `brugernavn` = '' or 'a' = 'a' ORDER BY `id` DESC");
Nu har du dog ikke password med i din SQL, og du bruger også md5 på den, men ellers ville jeg kunne logge ind med et hvert brugernavn, og ' or 'a' = 'a som password, og den ville logge ind.
Som andre siger, er det vigtigt at du bruger mysql_real_escape_string() på brugernavn. Og jeg ville også sige at du skulle prøve at bruge en database class, f.eks PEARs DB eller en der kan prepare SQL, så du ikke selv skal tænke på at sanitize alle variabler først.
Det er stort set essensen i SQL injection, mysql_real_escape retter en del af arbejdet, men du skal også tage forhold for mysql CLIENT_MULTI_STATEMENTS... $brugernavn = " ' ; delete from users --";
Jeg har som sagt ikke fundet en tutorial til anti injection, som jeg har kunne forstå, mest fordi jeg ingenting fatter xD
Men, hvis man nu laver et felt mere i mysql, der hedder brugermd5, der bare er md5 af brugernavn og holder op i mod den, i stedet for det normale brugernavn, vil det vel fjerne alle specialtegn og multi statements?
Det er da bedst at forstå det, jeg ville ikke gå en omvej for at undgå at bruge mysql_real_escape...
Bare kig på min besked igen:
Hvis jeg skriver (i input feltet, $_POST['brugernavn']):
' or 'a' = 'a
og du indsætter det i din SQL:
WHERE brugernavn = '$brugernavn'
Så bliver det jo til:
SELECT * FROM users WHERE brugernavn = '' or 'a' = 'a' ORDER BY id DESC
Hvilket betyder den tager alle brugernavne der er tomme, ELLER hvis a = a, og a er altid = a, så den tager bare alt fra users.
Hvis du nu brugte password = '$password' .. så ville jeg kunne skrive brugernavn = "admin" ... password = ' or 'a' = 'a og den ville glemme alt om password.
Men brug mysql_real_escape og is_numeric() til int, med mindre du bruger en DB class...
woodydrn, du kan jo ikke få den til at ignorere pass, da det bliver md5 krypteret. Hvis du skriver ' or 'a' = 'a' vil den se om password = e9fc0c452dff83d67aec691ea0c81634, og hvis den gjorde det samme med kodeord, ville du heller ikke kunne injecte den?
Nej, det var heller ikke det jeg sagde. Jeg sagde "Hvis du nu brugte password = '$password' .. " ... HVIS ;)
Der er dog mange sider der ikke kryptere deres passwords, f.eks jeg får emails fra buydomains med mit password i, så hvis de ikke bruger en eller anden form for sanitizing af den string - ville det kunne injectes.
"woodydrn, du kan jo ikke få den til at ignorere pass", men jeg kunne f.eks injecte brugernavnet og skrive 12345 ved password, så bare håbe på der er nogen med det password.
Der er ikke så meget at tage fejl af med mysql_real_escape_string(). Du bør bruge den på alle input fra en bruger, når du bruger mysql og du bruger inputtet direkte i din sql sætning! Dette gælder for ALLE de sider hvor du har bruger input til mysql!
MySQLi er en nyere version af mysql. Du kan ved lejlighed prøve at læse om den i php manualen. Men det kræver nok at du har lidt kendskab til klasser.
Og så lige en ekstra ting, md5 er en hash værdi. Dette betyder at to forskellige "sætninger" teoretisk godt kan have den samme hash værdi.
dkfire, jeg kan ikk helt se hvor det er jeg siger at jeg er ligeglad?!? Jeg har oprettet den her tråd for at forbedre sikkerheden i mit login script, jeg siger bare at jeg ikke har fundet en tutorial der har kunne forklare mig injection beskyttelse, så jeg har kunne forstå det.
Mange tak til alle der er kommet med gode råd og kunstriktiv kritik. Dem der selv mener de bør få point, skriv et svar, så vil jeg mandag morgen dele point ud :)
well jeg brugte da lidt tid på at forklarer SQL injection ;)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.