7. Moment07 - Förberedelser inför projekt

Vi har gått igenom ett antal moment för att vara förberedda på projektet, det finns vissa smådelar som vi intehar täckt in ännu och som kommer att behövas när vi gör vårt projekt för att uppnå en bra kvalitet på vårt projekt.

7.1 Kryptering

Som utvecklare är det viktigt att vi kan garantera att vi följer de lagar och regler som finns på nätet och en sådan viktig sak är att vi inte lagrar lösenord som går att läsa ut, alla lösenord måste lagras krypterade.

7.1.1 Vad är kryptering?

Kryptering innebär att data förändras på något sätt som gör att det är svårt eller omöjligt att läsa den text som från början är skriven. Det finns många olika funktioner för att kryptera kod både de funktioner som krypterar bara en väg, eller de som även går att kryptera.

Vi skall inte in så djupt på hur och varför vi krypterar utan istället visa exempel på kryptering som är tillräckligt säker för denna kurs och som ger dina användare ett tillräckligt skydd mot att någon enkelt skall kunna knäcka lösenorden.

7.1.2 sha1()

Vi kommer använda den inbyggda funktionen sha1() för att kryptera vårt lösenord. Det funktionen gör är helt enkelt att omvandla strängen med lösenordet till en krypterad variant av samma lösenord. sha1() är en permanent krypteringsfunktion vilket innebär att det inte går att dekryptera den krypterade strängen utan man måste kryptera kontrollsträngen för att sedan jämföra dessa båda krypterade strängarna och se om de är lika.

Att kryptera ett lösenord

<?php
$pwd = "qwerty";
echo "<p>Lösen: ". $pwd ."</p>";
echo "<p>Krypterad sträng: " . sha1($pwd)."</p>";
?>

Webbsidan

Lösen: qwerty
Krypterad sträng: b1b3773a05c0ed0176787a4f1574ff0075f7521e

7.1.3 salt

Att salta ett lösenord innebär att man lägger till en eller flera strängar till det inmatade lösenordet vilket gör hela lösenordet mer avancerat. Även om man har ett enkelt, och dåligt lösenord, som qwerty så kan det med lite saltning göras mycket svårare att knäcka.

Att kryptera ett lösenord

<?php
$saltBefore = "12Aq@y";
$saltAfter = "ö%$";
$pwd = "qwerty";

$salted = $saltBefore . $pwd . $saltAfter;
echo "<p>Saltat: ". $salted ."</p>";
echo "<p>Krypterad sträng: " . sha1($salted)."</p>";
?>

Webbsidan

Saltat: 12Aq@yqwertyö%$
Krypterad sträng: 9085031af1788199362342adaaade60123e5826b

7.1.4 Sammanfattning

Krypteringen används för att göra det omöjligt, eller iaf svårt, att lista ut vilket det ursprungliga lösenordet är. Det finns flera sätt att höja säkerheten.

  1. Kryptering i flera led kan vara ett sätt att göra det svårare att knäcka lösenordet.
  2. Att salta lösenordet en eller flera gånger, kanske tom i flera led, gör det svårare att knäcka lösenordet.
  3. Att hindra användaren från att använda de vanligaste lösenorden gör det mer tidsödande att hitta lösenordet med bruteforce. Bruteforce innebär att en dator testar att kryptera en mängd lösenord på flera sätt tills programmet får en träff. Ett crack-program kan testa flera hundra miljoner lösenord i sekunden.
  4. Hur mycket du än har saltat, hur många gånger du än har krypterat och hindrat de vanligaste lösenorden så faller all säkerhet om databasen och din metod för kryptering hamnar i fel händer. Rootkontots lösnord faller under denna kursens ram, säkerheten för servern faller under andra kurser.

För den som är intresserad så har Facebook meddelat hur de krypterar sina lösenord.

7.2 Heredoc & nowdoc

Strängar i PHP går att hantera på flera sätt, vi har tidigare använt både enkelfnuttar och dubbelfnuttar. Det som blir extra jobbigt är när det är större mängder text som skall användas ihop med flera variabler som skall skrivas ut i texten. Då är HEREDOC (och NOWDOC) ett smidigt alternativ. HEREDOC kan beskrivas som ett större formaterat textblock omringat av dubbelfnuttar medan NOWDOC är samma sak fast omringat av enkelfnuttar.

Externa länkar [klicka för att visa]

Exempel HEREDOC & NOWDOC

<?php
$tal1 = 81;
$tal2 = 23;

$heredoc = <<<EOD
<h2>HEREDOC</h2>
<p>Inom HEREDOC kan vi blanda text och variabler, alla variabler skriver ut
sitt värde, såsom $tal1 och $tal2. Om vi vill skriva ut variabelns namn så
måste vi använda escapetecken "\"! \$tal1 har värdet $tal1.</p>

<p>Glöm inte bort att den avslutande "EOD;" måste stå ensamt utan mellanslag
före eller efter för att stänga HEREDOC.</p>
EOD;

