SQL-injection

En genomgång om hur sårbar en databas kan vara om utvecklaren inte vet vad hen gör.

SQL-injection

Denna applikation skall visa faran med SQL-injection och vad som kan hända om vi inte tar ansvar för säkerheten.

Som ett led i att göra språket och databasen så säker som möjligt så kommer det hela tiden uppdateringar i PHP som gör att databasen skyddas allt mer. Under våren 2016 så byggde jag en applikation för att visa på bristerna med mysql-funktioner som gjorde att det gick att komma åt databasen utan att kunna lösenordet för en användare. Våren 2018 behövde jag bygga om denna för nu var dessa sårbarheter tilltäppta. Istället så byggde jag en sårbar applikation med mysqli-funktioner så att jag kunde orsaka samma skada som tidigare fast med de nya säkrare funktionerna.

Våren 2019 så har återigen olika delar slutat att fungera. Tyvärr kan jag inte längre ta bort användare eller ta bort tabell/databas. Vi får se om det tillkommer nya exempel på att skadligt manipulera databasen.

Resultat

Detta är det svar/resultset du får när du har ställt en fråga via ett formulär.

Du har inte ställt någon fråga!


Övning med mysqli-funktioner

I denna övning kommer vi använda några olika formulär med olika former av säkerhet.

Formulär 1: mysqli-funktioner

Det finns tre olika inloggningar som vi skall testa. När du har ställt din fråga till databasen så ser du om du får något resultat, får du ett resultat så kommer du att loggas in som den första användaren i tabellen, om detta hade varit en inloggningsapplikation på riktigt.

  1. Prova först att logga in med ett korrekt användarnamn och lösenord, du kan använda admin/admin, user/user eller test/test. Vad händer?
  2. Nu skall du prova att logga in med en felaktig kombination av användarnamn och lösenord. Vad händer?
  3. Dags att se om vi kan ta oss in i databasen genom att vara duktiga på SQL och se hur mysqli-funktionerna tar emot vårt lösenord. Klistra in strängen i raden nedanför som lösenord och prova sedan att logga in.
" or ""="

Lägg nu märke till två saker;

  1. Hur ser svaret från databasen ut?
  2. Om det gick att logga in, vilken användare kom först i listan? Det är isf denna användare du nu är inloggad som.

Det finns sätt att säkra upp detta även om du vill jobba med mysqli-funktioner, htmlentities() är en bra hjälp. Den funktionen gör om alla specialtecken till en speciell html-kod vilket är användabart för att säkra mot sådan här atacker. " görs om till " vilket gör att hela sql-satsen i vårt fall blir SELECT * FROM admin WHERE username = "admin" AND password = "" or ""=""; och det är därför vi inte får någon träff längre.

Testa samma formulär och samma kod vid mottagandet förutom att jag nu har lagt till htmlentities().

Formulär 2: mysqli-funktioner med htmlentities()


Databasutskrift

Detta är innehållet i databasens tabell admin.

idusernamepassword
1adminadmin
2useruser
3testtest