Datakurser
Aktuell vecka: 48

Tillbaka till toppen

Övrigt Säkerhet

Vilka hot finns?

Det finns ett antal sätt att sabotera för oss när vi skapar en sajt med hjälp av php och mysql. Vi ska lära oss lite om vad som kan hända om vi inte vidtar vissa säkerhetsåtgärder. Vi ska se vad vi kan göra för att säkra våra sidor och system.

OWASP (Open Web Application Security Project) är en organisation som arbetar med att skapa gratis kunskap, metoder, dokument, verktyg och tekniker för att hindra sabotage på webbsajter. OWASP lever på bidrag och är inte ett organisation som ska generera vinster. De skapar produkter med öppen källkod.
Enligt OWASP så är de 10 vanligaste säkerhetsriskerna.

The OWASP Top 10 - 2013:

Källa: https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project#tab=OWASP_Top_10_for_2013 (2014-01-13)

 

Cross Site Scripting (XSS)

XSS inträffar när webbservern tar emot indata som är skadlig och skickar ut den till en klient och dess webbläsare utan ordentlig validerng av innehållet. XSS är attacker där skript körs i offrets webbläsare och som kidnappar sessioner, ändrar webbsidor eller skickar offret vidare till farliga webbsidor som saboterar för offret.

Definition av Cross-site scripting (XSS), eller webbkodsinjektion, från Wikipedia (http://sv.wikipedia.org/wiki/Cross_site_scripting, 2013-01-13):

“Cross site scripting, XSS, är ett datorrelaterat säkerhetsproblem. Ofta handlar det om att stjäla information som annars inte visas, eller förstöra en webbsidas utseende. Ett exempel på hur XSS kan förstöra en sidas utseende vore om ett fält där det är meningen att text ska skrivas inte är skyddat mot HTML-kod. Då kan användaren lägga in stora bilder eller ramar som tar upp plats och förstör utseendet på sidan. Även länkar till skadliga sidor kan då planteras där.

XSS kan också användas för att stjäla information från andra användare. Exempelvis kan vi tänka oss en community där man kan skicka meddelanden till varandra. Om sajten inte är skyddad mot XSS så kan användaren X skicka ett meddelande till användare Y och få honom att klicka på en länk som via javascript automatiskt skickar hemlig information om användaren Y till användaren X. Med den informationen kan exempelvis användare X logga in som användare Y och därmed förstöra.”

Reflected XSS (Non-persistent, det vill säga lagras inte)

Här tar webbservern emot någon typ av indata och det skadliga används i den returnerade webbsidan och körs i klientens webbläsare.
sakerhet-bild1

<?php
     //Google har inbyggt skydd och för att stänga av det så har vi följande rad
     header("X-XSS-Protection: 0");
     if ($_POST['mytext']) {
          $answer = "";
          $answer=$_POST['mytext'];
          $_POST['mytext']=null; 
          echo $answer."<br>";
     }
?>

<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">
     <label>Namn:</label>
     <input type="text" name="mytext"><br>
     <input type="submit" value="Skicka">
</form>

OBS! Det skiljer beroende på var webbsidan ligger. På labbservern fungerar exemplet i Internet Explorer och Firefox, medan Google har inbyggt skydd mot XSS. För att kunna testköra även i Google så har skyddet stängts av med en kodrad i filen.

Hur skyddar man sig mot XSS

Det är inte speciellt svårt. Det viktiga är att vi granskar och rensar indata direkt från möjligheten att utföra otillåtna saker. Det gör vi genom att ändra "farliga" tecken till "ofraliga" genom att ändra sättet att skriva dessa tecken. När vi nu har rensad indata så behöver vi inte koda om den för utskrift i filen som ska skickas från webbservern men det kan vara bra att säkra att all data från en databas som ska skrivas ut är rensad. Det vill säga funktionen används på utdata från databasen som ska skrivas in på webbsidan.


Vi rensar indata som kommer med en php-funktion som heter htmlspecialchars( ).

htmlspecialchars(textsträngen, [eventuell extra krav som ENT_QUOTES], ['UTF-8'])
htmlspecialchars($str, ENT_QUOTES,'UTF-8')
htmlspecialchars($str)
Från PHP5.4.0 så är UTF-8 standard.

Den översätts alla html-specifika tecken till html-entiteter:

  • '&' (ampersand) blir '&amp;'
  • '"' (citat) blir '&quot;' när ENT_NOQUOTES inte är satt
  • "'" (apostrof) blir '&#039;' (or &apos;) endast när ENT_QUOTES är satt
  • '<' (mindre än) blir '&lt;'
  • '>' (större än blir '&gt;'
//Lösningen i ovanstående exempel
$answer = "";
$answer = $_POST['mytext'];
$answer = htmlspecialchars($answer, ENT_QUOTES,'UTF-8');
$_POST['mytext'] = null;

Vi initierar en variabel. Tilldelar variabeln innehållet i POST-variabeln. Översätter alla htmlspecifika tecken till motsvarande entiteter. Rensar bort värdet i den globala POST-variabeln.

Stored XSS (Persistent XSS, lagras på webbservern)

Ett exempel kan vara en oskyddad gästbok. Där kan det till exempel vara att kod sparas med ett inlägget. Då kommer den skadliga koden köras varje gång inlägget visas. Till exempel kod för att stjäla information från andra. Det skulle kunna se ut så här. A skickar in ett meddelande med dold kod. När B vill läsa webbsidan så bifogas en länk i webbsidan som via javascript automatiskt skickar viktig information om B till A. Med den informationen kan till exempel A logga in som B.

Säg att vi har en gästbok
gastbok

Om vi stoppar in följande kod som meddelande.
<script> window.location="http://www.bestonline.se/evil"; </script>


Så kommer alla som går till gästboken att skickas vidare till evil.php-sidan, ingen kommer ens att se gästboken.

Säkrar vi upp inmatningen genom att byta ut alla farliga tecken med

$namn=htmlspecialchars($_POST[namn], ENT_QUOTES,'UTF-8');
$meddelande=htmlspecialchars($_POST[meddelande], ENT_QUOTES,'UTF-8');

så kommer den farliga koden sparas som följande text

&lt;script&gt; window.location=&quot;http://www.bestonline.se/evil&quot;; &lt;/script&gt;

och kommer inte att behandlas som något skript när den ska hämtas från databasen och skrivas ut på en webbsida utan det översätts snyggt till följande text på webbsidan

"<script> window.location="http://www.bestonline.se/evil"; </script>".

SQL injektion

SQL-injektion är ett vanligt säkerhetsproblem på webbsidor. Det uppstår genom att okontrollerad data skickas direkt in i en SQL-fråga. På så sätt ändras SQL-anropets ursprungliga funktionalitet till något annat.

Ett SQL-injektion är ett säkerhetshålsom kan utnyttjas på många olika sätt. Databaser kan raderas, lösenord kan stjälas och så vidare.

För att undvika detta använd PDO. Med parameteriserade sql-förfrågningar och preparerade sql-satser.

Ett exempel

Vi har en inloggningssida för administratörer.
sqlinjektion-bild1
Följande SQL-fråga skulle mycket väl kunna användas i ett sådant skript.
SELECT * FROM users WHERE user = '$user' AND password = '$password'

Om någon nu skulle skriva in "zzz" som användarnamn och "'or 'a'='a" som lösenord
sqlinjection-bild2
så skulle SQL-frågan se utan så här:
SELECT * FROM users WHERE username = 'zzz' AND password = ''or 'a'='a'

Det skulle resultera att personen i fråga skulle bli inloggad som administratör, i och med att 'a' alltid är lika med 'a'.
sqlinjection-bild3


Damn Vulnerable Web Application (DVWA)

Här finns program och en testmiljö för att testa och förstå mer avancerad hacking, http://www.dvwa.co.uk/ .

Brute force attacks

"Brute force attacks" är när en hackare försöker att logga in tusentals gånger. Självklart är det en dator som utför arbetet. Lösenord skapas slumpmässigt eller så plockas ord från något ordlexikon.
En finess man kan lägga in sitt eget system är att logga antal försök och till exempel efter 3 st så låser man kontot, kanske bara för en viss tid eller så måste man be om nytt lösenord för att komma in.
Det är svårt att stoppa sådana här atacker. Ett sätt som ofta används idag är CAPTCHA. Det vill säga att vi ska skriva in några tecken som hämtas ur en bild som är svår att tolka för datorer.

CAPTCHA ute HONEYPOT inne

Honeypot är en antispamteknik som går ut på att man lägger in ett osynligt formulärsfält. Osynligt för vanliga användare men inte för spamrobotar. Fältet döljs med CSS och för att formuläret ska fungera så måste detta fält vara tomt (vilket alltid är fallet med vanliga användare).

Spambotarna kan i regel inte hantera CSS och de är ofta instruerade att fylla i alla fält i ett formulär. Det innebär att de inte kan ta sig förbi ett formulär som är skyddat av ett honeypot-fält. Spambotarna fastnar i honungsburken.

Det finns lite olika sätt att lägga in honeypot-skydd i ett formulär. Det enklaste är att lägga till ett textfält med CSS-värdet ”display:none;” (via en separat klass). När formuläret skickas är det bara att plocka bort de inlägg där detta fält har ett värde. Ange gärna ett vanligt formulärsnamn för detta fält (”zip”, ”phone” eller liknande).

Om en människa besöker sidan, med en webbläsare som inte hanterar CSS, så kan det även vara bra att lägga in en label med en text motsvarande ”Om du är en människa, fyll inte i detta fält”. Även detta bör då vara dolt. Förhoppningsvis anger då människan ifråga inte något i detta textfält.

Ett exempel för detta i PHP finns här: Quick and Simple PHP Honey Pot Spam Prevention. Ett bra inlägg om detta, för de som vill lära sig mer, finns här: Stopping spambots with hashes and honeypots

Ytterliggare ökad säkerhet

I ett eget logga in system kan det vara bra att även lagra och checka ip-adress och webbläsare vid varje anrop.
ip-adress: $ip = $_SERVER["REMOTE_ADDR"];
webbläsare: $hua = $_SERVER['HTTP_USER_AGENT'];

Källor, referenser, bra länkar

http://se1.php.net/manual/en/function.htmlspecialchars.php
w3schools.com/php/
http://www.w3sidan.net/wiki/Cross+site+scripting
http://sv.wikipedia.org/wiki/Cross_site_scripting
http://www.ansoncheunghk.info/article/top-6-security-attacks-php
http://www.sitepoint.com/php-security-cross-site-scripting-attacks-xss/
http://www.troyhunt.com/2013/05/understanding-xss-input-sanitisation.html
http://www.troyhunt.com/2010/05/owasp-top-10-for-net-developers-part-2.html
http://www.unixwiz.net/techtips/sql-injection.html
http://www.blackhatlibrary.net/SQL_injection
http://hackers2devnull.blogspot.se/2013/07/exploiting-post-method-xss-silently.html
http://sec24.se/penetrationstest/sql-injection-sqli/manuell-sql-injection

http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL
http://www.php-login.net/

Utvecklingsmiljöer

Labbservern

PHP 7.2, MariaDB 5.5 och Apache 2.4.6

Laragon

Apache 2.4, MySQL 5.7, PHP 7.4

Lösningsförslag

Alrik's