- Kursmaterial
- Planering
- Arbete
- Kunskapsdokument
- Tutorials
- Applikationer
- Andra kurser
- Om Kursolle
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 inte har 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.
- Kryptering i flera led kan vara ett sätt att göra det svårare att knäcka lösenordet.
- Att salta lösenordet en eller flera gånger, kanske tom i flera led, gör det svårare att knäcka lösenordet.
- 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.
- 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ösenord faller under denna kursens ram, säkerheten för servern faller under andra kurser.
För den som är intresserad så meddelade Facebook 2015 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.
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 verifikationslä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
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å html-säkra tecken
$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.6.1 htmlspecialchars()
htmlentities()
fungerar bra men det finns ett problem och det är hur den funktionen hanterar specialtecken såsom å, ä och ö. Då finns det en annan funktion htmlspecialchars() som vi kan använda istället. Vi testar och kikar på skillnaden.
Exempel på html-säkra tecken
$code = 'åäö'; echo htmlentities($code)."<br>"; echo htmlspecialchars($code, ENT_QUOTES, "UTF-8");
Webbsidans utskrift
åäö
åäö
Utskriften ser ju kanon ut, men om vi kikar på källkoden så ser den ut på följande sätt;
Källkoden
åäö<br>åäö
På detta sätt så kan vi få till samma funktionalitet som htmlentities() men utan problemet med att våra viktiga bokstäver å, ä, ö inte förstörs. Extra viktigt blir detta när vi skall lagra data till databasen.
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
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
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 Template
Hjälp för högre betyg
Detta avsnitt är inte obligatoriskt i kursen men för den som har tid och vill bygga applikationer lite mer genomtänkt så kan det vara värt tiden att kika på detta avsnitt.
När vi bygger större applikationer, eller iaf applikationer som innehåller ett antal olika sidor så gäller det att hitta ett bra sätt att bygga upp en bra struktur. Säg att vi har 20 sidor i en applikation och vi vill ändra css, då är det ju smidigt att detta ligger i en extern fil. Om vi vill ändra en meny, eller en sidfot på något enkelt sätt, hur gör vi då? Då gäller det att dra nytta av möjligheten att inkludera filer på olika sätt.
Detta är ett material som jag tidigare har använt som första uppgift i kursen Webbserverprogrammering02. Svårighetsmässigt är det inga konstigheter men det gäller att vända på tanken om hur du bygger dina applikationer idag. När du väl har tänkt om så kommer du känna att du kan skapa större applikationer på kortare tid och det blir också väldigt mycket smidigare att både bygga ut och bygga om dessa applikationer.
Detta material är byggd som en egen applikation som du hittar här. Tycker du utseendet ser tråkigt ut? Det var så Kursolles första version såg ut.....
Har du tid över så försök att bygga om en av din fungerande applikationer med denna template, det kan vara Paolos Webb, InloggDb eller kanske en bankapplikation?
7.9 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.