$nowdoc = <<<'EOD'
<h2>NOWDOC</h2>
<p>När vi använder NOWDOC så kommer variablernas värde inte att skrivas ut,
istället kommer variabelnamnet visas, utan att vi behöver använda escapetecken.
Exemplets variabler är $tal1 och $tal2.</p>
EOD;

echo $heredoc;
echo $nowdoc;
?>

Webbsidan

HEREDOC

Inom HEREDOC kan vi blanda text och variabler, alla variabler skriver ut sitt värde, såsom 81 och 23. Om vi vill skriva ut variabelns namn så måste vi använda escapetecken "\"! $tal1 har värdet 81.

Glöm inte bort att den avslutande "EOD;" måste stå ensamt utan mellanslag före eller efter för att stänga HEREDOC.

NOWDOC

När vi använder NOWDOC så kommer variablernas värde inte att skrivas ut, istället kommer variabelnamnet visas, utan att vi behöver använda escapetecken. Exemplets variabler är $tal1 och $tal2.

7.3 Include av delar

Vi har tidigare inkluderat inställningar för databasen som vi behöver på flera sidor. Det går självklart att inkludera andra koddelar som vi använder ofta. Detta är vanligt när vi bygger upp menyer, samt headers och footers som skall vara identiska genom hela projektet.

Ju mer du jobbar med utveckling av olika webbapplikationer desto fler filer väljer du förmodligen att inkludera. Vi kommer i fortsättningskursen kika på andra sätt att läsa in olika kodsnuttar som är gemensamma för hela applikationen som variabler och skriva ut dem som en mall i varje aktuell fil.

Include är ett av flera metoder som kan användas för att läsa in en annan fil, det finns fyra som du behöver hålla koll på.

  • include() - läser in filen men avbryter inte körningen om filen inte finns.
  • require() - läser in filen men avbryter körningen om filen inte finns.
  • include_once() - läser bara in filen en gång även om du gör anropet flera gånger. Lämpligt för funktioner som inte får deklareras en andra gång.
  • require_once() - avbryter körningen om filen inte finns, filen går bara att läsa in en gång.

Vill du kika närmare på denna tekniken så titta på Car, en applikation. Kolla framförallt på filen common.php och hur den används.

7.4 Mail

Att kunna skicka mail från de applikationer vi bygger är trevligt, fundera själv på hur du kan använda detta. Att skicka en bekräftelse när du har skapat ett konto är vanligt, kanske lägga till en verfikationslänk för att säkerställa att mailadressen är korrekt. Kanske har du någon gång använt möjligheten att återställa ett glömt lösenord?

Exempel skicka ett mail

<?php
$content = <<<EOD
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
  body {
      background-color: linen;
  }
  p {
      color: maroon;
      margin-left: 40px;
  }
  </style>
</head>
<body>
  <p>Detta är ett testmail!</p>
</body>
</html>
EOD;

# Adressen att skicka till
$to = "return@sender.se";

# Subject för mailet
$subject = 'Testmail!';

# Information om headern
$headers = "From: Avsändaren\r\n";
$headers .= "Reply-To: no_replay@hemlig.se\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";

# Skickar mailet
mail($to, $subject, $content, $headers);

# Ger användaren ett meddelande att mail är skickat
echo "Mailet har skickats!";
?>

7.5 Funktionen nl2br()

Att lagra skriven text i en databas, eller i en textfil, och sedan publicera den på en hemsida ger oss ibland problem då något som vi uppfattar som samma sak visas på olika sätt.
Till exempel så hanterar html multipla mellanslag som ett enda och struntar fullständigt i radbrytningar.

Exempel på mellanslag & radbrytning

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <p>Detta är
    text skriven

    på flera rader!!!!</p>

    <p>Kolla   vad   många   mellanslag
      jag            kan             slå in                 .</p>
</body>
</html>

Webbsidan

Detta är text skriven på flera rader!!!!

Kolla vad många mellanslag jag kan slå in .

Detta skapar problem om vi skall lagra data där vi vill att användaren skall kunna skapa en egen enkel formatering med radbrytningar. Vi kikar på ett exempel till.

Exempel på radbrytning

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <h2>Inlägg</h2>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati similique dolorem odio sit itaque tempora, aperiam eligendi. Cum officiis necessitatibus exercitationem dolores, ipsa distinctio laudantium unde ea porro beatae rerum.

  Ratione reiciendis dicta quo asperiores voluptate quasi, laboriosam similique molestias odit culpa vel facilis, sapiente delectus magni adipisci iste labore blanditiis, at dolores. Fugit aspernatur possimus voluptas harum debitis nisi!
</p>
</body>
</html>

Webbsidan

Inlägg

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati similique dolorem odio sit itaque tempora, aperiam eligendi. Cum officiis necessitatibus exercitationem dolores, ipsa distinctio laudantium unde ea porro beatae rerum. Ratione reiciendis dicta quo asperiores voluptate quasi, laboriosam similique molestias odit culpa vel facilis, sapiente delectus magni adipisci iste labore blanditiis, at dolores. Fugit aspernatur possimus voluptas harum debitis nisi!

Det blev ju inte riktigt som vi ville. Men i php finns det en funktion nl2br() som gör om alla "new line" som lagras i en text/sträng/variabel/databas till en <br>-tagg vilket får det resultat vi är ute efter.

Exempel på radbrytning

<?php
$text = nl2br("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati similique dolorem odio sit itaque tempora, aperiam eligendi. Cum officiis necessitatibus exercitationem dolores, ipsa distinctio laudantium unde ea porro beatae rerum.

Ratione reiciendis dicta quo asperiores voluptate quasi, laboriosam similique molestias odit culpa vel facilis, sapiente delectus magni adipisci iste labore blanditiis, at dolores. Fugit aspernatur possimus voluptas harum debitis nisi!");
?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <h2>Inlägg</h2>
  <?php
  echo $text;
  ?>
</p>
</body>
</html>

Webbsidan

Inlägg

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati similique dolorem odio sit itaque tempora, aperiam eligendi. Cum officiis necessitatibus exercitationem dolores, ipsa distinctio laudantium unde ea porro beatae rerum.

Ratione reiciendis dicta quo asperiores voluptate quasi, laboriosam similique molestias odit culpa vel facilis, sapiente delectus magni adipisci iste labore blanditiis, at dolores. Fugit aspernatur possimus voluptas harum debitis nisi!

7.6 Funktionen htmlentities()

När vi skickar saker från ett formulär så finns det flera säkerhetshål som behöver täppas till. Det vanligaste sabotaget som en användare kan göra är att skriva in ett script som gör att när något skall kolla på ett blogginlägg skickas vidare till en annan sida.

Det scriptet är enkelt att skriva men också enkelt att skydda sig mot.

Webbsidan

Inlägg:

Vad som händer är att när html-tolken skall rita upp hemsidan och hittar script-taggen så kommer sidan skickas vidare till den angivna sidan. Det går helt enkelt inte längre att läsa nyheten, blogginlägget eller vad som nu lagras på hemsidan.

För att förhindra detta så använder vi funktionen htmlentities() som gör om alla "farliga" tecken till html-säkra tecken.

Exempel på radbrytning

$input = htmlentities($_POST['text']);
echo $input

Strängen kommer istället då se ut så här; <script> window.location="http://www.kursolle.se/hacked.php"; </script> och utgör inte längre något hot då det inte längre finns någon skript-tagg som kan skicka oss vidare. I stället kommer det på hemsidan skrivas ut

Webbsidan

<script> window.location="http://www.kursolle.se/hacked.php"; </script>

Det är kanske inte så snyggt att detta skrivs ut men vi har iaf förhindrat ett sabotage.

7.7 SQL-injection

Genom att använda PDO har vi automatiskt skyddat oss mot första nivån av SQL-injection vilket är fullt tillräckligt för denna kursen. Det handlar om att applikationen/databasen skall vara skyddad mot intrång genom att användaren skriver en sql-sats som gör något annat än vad som är tanken. Det klassiska exemplet är att det är möjligt att logga in genom att manipulera sättet som en sql-sats byggs upp. Tanken är ju att användaren skall skriva så här, förutom att passwordsrutan skall vara type password;

Webbsidan

User:
Pwd:

Då blir ju SQL-satsen såhär;

SQL-sats som vi vill använda

SELECT *
FROM user
WHERE username = 'admin'
AND password = 'qwerty';

Det är ju precis vad vi vill, men den som vet hur SQL är uppbyggt och vilken svaghet det finns om man inte använder sig av skydd mot SQL Injection skulle kunna skriva följande i formuläret:

Webbsidan

User:
Pwd:

Då skulle istället följande kod skickas till databasen;

Manipulerad SQL-sats som är skadlig

SELECT *
FROM user
WHERE username = 'admin' OR 1 = 1; /*
AND password = '';

Vilket innebär att vi här kollar om username är admin eller om 1 = 1 sedan kommenterar vi bort resten av SQL-satsen. Detta innebär att vi troligtvis kommer få ett stort antal rader med användare som resultat på frågan. Finns det många resultat och utvecklaren har slarvat så bör hen se till att det är den första som skall användas. Vilken användare är den första att skapas i ett system? Vilka rättigheter har denna användare?

När vi jobbar med PDO så har vi extra skydd för sådana här säkerhetshål. Vissa databaser har också skapat visst skydd för det men eftersom det finns några system som har några år på nacken och som fortfarande rullar så kan man inte täppa till alla hål på en gång.

Jag har byggt en applikation där det går att testa på hur SQL-injection kan gå till. Men allt eftersom säkerheten höjs i nya versioner av PHP så kommer möjligheterna till skadligt angrepp av databasen minskas allt eftersom.

Här kommer en länk till applikationen "SQL_injection".

7.8 Uppgift

I detta moment finns det ingen uppgift som skall lämnas in. Jag uppmanar dig istället att läsa på och eventuellt testa de tekniker som finns ovan. SQL-injection och htmlentities() är tekniker som du med största sannolikhet behöver använda dig av under slutprojektet. Beroende på vilken typ av projekt du gör kommer även de andra teknikerna vara aktuella.