42

Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23
Page 2: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23
Page 3: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Objektorientierte Webentwicklungmit PHP und MySQLvon Marc Remolt, Jan Teriete

Art.-Nr. 011948445Version 5.1.0 vom 30.7.2014

Autorisiertes Curriculum für das Webmasters Europe Ausbildungs- und Zertifizierungsprogramm

© 2012 by Webmasters Presswww.webmasters-press.deNordostpark 7, 90411 Nürnberg, Germany

Page 4: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23
Page 5: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Das vorliegende Fachbuch ist urheberrechtlich geschützt. Alle Rechtevorbehalten. Die Verwendung der Texte und Abbildungen, auch aus-zugsweise, ist ohne schriftliche Genehmigung des Verlags urheber-rechtswidrig und daher strafbar. Dies gilt insbesondere für die Verviel-fältigung, Übersetzung oder Verwendung in elektronischen Systemensowie für die Verwendung in Schulungsveranstaltungen. Die Informatio-nen in diesem Fachbuch wurden mit größter Sorgfalt erarbeitet. Trotz-dem können Fehler nicht vollständig ausgeschlossen werden. Autorenund Herausgeber übernehmen keine juristische Verantwortung oderirgendeine Haftung für eventuell verbliebene fehlerhafte Angaben undderen Folgen.

Page 6: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23
Page 7: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Informationen zu dieserBuchreihe

Dieses Buch ist Teil unserer Buchreihe zum Zertifizierungsprogramm des Europäischen Web-masterverbandes, Webmasters Europe e.V. (WE).

Das Webmasters Europe Ausbildungs- und Zertifizierungsprogramm ist modular aufgebautund bietet Abschlüsse und Zertifizierungen auf verschiedenen Ebenen an – von der Experten-Zertifizierung für einzelne Themen bis hin zu Diploma-Abschlüssen für Webdesigner, Web-Entwickler, Webmaster und Online Marketing Manager. Nähere Informationen dazu finden Sieunter http://de.webmasters-europe.org/bildungsprogramm

Unsere Buchreihe bietet Ihnen nicht nur eine fundierte und praxisnahe Einführung in dasjeweilige Thema, sondern ist von Webmasters Europe e.V. offiziell autorisiert zur Vorbereitungauf die WE-Zertifikatsprüfungen. Damit haben Sie die Garantie, dass alle prüfungsrelevantenThemen behandelt werden.

Page 8: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23
Page 9: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Inhaltsverzeichnis

15Einführung

15Einleitung15Vorkenntnisse16Aufbau der Lektionen16Aufgaben im Fließtext16Testen Sie Ihr Wissen17Aufgaben zur Selbstkontrolle17Optionale Aufgaben17Anforderungen an PHP17Was sind Entwurfsmuster?

19Strukturierung von PHP-Webprojekten

19Das Problem20Strukturierung von PHP-Code20PHP und HTML trennen23Lesbaren Code schreiben24Kapselung in Funktionen26Funktionen, die atomare Probleme lösen28Zusammenfassung

29Einführung in die objektorientierte Programmierung

29Einleitung29Was sind Objekte?31Objekte in PHP33Klassen36Attribute36Attribute verändern36Attribute auslesen37Attribute in Klassen definieren38Methoden38Grundlagen39Vorteil von Methoden41Die Variable $this43Namenskonventionen43Klassen43Attribute44Methoden44Variablen, die Objekte enthalten

46Getter- und Setter-Methoden

46Das Problem46Kapselung47Getter-Methoden47Vorteil von Getter-Methoden48Ein Attribut »privat« machen

1

1.11.21.31.3.11.3.21.3.31.3.41.41.5

2

2.12.22.2.12.2.22.2.32.2.42.3

3

3.13.23.2.13.2.23.33.3.13.3.23.3.33.43.4.13.4.23.4.33.53.5.13.5.23.5.33.5.4

4

4.14.24.34.3.14.3.2

Page 10: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

50Setter-Methoden50Nachteile des direkten Änderns eines Attributs51Methoden zum Ändern von Attributen52Öffentliche und private Methoden

54Arbeiten mit Objekten

54Das Problem54Methoden, die andere Methoden aufrufen56Methoden in anderen Objekten aufrufen56Grundlagen59Der instanceof-Operator60Type-Hinting

63Virtuelle Attribute

63Das Problem63Virtuelle Attribute63Konzept65Setter für virtuelle Attribute

67Magische Methoden

67Das Problem68Magische Methoden68Konzept68Die Methode __toString()70Konstruktoren70Konzept70Die Methode __construct()71Parameter an __construct() übergeben72Ein assoziatives Array an den Konstruktor übergeben

78Beziehungen zwischen Objekten

78Das Problem78Objekte in anderen Objekten verstecken80Ganze Objekte als Parameter übergeben

83Das MVC-Entwurfsmuster

83Einleitung84Model86Templates87Vollständige Templates88Teil-Templates89View90Controller90Controller mit Aktionen92Die Standard-Aktion94Zusammenfassung

4.44.4.14.4.24.5

5

5.15.25.35.3.15.3.25.3.3

6

6.16.26.2.16.2.2

7

7.17.27.2.17.2.27.37.3.17.3.27.3.37.3.4

8

8.18.28.3

9

9.19.29.39.3.19.3.29.49.59.5.19.5.29.6

Page 11: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

98Objekt-relationales Mapping

98Das Problem98Verbreitete ORM-Entwurfsmuster99Active Record

100Data Mapper101Zusammenfassung

102Composer, Packagist & Co.

102Einleitung102Composer & Packagist103composer.phar103composer.json105Die eigentliche Installation105Wichtige Composer-Dateien105composer.lock106autoload_namespaces.php106Zusammenfassung

108Doctrine-Entities

108Einleitung108Die Beispiel-Datenbank108Die reine Tag-Datenklasse110Namespaces112Konfiguration per Annotationen113Entity113Table114Der Primärschlüssel114Id115GeneratedValue115Column115Doctrine-Datentypen116Parameter von Column116type116length116unique117nullable117precision und scale117Konfiguration des Autoloaders119Zusammenfassung

121Die Webmasters Doctrine Extensions

121Einleitung121Bootstrap122$connectionOptions123$applicationOptions124EntityManager125Chaining125Vererbung126ArrayMapper127Zusammenfassung

10

10.110.210.2.110.2.210.3

11

11.111.211.2.111.2.211.2.311.311.3.111.3.211.4

12

12.112.212.2.112.2.212.312.3.112.3.212.412.4.112.4.212.4.312.512.612.6.112.6.212.6.312.6.412.6.512.712.8

13

13.113.213.2.113.2.213.313.3.113.3.213.413.5

Page 12: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

129PHP-Objekte mit Doctrine speichern

129Einleitung129Das Controller-Skeleton130Das SchemaTool131Das eigentliche Speichern132persist132flush oder das Entwurfsmuster Unit of Work133Zusammenfassung

135Datenbankabfragen mit Doctrine

135Einleitung135EntityRepository135findAll136find136findBy137findOneBy137Zusammenfassung

139Komplexe Abfragen mit Doctrine

139Einleitung139Per DQL139createQuery140getResult142getSingleResult142getOneOrNullResult142Per QueryBuilder143createQueryBuilder143Die wichtigsten Methoden144Zusammenfassung

145DateTime

145Einleitung145Die DateTime-Klasse146format147modify147diff147Timestampable150Doctrine und die Nutzung von DateTime-Objekten151Zusammenfassung

153Datenbank-Beziehungen mit Doctrine

153Das Problem153Beziehungen per Annotation definieren1541:n-Beziehungen abbilden154Klasse User155Klasse Article155Das Problem157Die Handhabung von 1:n-Beziehungen159Ein Beispiel161n:m-Beziehungen abbilden

14

14.114.214.314.414.4.114.4.214.5

15

15.115.215.2.115.2.215.2.315.2.415.3

16

16.116.216.2.116.2.216.2.316.2.416.316.3.116.3.216.4

17

17.117.217.2.117.2.217.2.317.317.417.5

18

18.118.218.318.3.118.3.218.3.318.3.418.3.518.4

Page 13: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

162Klasse Article und Klasse Tag163Die Zwischentabelle163Ein Beispiel166Lazy Loading168JOINs168Per DQL169Per QueryBuilder169Zusammenfassung

171Der Controller im Überblick

171Einleitung171Vorbereitungen172BREAD174Browse175Read177Edit179Add180Delete181Tagging183Zusammenfassung

185Fortgeschrittene Techniken

185Doctrine um Validierungen erweitern188Validierungsbedingungen für Datumswerte190Öffentliche Methoden von EntityValidator191Datenbankabfragen in Repositories auslagern193Zufallsdatensätze

197Eine Einführung in das Thema Sicherheit

197Absolute Sicherheit ist unmöglich198Fünf empfehlenswerte Tugenden199Security through Obscurity200www.webmasters-fernakademie.de200blog-das-oertchen.de201www.google.de201localhost202Server-Konfiguration204Parametermanipulation205Whitelist - Variante 1206Whitelist - Variante 2207Dateiangaben als Parameter209Die bekanntesten Angriffsvarianten209SQL-Injections212Cross-Site-Scripting217Weitere Angriffsmöglichkeiten220Authentisierungssicherheit220Passwörter225Passworthashing230Benutzernamen und Kennungen231Browserfeatures234Ein paar grundsätzliche Hinweise

18.4.118.4.218.4.318.518.618.6.118.6.218.7

19

19.119.219.319.3.119.3.219.3.319.3.419.3.519.419.5

20

20.120.1.120.1.220.220.3

21

21.121.221.321.3.121.3.221.3.321.3.421.3.521.421.4.121.4.221.4.321.521.5.121.5.221.5.321.621.6.121.6.221.6.321.6.421.7

Page 14: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

234Eval is Evil235Datenminimierung236HTTPS ist kein Allheilmittel237Letzte Worte

240Anhang: Weiterführende Informationen

240Einführung240Weblinks240www.php.net240www.phpdeveloper.org240devzone.zend.com241Buchtipps

242Lösungen

251Index

21.7.121.7.221.7.321.8

22

22.122.222.2.122.2.222.2.322.3

Page 15: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Diese Version der reset.php hat zwei Besonderheiten:

➤ In Zeile 8 müssen wir vor den Truncate-Befehlen die Fremdschlüsselprüfung deaktivierenund danach in Zeile 12 wieder aktivieren. Würden wir dies nicht tun, so würde das Trun-cate mit der Meldung Fatal error: Uncaught exception 'PDOException' withmessage 'SQLSTATE[42000]: Syntax error or access violation: 1701Cannot truncate a table referenced in a foreign key constraint verwei-gert.

➤ In den Zeilen 43 und 44 stellen wir dann eine bidirektionale Beziehung zwischen demUser - und dem Article -Objekt her.

Beispiel

1 <?php<?php23 require_oncerequire_once 'inc/functions.inc.php';4 require_oncerequire_once 'inc/helper.inc.php';56 require_oncerequire_once 'inc/config.inc.php';78 useuse ModelsModels\TagTag, ModelsModels\UserUser, ModelsModels\ArticleArticle;9

1010 $action = issetisset($_REQUEST$_REQUEST['action']) ? $_REQUEST$_REQUEST['action'] : null;11 $view = $action;1213 switchswitch($action) {14 // gekuerztes Beispiel1516 defaultdefault:17 $articles = $em18 ->getRepository('Models\Article')19 ->findAll()2020 ;2122 $view = 'index';23 breakbreak;24 }2526 require_oncerequire_once 'views/' . $view . '.tpl.php';2728 ?>?>

Listing 18.11 index.php - Version 1

1 <!DOCTYPE html>2 <html>34 <head>5 <meta charset="utf-8" />6 <title>Newsticker</title>7 </head>89 <body>

1010 <header>11 <h1>Newsticker</h1>12 </header>1314 <section>15 <?php<?php foreachforeach ($articles asas $article): ?>?>16 <article>17 <header>18 <h1><?php<?php echoecho $article->getTitle(); ?>?></h1>19 </header>202021 <div class="teaser">

160 18 Datenbank-Beziehungen mit Doctrine

Page 16: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

22 <?php<?php echoecho $article->getTeaser(); ?>?>23 </div>2425 <footer>26 Erstellt am27 <time datetime="<?php<?php echoecho$article->getCreated_at()->format('Y-m-d\TH:i:s'); ?>?>">28 <?php<?php echoecho $article->getCreated_at()->format('d.m.Y H:i'); ?>?>29 </time>3030 von <?php<?php echoecho $article->getUser(); ?>?>31 </footer>32 </article>33 <hr />34 <?php<?php endforeachendforeach; ?>?>35 </section>36 </body>3738 </html>

Listing 18.12 views/index.tpl.php - Version 1

Sobald Sie mittels EntityRepository#findAll() alle Datensätze der Entity Articleermittelt haben, können Sie diese ganz normal im Rahmen einer foreach -Schleife einzelnanzeigen. Von jedem Datensatz zeigen wir den Titel, den Teaser, den Erstellungszeitpunkt unddie Mail-Adresse des Erstellers an. Wir nutzen hierbei den Umstand, dass uns die MethodeArticle#getUser() das komplette User -Objekt zurückliefert.

Sie haben doch hoffentlich den Alternativschlüssel email in User als Rückgabewert der__toString() -Methode benutzt, oder haben Sie dies etwa vergessen? Würden wir vomUser beispielsweise den Wert des Attributs ID benötigen, so müssten wir stattdessen auf fol-gendes Chaining zurückgreifen $article->getUser()->getId() .

Aufgabe 3:

1. Implementieren Sie den aktuellen Stand der reset.php in Ihrem Projekt. Rufen Sieanschließend diesen Controller im Browser auf.

2. Implementieren Sie den aktuellen Stand der index.php und index.tpl.php in Ihrem Pro-jekt.

3. Überprüfen Sie die komplette Implementierung durch einen Aufruf der Standard-Aktion des Controllers index.php im Browser.

18.4 n:m-Beziehungen abbilden

Kommen wir nun zur Königsdisziplin unter den hier vorgestellten Datenbank-Beziehungen,der n:m-Beziehung zwischen Article und Tag .137 Ein Article kann beliebig viele Tags habenund zu einem Tag gehören meist mehrere Articles.

Doch welcher Teil der Beziehung soll nun unsere Eigentümer- und welcher die Gegenseitesein? Für n:m-Beziehungen liegt diese Entscheidung ja bei uns. Aus Programmierersichtgibt es jedoch oftmals einen einfachen Anhaltspunkt für diese Entscheidung. Sie müssen sichnur fragen, welche Entity die Verknüpfung handhabt, und diese als Eigentümerseite wählen.

137. Zu erkennen an der Zwischentabelle tagging .

18.4 n:m-Beziehungen abbilden 161

Page 17: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Beispiel

Betrachten wir das sehr ähnlich gelagerte Blogsystem WordPress, das ebenfalls Artikel (Posts)und Schlagwörter (Tags) bietet. Immer wenn Sie einen Artikel mit einem Schlagwort verknüp-fen wollen, managt der Artikel die Verknüpfung. Legt man nämlich einen neuen Artikel an, soerlaubt das entsprechende Formular die Auswahl bereits bestehender und das Anlegen neuerSchlagwörter. Aus diesem Grund würde man den Artikel als Eigentümerseite wählen.

18.4.1 Klasse Article und Klasse Tag

In unserem Newsticker könnte sich ein bereits existierender Benutzer einloggen, um danachTags oder Articles anzulegen. Wenn er neue Tags anlegt, so würde er dies vermutlich ohnedirekte Zuordnung zu Articles tun.138 Erst danach würde der Benutzer einen neuen Articleanlegen und dabei auswählen, welche der bereits existierenden Tags dem neuen Article zuge-ordnet werden sollen. Danach würden wir den Article speichern.

Im aktuellen Fall ist es also sinnvoll, die Entity Article als Eigentümerseite und die EntityTag als Gegenseite festzulegen. In der Klasse Article ergänzen wir zunächst ein Attribut$tags und in Tag nennen wir das Gegenstück $articles . Danach versehen wir beideAttribute mit einer @ORM\ManyToMany -Annotation.

Beispiel

/*** @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")*/

privateprivate $tags;

Listing 18.13 src/Models/Article.php - Annotation der Eigentümerseite

/*** @ORM\ManyToMany(targetEntity="Article", mappedBy="tags")*/

privateprivate $articles;

Listing 18.14 src/Models/Tag.php - Annotation der Gegenseite

Eigentümerseite Gegenseite

Klasse Article Tag

Annotation @ORM\ManyToMany @ORM\ManyToMany

ParametertargetEntity="Tag"inversedBy="articles"

targetEntity="Article"mappedBy="tags"

Tabelle 18.2 Zusammenfassung

Bei einer n:m-Beziehung muss in beiden Klassen im Konstruktor eine Sammlung für das ent-sprechende Attribut initialisiert werden. Für jede dieser Sammlungen benötigen wir anstatteines Setters die vier Delegator-Methoden.

138. So wie es derzeit auch bei der reset.php der Fall ist.

162 18 Datenbank-Beziehungen mit Doctrine

Page 18: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

18.4.2 Die Zwischentabelle

Für die n:m-Beziehung würde Doctrine die Zwischentabelle auf Basis einer Namenskonven-tion eigenständig als article_tag anlegen. Die Konvention besagt, dass der Tabellennameaus den beiden Klassennamen (ohne Namespace) und einem Unterstrich als Trenner gebildetwird. Genauso werden die Spaltennamen in der Zwischentabelle standardmäßig aus den bei-den Klassennamen gefolgt von einem _id gebildet.139

Wenn Ihnen die Namen egal sind, reduziert sich der Mapping-Code also auf ein Minimum. Inunserem Fall entspricht der Name der Zwischentabelle jedoch nicht der Datenbankplanung,wo als Name tagging vorgegeben wurde. Diese Änderung erreichen wir ganz einfach mitder Annotation @ORM\JoinTable , der wir als Parameter den gewünschten Tabellennamenübergeben können und die auf der Eigentümerseite ergänzt wird.

Beispiel

/*** @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")* @ORM\JoinTable(name="tagging")*/

privateprivate $tags;

Listing 18.15 src/Models/Article.php - Annotation der Eigentümerseite

/*** @ORM\ManyToMany(targetEntity="Article", mappedBy="tags")*/

privateprivate $articles;

Listing 18.16 src/Models/Tag.php - Annotation der Gegenseite

Aufgabe 4:

1. Ergänzen Sie in den Entity-Klassen Article und Tag die fehlenden Attribute undAnnotationen für die n:m-Beziehung.

2. Beide Entity-Klassen benötigen für die neuen Attribute die vier bekannten Delegator-Methoden. Setzen Sie diese inklusive der beiden Getter um.

3. Rufen Sie abschließend den Controller setup.php im Browser auf, um damit die nochfehlenden Tabellen und Spalten zu erstellen.

18.4.3 Ein Beispiel

Um mit der n:m-Beziehung ein wenig herumspielen zu können, müssen wir erneut den Con-troller reset.php anpassen.

139. Bei beiden Konventionen werden Kleinbuchstaben verwendet.

18.4 n:m-Beziehungen abbilden 163

Page 19: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Beispiel

1 <?php<?php23 require_oncerequire_once 'inc/config.inc.php';45 useuse ModelsModels\TagTag, ModelsModels\UserUser, ModelsModels\ArticleArticle;67 // Schritt 18 $em->getConnection()->query('SET FOREIGN_KEY_CHECKS=0;');9 $em->getConnection()->query('TRUNCATE TABLE tags;');

1010 $em->getConnection()->query('TRUNCATE TABLE users;');11 $em->getConnection()->query('TRUNCATE TABLE articles;');12 $em->getConnection()->query('TRUNCATE TABLE tagging;');13 $em->getConnection()->query('SET FOREIGN_KEY_CHECKS=1;');1415 // Schritt 216 $entries = arrayarray(17 arrayarray('title' => 'HTML'),18 arrayarray('title' => 'JavaScript'),19 arrayarray('title' => 'PHP')2020 );2122 foreachforeach ($entries asas $entry) {23 $tag = newnew TagTag($entry);24 $em->persist($tag);25 }2627 $entry = arrayarray(28 'email' => '[email protected]',29 'password' => 'Du_kommst_hier_nicht_rein!'3030 );31 $user = newnew UserUser($entry);32 $em->persist($user);3334 $em->flushflush();3536 // Schritt 337 $query = $em38 ->createQueryBuilder()39 ->select('t')4040 ->from('Models\Tag', 't')41 ->where('t.title = :title1 OR t.title = :title2')42 ->setParameters(arrayarray('title1' => 'HTML', 'title2' => 'PHP'))43 ->getQuery()44 ;45 $tags = $query->getResult();4647 $entry = arrayarray(48 'title' => 'Nur ein Test',49 'teaser' => 'Dies ist nur ein Test ...',5050 'news' => 'Erster Absatz' . "\n\n" . 'Zweiter Absatz'51 );52 $article = newnew ArticleArticle($entry);5354 $article->setPublish_at(55 newnew DateTimeDateTime('now')56 );5758 $user->addArticle($article);59 $article->setUser($user);606061 foreachforeach ($tags asas $tag) {62 $tag->addArticle($article);63 $article->addTag($tag);64 }6566 $em->persist($article);67

164 18 Datenbank-Beziehungen mit Doctrine

Page 20: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

68 $em->flushflush();697070 ?>?>71 Die Datenbankinhalte wurden angepasst.

Listing 18.17 reset.php - Version 2

Was hat sich im Controller geändert?

➤ In Zeile 12 wurde ein Truncate für die Tabelle tagging ergänzt.

➤ In Zeile 34 wurde ein Aufruf von EntityManager#flush() ergänzt.

➤ In den Zeilen 37 bis 45 lesen wir die Datensätze von zwei der drei Tags wieder aus derDatenbank aus. Dies wäre ohne das vorherige Flush (noch) nicht möglich, da die eigentli-che Speicherung ja erst durch dieses Flush stattfindet.

➤ In Zeile 41 habe ich zwei WHERE -Bedingungen direkt mit OR verknüpft. Die MethodeQueryBuilder#orWhere() ist hierfür also nicht zwingend nötig, verbessert aber oft-mals die Lesbarkeit des Codes.

➤ Die Zeilen 61 bis 64 dienen dann dazu, die Beziehung zwischen diesen beiden Tags undunserem Article herzustellen.

Auch der View index.tpl.php muss erneut angepasst werden.

Beispiel

1 <!DOCTYPE html>2 <html>34 <head>5 <meta charset="utf-8" />6 <title>Newsticker</title>7 </head>89 <body>

1010 <header>11 <h1>Newsticker</h1>12 </header>1314 <section>15 <?php<?php foreachforeach ($articles asas $article): ?>?>16 <article>17 <header>18 <h1><?php<?php echoecho $article->getTitle(); ?>?></h1>19 </header>202021 <div class="teaser">22 <?php<?php echoecho $article->getTeaser(); ?>?>23 </div>2425 <footer>26 Erstellt am27 <time datetime="<?php<?php echoecho$article->getCreated_at()->format('Y-m-d\TH:i:s'); ?>?>">28 <?php<?php echoecho $article->getCreated_at()->format('d.m.Y H:i'); ?>?>29 </time>3030 von <?php<?php echoecho $article->getUser(); ?>?>31 <br />32 Tags:33 <?php<?php echoecho implodeimplode(' ', $article->getTags()->toArray()); ?>?>34 </footer>35 </article>36 <hr />37 <?php<?php endforeachendforeach; ?>?>

18.4 n:m-Beziehungen abbilden 165

Page 21: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Adresse) öffentlich anzeigen. Beispielsweise könnten Sie Ihre User -Entity um ein Attribut$display_name erweitern, das Sie dann für die öffentliche Anzeige des Erstellers einesArticle benutzen.

Wenn Sie in einer Anwendung eine Loginprüfung umsetzen, so sollten erfolglose Anmelde-versuche immer nur mit einer kurzen Fehlermeldung ohne Angabe von Einzelheiten abge-lehnt werden. Insbesondere darf in einem solchen Fall nicht erkennbar sein, ob der eingege-bene Benutzername oder das Kennwort (oder beides) falsch ist. Unterlassen Sie die Umset-zung dieser Empfehlung, so kann ein Angreifer mit einem Wörterbuchangriff zunächst gültigeBenutzernamen ermitteln und hat somit schon die halbe Miete. Benutzen Sie zudem niemalstypische Benutzernamen wie admin, administrator, root oder superuser. Bei automatisier-ten Angriffen werden diese immer zuerst ausprobiert.

21.6.4 Browserfeatures

Seit etlichen Jahren verfügen die bekannten Browser (IE, Firefox, Chrome, Safari und Opera)über Features, die den Benutzer beim Besuch von Websites unterstützen sollen. Doch auchaus diesen eigentlich hilfreichen Features können sich schnell Probleme für uns als Entwicklerergeben. Ich möchte im Folgenden zwei dieser Features am Beispiel des Browsers Firefox vor-stellen und Ihnen zeigen, wie Sie diese zu Lasten des Benutzerkomforts deaktiveren können.

Formular-Autovervollständigung

Firefox merkt sich, welche Daten man in einzeilige Textfelder eingegeben hat. Nach einersolchen Eingabe ist diese beim nächsten Besuch der Webseite wieder verfügbar und wirdnach der Angabe des ersten Buchstabens als Vorschlag angezeigt.285 Um dies zu ermöglichen,reagiert der Browser auf eine Kombination von URL und Eingabefeldnamen.

Dieses Feature hört sich zunächst einmal toll an. Doch was ist, wenn Ihr Benutzer einmal kurzseinen Rechner verlassen muss und in dieser Zeitspanne ein Unbefugter Zugriff auf den Brow-ser hat? Der Angreifer bräuchte lediglich das erste Zeichen auszuprobieren und bekäme sofortden kompletten Benutzernamen serviert.

Beispiel

1 <form action="index.php?action=login" method="post">23 <label for="email">E-Mail</label>4 <input type="text" name="email" id="email" />56 <label for="password">Password</label>7 <input type="password" name="password" id="password" />89 <input type="submit" class="button" value="Anmelden" />

101011 </form>

Listing 21.34 views/login.tpl.php (Version 1)

Das Kennwort ist hiervon übrigens nicht betroffen, da es für password -Felder keine Vor-schlagsfunktionalität gibt. Trotzdem besteht auch eine Gefahr für dieses. Erst vor kurzem hatte

285. Siehe https://support.mozilla.org/de/kb/Formular-Autovervollstaendigung

21.6 Authentisierungssicherheit 231

Page 22: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

ich in meiner eigenen Familie den Fall, dass eine Login-Eingabe zu schnell erfolgte und dabeidie Tabulator-Taste nicht korrekt aktiviert wurde. Hierdurch landete eine kombinierte Eingabevon Benutzername und Passwort in den automatischen Vorschlägen für den Benutzernamen.Dank der anderen Vorschläge wäre es dann ein Leichtes gewesen, den Beginn des Kennwortszu identifizieren.

Passwort-Manager

Der Passwort-Manager von Firefox speichert die Benutzernamen und Kennwörter, die man aufWebseiten verwendet, und fügt sie beim nächsten Besuch automatisch in das Login-Formularein. Hierbei kann man als Benutzer entscheiden, ob eine Speicherung erfolgen soll oder nicht(bzw. nie).286

Dieses Feature kann gleich in mehreren Szenarien nachteilig sein:

1. Ein Cross-Site-Scripting-Angriff auf das Login-Formular: Ein Angreifer muss nicht erstauf die Eingabe der Daten durch den Benutzer warten, sondern kann diese sofort über-mitteln.

2. Ein Unbefugter mit direktem Browser-Zugriff: Der Angreifer sieht sofort den Benutzer-namen und kann bei ausreichend Zeit das Passwort ändern. Eine Anwendung sollte des-wegen vor einer solchen Änderung als zusätzliche Verteidigungslinie immer nach dembisherigen Kennwort fragen. Wenn der Angreifer jedoch genug Zeit hat, könnte er aucheine Browser-Erweiterung installieren, um vorübergehend die Sternchen im Passwortfeldzu demaskieren.287

3. Ein Unbefugter, der die Festplatte (bzw. den kompletten Rechner) entwendet oderDaten kopiert: Obwohl der Passwort-Manager die Zugangsdaten in einem verschlüssel-ten Format auf der Festplatte speichert, kann sich ein Angreifer mit ausreichend ZeitZugriff auf die Daten im Klartext verschaffen. Eine Speicherung als Hash ist nämlich nichtmöglich, da die Klartextwerte für die Zuweisung in die jeweiligen Felder des Login-For-mulars benötigt werden. Ich hoffe, Sie verwenden zumindest ein Masterkennwort(sofern Sie selbst einen Passwort-Manager verwenden), um so die benötigte Angriffszeitzu erhöhen.288

Um diese Probleme zu vermeiden, wurde seit dem Internet Explorer 5 (Firefox ab 0.9.4) dieUnterstützung des nicht standardisierten Attributs autocomplete in die Browser implemen-tiert. Es wird in den aktuellen Versionen von allen bekannten Browsern unterstützt und ist Teildes neuen HTML5-Standards.289

Beispiel

1 <form2 action="index.php?action=login" method="post"3 autocomplete="off"4 >5

286. Siehe https://support.mozilla.org/de/kb/passworter-verwalten-speichern-loeschen-aendern

287. Siehe https://addons.mozilla.org/en-us/firefox/addon/unhide-passwords/

288. Siehe auch die Maßnahme M 4.306: https://www.bsi.bund.de/DE/Themen/ITGrundschutz/ITGrundschutzKata-loge/itgrundschutzkataloge_node.html

289. Siehe https://developer.mozilla.org/en-US/docs/Mozilla/How_to_Turn_Off_Form_Autocompletion

232 21 Eine Einführung in das Thema Sicherheit

Page 23: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

6 <label for="email">E-Mail</label>7 <input type="text" name="email" id="email" />89 <label for="password">Password</label>

1010 <input type="password" name="password" id="password" />1112 <input type="submit" class="button" value="Anmelden" />1314 </form>

Listing 21.35 views/login.tpl.php (Version 2)

Das Attribut kann im öffnenden form -Tag ergänzt werden und deaktiviert so die Autovervoll-ständigung für alle Felder dieses Formulars.

Beispiel

1 <form action="index.php?action=login" method="post">23 <label for="email">E-Mail</label>4 <input5 type="text" name="email" id="email"6 autocomplete="off"7 />89 <label for="password">Password</label>

1010 <input11 type="password" name="password" id="password"12 autocomplete="off"13 />1415 <input type="submit" class="button" value="Anmelden" />1617 </form>

Listing 21.36 views/login.tpl.php (Version 2b)

Alternativ ist auch der Einsatz in einzelnen Formularfeldern möglich, was ich persönlich bevor-zuge.290

Das Attribut autocomplete funktioniert mit folgenden Typen des input-Tags: text, pass-word, search, url, tel, email, range, color und den Datumstypen.291

Wichtig ist jedoch, dass das Attribut lediglich als Empfehlung an den Browser angesehenwerden kann. Da es sich um eine Angabe im HTML-Quelltext einer Webseite handelt, kannein Benutzer diese »Gängelung durch den Seitenbetreiber«292 mittels Browser-Erweiterung293

umgehen.

Sollten Sie das Attribut aus irgendeinem Grund nicht einsetzen wollen, so ist eine dynamischeÄnderung des name -Attributs der Formularfelder zumindest hilfreich bei den ersten beidenSzenarien. Um dies zu erreichen, könnten Sie beispielsweise mit PHP bei jedem Formularaufrufein (zufälliges) Präfix festlegen, in der Session speichern und vor jedem Wert im name -Attributder betreffenden Formularfelder einfügen.294

290. Siehe aktuell.de.selfhtml.org/artikel/html/autocomplete/

291. Siehe www.torbenleuschner.de/blog/601/html5-formulare-neue-input-types-attribute-und-mehr/

292. Siehe www.knetfeder.de/linux/index.php?id=126

293. Siehe https://addons.mozilla.org/de/firefox/addon/remember-passwords/

21.6 Authentisierungssicherheit 233

Page 24: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

21.7 Ein paar grundsätzliche Hinweise

In den bisherigen Kapiteln dieser Lektion bin ich relativ ausführlich auf einzelne Themen ein-gegangen. Im Folgenden möchte ich kurz ein paar ergänzende Themenbereiche anreißen,damit Sie auch diese auf dem Radar haben.

21.7.1 Eval is Evil

Das Sprachkonstrukt eval() wertet eine Zeichenkette als PHP-Code aus.295

Beispiel

evaleval('echo "Hallo Welt!";');

Listing 21.37 eval() - Beispiel 1

Der Beispiel-Code würde tatsächlich den echo -Befehl ausführen, obwohl er nur als String vor-liegt. Eigentlich ganz einfach, oder? Ja und nein. Solange es sich bei dem String nicht um eineBenutzereingabe handelt, haben Sie auch kein wirkliches Sicherheitsproblem. Falsch ange-wendet, ergeben sich für einen Angreifer jedoch einige interessante Möglichkeiten.

Beispiel

$method = $_GET$_GET['method'];evaleval('Foo::' . $method . '();');

Listing 21.38 eval() - Beispiel 2

In diesem Beispiel verwenden wir direkt eine Benutzereingabe aus $_GET , um eine statischeMethode der Klasse Foo aufzurufen. Den Code habe ich so bei meinen Recherchen gefundenund er soll tatsächlich in der freien Wildbahn anzutreffen gewesen sein. Dies kann nundadurch ausgenutzt werden, dass nicht nur der Name der Methode (z.B. bar ) übergebenwird, sondern ähnlich wie bei einer SQL-Injection zusätzlicher Code angehängt wird.

Beispiel

1 <?php<?php23 classclass FooFoo4 {5 publicpublic staticstatic functionfunction barbar() {6 // Der Inhalt ist nicht relevant7 }8 }9

1010 $method = $_GET$_GET['method'];11 evaleval('Foo::' . $method . '();');1213 ?>?>

294. Alternativ kann das Präfix auch mittels eines versteckten Formularfelds (natürlich ohne Präfix im name -Attribut)zu den restlichen Formulardaten ergänzt werden.

295. Der Hinweis auf die Gefährlichkeit fehlt übrigens derzeit auf der deutschen php.net-Website, weswegen ich siehier nicht verlinke. Siehe auch: www.php.net/manual/en/function.eval.php

234 21 Eine Einführung in das Thema Sicherheit

Page 25: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

14 <html>15 <body>16 <?php<?php echoecho urldecodeurldecode($method); ?>?><br />17 <?php<?php var_dumpvar_dump($_SESSION$_SESSION); ?>?>18 </body>19 </html>

Listing 21.39 eval() - Beispiel 3

Versuchen Sie nun einmal, die Datei mit folgender Angabe aufzurufeneval.php?method=bar%28%29%3B%24_SESSION%5B%22user_id%22%5D%3D1%3B%2F%2F .Wenn der Aufruf korrekt war, so sollten Sie nun erkennen können, was die Attacke bewirkt hat.In diesem Fall wurde nämlich nicht nur die Methode Foo#bar() aufgerufen, sondern auchder User mit der ID 1 eingeloggt.296

Aus gutem Grund hat Rasmus Lerdorf (der Erfinder von PHP) einmal geschrieben: »If eval() isthe answer, you're almost certainly asking the wrong question« (dt. »Wenn eval() die Antwortist, stellst Du sehr wahrscheinlich die falsche Frage«). Aber ist eval() wirklich böse? Persön-lich stimme ich hierbei mit Dan Horrigan überein, der in einem Blog-Beitrag297 2012 schrieb,dass man sich vor einer Verwendung fragen sollte: »Will this code run in production with userinput?« Wenn es sich um ein produktives Umfeld mit Benutzereingaben handelt, sollten Sieeval() auf keinen Fall verwenden.298

Das Problem dieses Kapitels, eine variable Funktion bzw. Methode aufrufen zu müssen, hattenwir übrigens schon einmal ganz zu Anfang bei den magischen Methoden (siehe Lektion 7).Dort haben wir zum Aufruf der Setter die sogenannten Variablenfunktionen verwendet,d.h. wir können einfach Foo::$method(); schreiben und somit in diesem Fall komplett aufeval() verzichten. Zudem würde eine Zeichen- oder Array-basierte Whitelist für $methodSinn machen.

Sofern man eval() nicht benötigt, könnte man in Versuchung geraten, eine kompletteDeaktivierung mit der php.ini-Direktive disable_functions vorzunehmen.299 Da es sichbei eval() jedoch um ein Sprachkonstrukt und nicht um eine Funktion handelt, ist dies(derzeit) nicht möglich.300

21.7.2 Datenminimierung

Schafft es trotz aller bisherigen Maßnahmen ein Angreifer, sich Zugriff auf die Datenbank einerAnwendung zu verschaffen, dann muss sich zunächst der Betreiber und dann auch der Ent-wickler verantworten. Aber auch sonst sollten Sie die Daten Ihrer Benutzer nicht einfach offenherumliegen lassen, jeder E-Mail-Harvester301 und »Social Bot«302 würde sich hierüber nämlichtierisch freuen. Beachten Sie bei der Umsetzung einer Web-Anwendung deswegen unbedingtein paar einfache Regeln:

296. Sofern noch keine Datensätze gelöscht wurden, wird diese ID in unserer users -Tabelle existieren.

297. Siehe auch: dhorrigan.com/post/30395987906/is-eval-really-evil-yes-and-no

298. Außer man weiß wirklich was man tut und ist wirklich sicher, dass der auszuführende Code sicher ist.

299. Siehe www.php.net/manual/de/ini.core.php#ini.disable-functions

300. Siehe auch: https://bugs.php.net/bug.php?id=62397

301. Siehe de.wikipedia.org/wiki/E-Mail-Harvester

302. Siehe t3n.de/news/facebook-daten-sammeln-leicht-gemacht-bots-greifen-339946/

21.7 Ein paar grundsätzliche Hinweise 235

Page 26: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

1. Speichern Sie immer nur die Daten, die für den Betrieb Ihrer Anwendung zwingend nötigsind.

2. Wenn Besucher sich Profile anderer Benutzer ansehen dürfen, so sollte dies nur einge-loggten Benutzern möglich sein.

3. Lassen Sie jeden Benutzer über sogenannte Privatsphären-Einstellungen selbst entschei-den, welche Informationen (beispielsweise im Benutzerprofil) öffentlich zugänglich sind.

4. Ist die Anzeige einer sensitiven Information unvermeidlich, so sollte möglichst nur ein Teildieser Information angezeigt werden. Amazon zeigt in der abschließenden Übersichteines Bestellvorgangs beispielsweise nur die letzten zwei Stellen einer Kontonummer an.Dies entspricht weniger als 30% der Gesamtinformation und ist ein guter Richtwert.

21.7.3 HTTPS ist kein Allheilmittel

Secure Sockets Layer (SSL) ist ein hybrides Verschlüsselungsprotokoll303 zur Datenübertra-gung im Internet. Gleichzeitig kann ein Benutzer anhand eines sogenannten Zertifikats304 dieIdentität einer Website verifizieren. Ab Version 3.0 wurde das SSL-Protokoll unter dem NamenTLS (Transport Layer Security)305 weiterentwickelt. TLS 1.0 meldet sich übrigens im Headernoch als Version SSL 3.1.

TLS-Verschlüsselung wird heute vor allem bei HTTPS (Hypertext Transfer Protocol Secure)306

eingesetzt. Hierbei handelt es sich um ein Kommunikationsprotokoll zur abhörsicherenDatenübertragung zwischen Webserver und Browser. Ohne eine solche Verschlüsselung sindfür jeden Angreifer, der Zugriff auf den Datenverkehr hat, alle übertragenen Daten im Klartextlesbar. Sobald sensitive Daten zwischen Browser und Webserver übertragen werden (bei-spielsweise Zahlungsinformationen) sollte immer HTTPS eingesetzt werden. Wenn es um sen-sitive Daten aus den Bereichen Finanzen und Gesundheit geht, so wird die Verwendung vonHTTPS von den Benutzern grundsätzlich erwartet und das Fehlen des »goldenen Schlosses«nicht akzeptiert.

HTTPS ist jedoch kein Allheilmittel, da die benutzte Version von SSL/TLS von der Konfigurationdes Webservers und dem verwendeten Browser bzw. Betriebssystem abhängig ist. Je älterdiese Version ist, desto größer ist die Wahrscheinlichkeit, dass es inzwischen bekannteAngriffsmöglichkeiten gibt. So wurden beispielsweise Anfang 2013 Schwachstellen bekannt,die SSL 3.0, TLS 1.1 und 1.2 307 bzw. TLS 1.0 und 1.1 308 angreifbar machen. Durch die Enthüllun-gen von Edward Snowden wurde Anfang September 2013 bekannt, dass es der NSA bereits seit2010 möglich sein soll, »gängige Internet-Verschlüsselungsmethoden zu umgehen«.309 Selbstwenn Sie eine noch nicht angreifbare TLS-Version nutzen sollten, schützt dies jedoch ledig-lich die Übertragung der Daten.310 Sind die Daten erstmal auf dem Webserver bzw. im Browserangekommen, so können sie dort dennoch eine schädliche Wirkung entfalten.

303. Siehe de.wikipedia.org/wiki/Hybride_Verschl%C3%BCsselung

304. Siehe de.wikipedia.org/wiki/Digitales_Zertifikat

305. Siehe de.wikipedia.org/wiki/Transport_Layer_Security

306. Siehe de.wikipedia.org/wiki/Hypertext_Transfer_Protocol_Secure

307. Siehe www.golem.de/news/lucky-thirteen-sicherheitsluecke-in-tls-dtls-und-ssl-1302-97358.html

308. Siehe www.golem.de/news/ssl-tls-schwaechen-in-rc4-ausnutzbar-1303-98164.html

309. Siehe t3n.de/news/nsa-gchq-ssl-verschlusselung-prism-492991/

310. SSL ist ein "auf-der-Leitung" Protokoll.

236 21 Eine Einführung in das Thema Sicherheit

Page 27: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

21.8 Letzte Worte

In den komplexen »Öko-Systemen«, in welchen sich Web-Anwendungen heutzutage bewe-gen, reicht eine Absicherung nur der der Anwendung nicht aus. Auch die restlichen Software-Komponenten, die Hardware (Server- und Netzwerkkomponenten) und die verwendetenRäumlichkeiten sollten neben den eigentlichen Benutzern Bestandteil eines umfassendenSicherheitskonzeptes sein. Schließlich könnte auch ein Angreifer, der über einen dieser WegeZugriff erlangt, für Sie und Ihre Anwendung gefährlich werden.

Bedenken Sie zudem, dass Sie im Falle eines Falles immer ein aktuelles Backup Ihrer Anwen-dung zur Hand haben sollten. Dies betrifft sowohl die Dateien der Anwendung (inklusive mög-licherweise vorhandenen Benutzer-Uploads) als auch die Inhalte der Datenbank. Es nützt übri-gens nicht viel, wenn eine solche Datensicherung auf dem gleichen Gerät wie die eigentlicheAnwendung gespeichert wird und somit beides von einem Hardwaredefekt betroffen wäre.Am besten ist es sogar, wenn Ihre Sicherungen an einem komplett anderen Ort aufbewahrtwerden, damit ein Feuer nur eines von beidem vernichten kann.

Sie sollten auch immer die Neuigkeiten in der PHP-Welt im Blick behalten. So sind Sie früh-zeitig informiert, wenn es gravierende Änderungen am Öko-System Ihrer Anwendung gebensollte, und können ohne Zeitdruck die nötigen Anpassungen planen und umsetzen.311 Per-sönlich lese ich beispielsweise möglichst täglich den Newsticker von <?PHPDeveloper.org unddes deutschsprachigen PHPmagazins.

➤ phpdeveloper.org/archive/

➤ phpmagazin.de/news/.

Nehmen Sie sich abschließend einen Satz aus dem fliegenden Klassenzimmer von Erich Käst-ner zu Herzen: »An jedem Unfug, der passiert, sind nicht nur die schuld, die ihn begehen, son-dern auch die, die ihn nicht verhindern«.312 Versuchen Sie also immer das Möglichste, um dieIntegrität Ihrer Anwendung nicht zu gefährden.

Testen Sie Ihr Wissen

1. Welche Daten eines Benutzers sind sicher?2. Ist eine absolute Risiko-Eleminierung bei einer Web-Anwendung möglich?3. Welche fünf Tugenden sollte sich ein sicherheitsbewusster Entwickler angewöhnen?4. Unter welcher Prämisse sollte man heutzutage Anwendungen entwickeln?5. Wieso ist ein Whitelist-Ansatz einer Blacklist meist überlegen?6. Was ist die primäre Maßnahme zum Schutz einer Anwendung gegen SQL-Injections?7. Was ist der Unterschied zwischen persistentem und reflektiertem Cross-Site-Scripting?8. Welche Möglichkeiten hat ein Angreifer, um an das Kennwort eines Benutzers zu gelan-

gen? Gehen Sie in diesem Fall von einer Anwendung ohne gravierende Sicherheitslückenaus.

9. Was ist der wichtigste Unterschied zwischen Verschlüsselung und Hashing?10. Reicht HTTPS als alleinige Verteidigungslinie für eine Web-Anwendung aus?

311. Nichts ist schlimmer, als wenn eine Anwendung nach dem Update einer Komponente für längere Zeit ausfällt.

312. Siehe de.wikipedia.org/wiki/Das_fliegende_Klassenzimmer

21.8 Letzte Worte 237

Page 28: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Aufgaben zur Selbstkontrolle

Beispiel

1 <?php<?php23 // gekuerztes Beispiel45 functionfunction log_inlog_in($id)6 {7 $_SESSION$_SESSION['user_id'] = $id;8 }9

1010 functionfunction is_logged_inis_logged_in()11 {12 returnreturn (issetisset($_SESSION$_SESSION['user_id']) && !emptyempty($_SESSION$_SESSION['user_id']));13 }1415 functionfunction log_outlog_out()16 {17 unsetunset($_SESSION$_SESSION['user_id']);18 }192020 ?>?>

Listing 21.40 inc/functions.inc.php

Aufgabe 7:

Implementieren Sie den letzten Stand des Views login.tpl.php und die drei Funktionenlog_in(), is_logged_in() und log_out() in Ihrem Projekt. Außerdem benötigen wirim View _navi.tpl.php unter Register einen neuen Link Login.

Aufgabe 8:

Setzen Sie nun die Aktion login um. Wenn Formulardaten vorhanden sind, soll sie einObjekt der User-Entity anhand der eingegebenen E-Mail-Adresse ermitteln. Wird einObjekt gefunden und stimmt das Password mit der Formulareingabe überein, so soll dieFunktion log_in() aufgerufen werden.313 Erzeugen Sie außerdem eine Flash-Notice, dieden erfolgreichen Login bestätigt. Machen Sie dann eine Header-Umleitung zur Start-seite. Falls Formulardaten vorhanden sind, diese aber nicht korrekt sind, so befüllen Siedie Variable $errors mit einem Array. Dieses Array soll als einzigen Wert den String'Fehlerhafte Logindaten!' haben.314

Aufgabe 9:

Passen Sie nun die _navi.tpl.php erneut an. Die Register- und Login-Links sollen nurnoch angezeigt werden, wenn der User noch nicht eingeloggt ist. Ist er eingeloggt, so sol-

313. Als Parameter müssen Sie die ID des Objekts verwenden.

314. Da wir hier keine Header-Umleitung machen, benutzen wir auch keine Flash-Notice.

238 21 Eine Einführung in das Thema Sicherheit

Page 29: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

len stattdessen die Links zum Erstellen von Tags bzw. Articles und ein Logout-Link ange-zeigt werden. Benutzen Sie als Bedingung die Funktion is_logged_in().

Aufgabe 10:

Benutzen Sie diese Funktion nun auch, um die Links zum Bearbeiten und Löschen vonArticle-Datensätzen nur noch bei eingeloggten Benutzern anzuzeigen.

Aufgabe 11:

Setzen Sie die Aktion logout um. Diese soll den User mit der Funktion log_out() aus-loggen, eine Flash-Notice anlegen und dann auf die Startseite des Newstickers weiterlei-ten.315

Optionale Aufgaben

Aufgabe 12:

Das Begleitmaterial enthält einen »finalen« Stand des Newstickers. Dieser verwendetPasswort-Hashes, ein zusätzliches Attribut $display_name in der User-Entity (inkl. Vali-dierung) und beschränkt in der index.php den Zugriff auf manche Aktionen.316 Installie-ren Sie diesen Stand, welcher die neue Datenbank newsticker_final verwenden soll,auf Ihrem Entwicklungssystem.317 Vollziehen Sie die Änderungen bzw. Inhalte der nach-folgenden Dateien nach:

➤ src/Models/User.php

➤ src/Repositories/UserRepository.php

➤ src/Validators/UserValidator.php

➤ views/edit_user.tpl.php

➤ index.php (z.B. Zugriffsbeschränkung über dem Switch und Änderungen in den Aktio-nen add_article bzw. login)

➤ reset.php

315. Einen View benötigen Sie somit nicht.

316. Ein alleiniges Verstecken der Links reicht nicht aus, es muss auch ein Aufruf bei manuell eingegebenen URLsverhindert werden. Ich habe mich hierbei ausnahmsweise für eine Blacklist entschieden, da aktuell nur einSchutz für Add, Edit und Delete nötig ist.

317. Denken Sie daran, die Datenbanktabellen durch einen Aufruf der setup.php zu erstellen und diese mit derreset.php zu befüllen. Welche Datei verhindert noch einmal die Ausführung dieser beiden Controller im Brow-ser?

21.8 Letzte Worte 239

Page 30: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

22 Anhang: WeiterführendeInformationen

In dieser Lektion lernen Sie:

➤ wo Sie interessante, weiterführende Quellen zum Thema PHP finden.

22.1 Einführung

Nach dem langen Weg durch dieses Lernbuch muss ich Ihnen leider sagen, dass das nochlange nicht alles war, was es zum Thema PHP oder OOP zu wissen gibt.318 Deshalb habe ichIhnen in der letzten Lektion einige interessante Webseiten und Bücher zusammengestellt,über die Sie weiterführende Informationen rund um PHP erhalten.

22.2 Weblinks

22.2.1 www.php.net

Die offizielle Seite der PHP-Entwickler bietet nicht nur eine Übersicht über alle PHP-Funktio-nen, sondern auch ein Handbuch in deutscher Sprache. Dieses Handbuch versteht sich selbsteher als Referenz denn als Lernheft. Folglich sind auch die Erklärungen und Beispiele effizi-ent, aber eher knapp gehalten. Die Seite eignet sich sehr gut, um in Ihrem PHP-Wissen gezieltLücken zu füllen. Als entspannte Abend-Lektüre würde ich sie weniger empfehlen.

22.2.2 www.phpdeveloper.org

<?PHPDeveloper.org ist eine Kommunikationsplattform rund um PHP. Sie finden dort eineÜbersicht von Neuigkeiten aus der PHP-Welt, Informationen über Konferenzen, Jobangebote,aktuelle Diskussionen und eine Übersicht der interessantesten Fachartikel der letzten Zeit.

22.2.3 devzone.zend.com

In der Entwickler-Community von ZEND, den Entwicklern von PHP, finden Sie interessante undoft sehr aktuelle, aber doch recht fortgeschrittene Artikel (engl. Tutorials) zum Thema PHP. DieSeite wird für Sie umso wichtiger werden, je mehr Sie über PHP wissen.

318. Sonst wäre dieses Buch mehrere tausend Seiten dick und das Wort »alles« wäre immer noch gelogen.

240 22 Anhang: Weiterführende Informationen

Page 31: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

22.3 Buchtipps

Die Lektion zum Thema Sicherheit basiert auf den nachfolgenden Quellen. Die Lektion bietetjedoch aus Platzgründen lediglich einen Querschnitt der dortigen Themen.

Christopher Kunz, Stefan Esser, Peter Prochaska: PHP-Sicherheit. PHP/MySQL-Webanwen-dungen sicher programmieren. 2. aktualisierte und überarbeitete Auflage, dpunkt.verlag 2007(ISBN-13 978-3898644501)

Tobias Wassermann: Sichere Webanwendungen mit PHP, mitp 2007 (ISBN-13978-3826617546)

Chris Snyder, Thomas Myer, Michael Southwell: Pro PHP Security. From Application SecurityPrinciples to the Implementation of XSS Defenses. Second Edition, Apress 2010 (ISBN-13978-1430233183)

Ich kann Ihnen nur ans Herz legen: Verlassen Sie sich nicht nur auf meine Kurzübersicht,sondern lesen Sie die ausführlicheren Originale (auch wenn sie oftmals etwas veraltetsind)!

22.3 Buchtipps 241

Page 32: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Lösungen

Lektion 2: Übungen

Lektion 3: Testen Sie Ihr Wissen

1. Was ist in der Objektorientierung ein Objekt?

Ein Objekt in der Programmierung (auch Instanz genannt) ist vergleichbar mit den greifba-ren Objekten bzw. Gegenständen der realen Welt. Jedes Objekt gehört zu einer bestimm-ten Objektgruppe und verfügt über eine bestimmte Anzahl von Eigenschaften, die beiallen Objekten einer Gruppe vorhanden sind. Im Gegensatz zur realen Welt liegt jedochkeine Betonung auf greifbar, d.h. auch die Gruppen Flüssigkeit, Gas und Lebewesen sindnicht ausgeschlossen.

2. Was ist eine Klasse?

Bei dem Begriff Klasse handelt es sich um den aus dem englischen abgeleiteten Fachbe-griff für eine Objektgruppe. Sie stellt eine Art Bauplan bei der Instanziierung von Objektendar.

3. Was sind Attribute?

Attribute sind die Eigenschaften, die ein Objekt hat bzw. haben kann. Sie werden im Nor-malfall in der Klasse definiert und mit einem Standardwert befüllt.

4. Wie können Sie in PHP aus einer Klasse ein Objekt instanziieren?

Dies geht beispielsweise, indem Sie das Schlüsselwort new und den Namen der Klasse ver-wenden und das Ergebnis einer Variablen zuweisen: $sparbuch = new Konto();

5. Auf was bezieht sich die Variable $this$this ?

Auf das aktuelle Objekt, in dem Sie sich gerade befinden. Wann immer Sie in einer Klasseauf ein Attribut oder eine Methode einer Instanz dieser Klasse zugreifen wollen, müssenSie die spezielle Variable$this

verwenden.

6. Was unterscheidet Methoden von Funktionen?

Methoden werden in Klassen definiert und sind an deren Instanzen gebunden. Methodenkönnen über das Schlüsselwort $this auf die Attribute und andere Methoden einerInstanz zugreifen. Ansonsten verhalten sie sich wie Funktionen.

7. Wie können Sie eine Methode eines Objektes aufrufen?

Dies geht mit der Schreibweise $objekt->nameDerMethode() , wobei $objekt eineVariable sein muss, in der eine Instanz der gewünschten Klasse abgelegt ist.

242 Lösungen

Page 33: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Lektion 3: Übungen

Lektion 4: Testen Sie Ihr Wissen

1. Was unterscheidet Getter- und Setter-Methoden von normalen Methoden?

Technisch gesehen sind es ganz normale Methoden, also nichts.

2. Warum ist Ihr Code besser wartbar, wenn Sie Attribute über Methoden verändernstatt direkt?

Da Sie auf diese Weise in das Ändern des Attributs eingreifen können, um den Wert zu prü-fen oder zu ändern, ohne dass man davon außen etwas bemerkt.

3. Wie können Sie auf ein Attribut nur lesenden Zugriff erlauben?

Sie markieren das Attribut als private und schreiben nur einen Getter.

Lektion 4: Übungen

Lektion 5: Testen Sie Ihr Wissen

1. Wie können Sie eine Methode desselben Objektes von einer anderen Methode ausaufrufen?

$this->methodenName()

2. Können Sie Objekte in der Session speichern?

Ja!

3. Was testet der Operator instanceofinstanceof ?

Er testet, ob eine Variable ein Objekt enthält, das aus einer bestimmten Klasse erzeugtwurde, also z.B. $test instanceof TestKlasse überprüft, ob in $test eine Instanzvon TestKlasse gespeichert ist.

Lektion 5: Übungen

Lektion 6: Testen Sie Ihr Wissen

1. Was unterscheidet virtuelle Attribute von echten Attributen?

Virtuelle Attribute sind nicht ausdrücklich in der Klasse definiert. Sie verfügen aber überGetter und Setter, die deren Existenz vorgaukeln.

2. Unter welchen Umständen sind virtuelle Attribute nützlich?

Wenn Sie mehrere Attribute zur Verfügung stellen wollen, die sich aber aus einer Daten-quelle ableiten.

3. Was ist bei Settern von virtuellen Attributen zu beachten?

Diese Setter verändern nicht die virtuellen, sondern echte Attribute, die selbst ebenfallsSetter haben. Sie müssen dafür sorgen, dass sich diese Setter nicht in die Quere kommen.

22.3 Buchtipps 243

Page 34: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Lektion 6: Übungen

Lektion 7: Testen Sie Ihr Wissen

1. Was versteht man unter einer magic method?

Magische Methoden sind Methoden, die von PHP automatisch aufgerufen werden, wennein vordefiniertes Ereignis eintritt. Sie haben festgelegte Namen.

2. Wann wird die Methode __toString()__toString() eines Objektes aufgerufen?

Sobald Sie ein Objekt als String behandeln, also z.B. versuchen, es mit echo auszugeben.

3. Wann wird die Methode __construct()__construct() eines Objektes aufgerufen?

Jedes Mal, wenn Sie ein neues Objekt erzeugen.

4. Benötigt jede Klasse eine Konstruktor-Methode?

Es ist keine zwingende Voraussetzung. Wenn es nichts für einen Konstruktor zu tun gibt,können Sie ihn selbstverständlich weglassen.

5. Sie haben ein PersonPerson -Objekt in der Variable $person$person und möchten dessen Inhaltals Text verwenden. Was müssen Sie aufrufen?

echo $person oder $person->__toString()

Lektion 7: Übungen

Lektion 8: Testen Sie Ihr Wissen

1. Wie können Sie ein Objekt in einem anderen Objekt ablegen?

Indem das innere Objekt als Attribut des anderen Objekts abgelegt wird.

2. Wie können Sie auf die Attribute des innen abgelegten Objekts zugreifen?

Über virtuelle Attribute, die auf die Attribute des inneren Objekts zugreifen.

3. Warum sollten Sie bevorzugt ganze Objekte als Parameter an Methoden übergeben?

Es macht Ihren Code robuster gegen Änderungen, da Sie weniger Informationen über IhreKlassen nach außen dringen lassen.

Lektion 8: Übungen

Lektion 9: Testen Sie Ihr Wissen

1. Auf welche Sprachelemente sollte sich der PHP-Code in Templates beschränken?

Nach Möglichkeit auf echo , Schleifen und if-else -Anweisungen.

244 Lösungen

Page 35: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

2. Warum sollten Sie so wenig PHP wie möglich in Templates verwenden?

Um so weit wie möglich HTML von PHP-Code zu trennen. Auf diese Weise ist der PHP-Teilübersichtlicher und der HTML-Teil kann leichter von Webdesignern ohne PHP-Kenntnisseangepasst werden.

3. Welche Aufgabe hat der Controller?

Der Controller entscheidet, welche Aktion beim Aufruf der PHP-Seite ausgeführt werdensoll.

4. Wie kann der Controller entscheiden, welche Aktion er ausführen soll?

Über eine Variable, die beim Aufruf der Seite mit übergeben wird, beispielsweise$_REQUEST['action'] .

5. Warum sollte es eine Standard-Aktion geben?

Falls kein Parameter übergeben wurde, muss trotzdem eine Aktion ausgeführt werden.

Lektion 9: Übungen

Lektion 10: Testen Sie Ihr Wissen

1. Wie viele Klassen repräsentieren normalerweise eine Datenbank-Tabelle, wenn SieActive Record verwenden?

Nur eine.

2. Wie viele Objekte erhalten Sie in PHP, wenn Sie mit Active Record 30 Datensätze ausder DB auslesen?

30 Objekte, eines für jeden Datensatz.

3. Wie viele Klassen repräsentieren normalerweise eine Datenbank-Tabelle, wenn SieData Mapper verwenden?

Zwei Klassen, eine für die Datenhaltung und eine für die Datenverwaltung (speichern,löschen usw.).

4. Wie viele Objekte erhalten Sie in PHP, wenn Sie mit dem Data Mapper 30 Datensätzeaus der DB auslesen?

31! 30 Objekte der Datenklasse und ein Objekt des Mappers.

Lektion 11: Testen Sie Ihr Wissen

1. Welche Konsolenbefehle von Composer haben Sie kennengelernt?

php composer.phar -V , php composer.phar self-update und phpcomposer.phar install

2. Was erspart Ihnen die __autoload()__autoload() -Funktion?

Die Funktion erspart hauptsächlich viel Schreibarbeit und zudem die vorherige Festlegungder benötigten Klassen von Drittanbietern.

22.3 Buchtipps 245

Page 36: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Lektion 11: Übungen

Lektion 12: Testen Sie Ihr Wissen

1. Nennen Sie Beispiele für Namespaces jenseits der PHP-Programmierung.

z.B. Dateiverzeichnisse, Postleitzahlen und Telefonvorwahlen

2. Was muss jede Entity enthalten, damit sie von Doctrine als solche erkannt wird? Esgibt drei Möglichkeiten, wir haben in dieser Lektion aber nur eine benutzt.

Annotationen

3. Überlegen Sie, ob jedes Attribut Annotationen (z.B. @@ORM\ColumnORM\Column ) benötigt.

Attribute, die nicht von Doctrine in der Datenbank gespeichert werden sollen, benötigenauch keine Annotationen. Solche Attribute sind allerdings relativ selten.

Lektion 12: Übungen

Lektion 13: Testen Sie Ihr Wissen

1. Wie nennt man die Schnittstelle zu Doctrine, die man zum Auslesen, Speichern undLöschen von Datensätzen nutzt?

EntityManager

2. Es gibt eine Namenskonvention für die Variable, in der das Objekt dieser Schnitt-stelle liegt. Wie lautet diese?

$em

Lektion 13: Übungen

Lektion 14: Testen Sie Ihr Wissen

1. Reicht es, die Methode persist()persist() aufzurufen, um ein Objekt zu speichern?

Nein. Erst wenn man die Methode EntityManager::flush() aufruft, werden alle SQL-Anweisungen ausgeführt, die sich bis zu diesem Zeitpunkt angesammelt haben. Alternativkönnte man auch bis zum Ende des Requests warten, wo dann ein automatisches Flushingstattfindet.

2. Wie nennt man das Vorgehen, Aufgaben zu sammeln und am Stück abzuarbeiten?

Unit of Work

246 Lösungen

Page 37: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Lektion 14: Übungen

Lektion 15: Testen Sie Ihr Wissen

1. Was repräsentiert bei Doctrine eine Tabelle mit allen enthaltenen Datensätzen unddient gleichzeitig dazu, Datensätze nach bestimmten Kriterien auszulesen?

Die Tabelle wird durch ihr EntityRepository repräsentiert, welches man mit der MethodeEntityManager#getRepository() erhält.

Lektion 15: Übungen

Lektion 16: Testen Sie Ihr Wissen

1. Welche zwei Möglichkeiten existieren, um komplexere Datenbank-Abfragen mitDoctrine umzusetzen?

DQL und der QueryBuilder

Lektion 16: Übungen

Lektion 17: Testen Sie Ihr Wissen

1. Welche Alternative(n) zur Unmenge von Datums- und Zeitfunktionen haben Sie indieser Lektion kennengelernt?

Die Klasse DateTime bzw. Webmasters\Doctrine\ORM\Util\DateTime

2. Womit kann man automatisiert ein Erstellungs- oder Aktualisierungsdatum in einemAttribut pflegen?

Mit der Annotation @Gedmo\Timestampable

Lektion 17: Übungen

Lektion 18: Testen Sie Ihr Wissen

1. Wie definiert man Beziehungen zwischen Doctrine-Entities?

Man benötigt in beiden Entities ein neues Attribut und versieht dieses mit Annotationen.

2. Genauer gefragt, was nutzt man, um eine 1:n-Beziehung abzubilden?

Auf der 1(One)-Seite der Beziehung nutzt man die Annotation @ORM\OneToMany und aufder n-Seite benötigt man ein @ORM\ManyToOne .

3. Und was nutzt man, um eine n:m-Beziehung abzubilden?

Auf beiden Seiten nutzt man eine @ORM\ManyToMany -Annotation. Diese unterscheidensich allerdings in ihren Attributen ( mappedBy bzw. inversedBy ).

22.3 Buchtipps 247

Page 38: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

4. Welche vier Delegator-Methoden haben Sie kennengelernt?

Sie kennen inzwischen sieben Methoden der Klasse ArrayCollection , aber wir nutzennur vier davon im Rahmen der Delegator-Methoden clear , add , has und remove .

5. Was ist Lazy Loading?

Als Lazy Loading bezeichnet man das Nachladen von Daten bei Bedarf. Bei Doctrine wirddies durch die Nutzung sogenannter Proxy-Klassen ermöglicht.

Lektion 18: Übungen

Lektion 19: Testen Sie Ihr Wissen

1. Wofür steht das Akronym CRUD?

Create, Read, Update und Delete

2. Wofür steht das Akronym BREAD?

Browse, Read, Edit, Add und Delete

3. Weswegen beschreibt BREAD die nötigen Aktionen einer MVC-Anwendung besserals CRUD?

BREAD berücksichtigt den Code-Unterschied bei der Anzeige eines bzw. mehrerer Daten-sätze und trennt deswegen Browse und Read in zwei verschiedene Aktionen.

4. Wodurch unterscheiden sich die Aktionen Read, Edit und Delete von den (eher allge-meinen) Aktionen Browse und Add?

Read, Edit und Delete benötigen zur Ausführung die ID eines Datensatzes.

Lektion 19: Übungen

Lektion 20: Testen Sie Ihr Wissen

1. In welcher Datei kann klassenbasierter Validierungscode für unsere UserUser -Entityabgelegt werden und wo wird diese Datei gespeichert?

src/Validators/UserValidator.php

2. Wozu werden Repository-Klassen benutzt?

In Repository-Klassen können (längere) Datenbankabfragen ausgelagert werden, wie siebeispielsweise bei der Nutzung des QueryBuilders und JOINs auftreten. Bei einem gutgewählten Methodennamen verbessert sich so auch die Lesbarkeit des Codes.

248 Lösungen

Page 39: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Lektion 20: Übungen

Lektion 21: Testen Sie Ihr Wissen

1. Welche Daten eines Benutzers sind sicher?

Daten, die gar nicht erst erhoben und gespeichert werden.

2. Ist eine absolute Risiko-Eleminierung bei einer Web-Anwendung möglich?

Theoretisch ja, praktisch nein. Man spricht deshalb lediglich von einem Risiko-Manage-ment.

3. Welche fünf Tugenden sollte sich ein sicherheitsbewusster Entwickler angewöhnen?

1. Nichts ist zu 100 Prozent sicher.

2. Traue niemals den Benutzern.

3. Benutze immer mehrere Verteidigungslinien.

4. Wartbaren Code kann man besser absichern.

5. Vier Augen sehen mehr als zwei.

4. Unter welcher Prämisse sollte man heutzutage Anwendungen entwickeln?

»Der Feind kennt das System«

5. Wieso ist ein Whitelist-Ansatz einer Blacklist meist überlegen?

Bei einer Blacklist benötigt man eine genaue Kenntnis der nicht erlaubten Angaben, beieiner Whitelist hingegen schaltet man selektiv nach und nach die erlaubten (und geteste-ten) Werte frei.

6. Was ist die primäre Maßnahme zum Schutz einer Anwendung gegen SQL-Injections?

Prepared Statements mit (benannten) Platzhaltern für alle Benutzereingaben sind derwichtigste Schutz. Ihre Nutzung ist jedoch nur möglich, sofern die Eingabe als Wert (undz.B. nicht als Spalte bzw. Attribut) im SQL-/DQL-Statement benötigt wird.

7. Was ist der Unterschied zwischen persistentem und reflektiertem Cross-Site-Script-ing?

Beim persistenten XSS erfolgt der Angriff auf den Benutzer bei einem normalen Aufrufder Website. Der Schadcode ist dauerhaft in die Website integriert. Beim reflektierten XSSmuss die Website hingegen auf eine spezielle Art und Weise aufgerufen werden (meistüber einen präparierten Link). Der Schadcode gelangt erst über diesen Aufruf in die Aus-gabe der Website.

8. Welche Möglichkeiten hat ein Angreifer, um an das Kennwort eines Benutzers zugelangen? Gehen Sie in diesem Fall von einer Anwendung ohne gravierende Sicher-heitslücken aus.

Wörterbuchangriff, Brute-Force-Methode oder einfach eine Tafel Schokolade ;-)

9. Was ist der wichtigste Unterschied zwischen Verschlüsselung und Hashing?

Bei einem Einweg-Hash-Algorithmus ist im Gegensatz zu einer Verschlüsselung der Vor-gang nicht umkehrbar.

22.3 Buchtipps 249

Page 40: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

10. Reicht HTTPS als alleinige Verteidigungslinie für eine Web-Anwendung aus?

Nein, HTTPS schützt lediglich die Übertragung der Daten. Diese Daten können aber immernoch Schadcode enthalten.

Lektion 21: Übungen

250 Lösungen

Page 41: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Index

11:n-Beziehung 153 155 158

169 247

AActive Record 99 100 101

Adder-Methoden 156Autoloader 102 106 118 121

BBackup 203 237bidirektionale Beziehung

157 160Blacklist 203 209 216 237

249BREAD 172 183 248Brute-Force-Methode 221

249

Ccollection 156 158 166Composer 102 103 104 105

107 117 118 119 120 121204 208 227 245

Controller-Skeleton 129 130Cross-Site Request Forgery

217Cross-Site-Scripting 212 220

237 249CRUD 172 183 248

DData Mapper 100 101 102

113 167 245DateInterval 147Datenkapselung 47DateTime 116 145 146 147

149 150 151 188 189 190

Defacement 212 215Delegator 78 156 158 162

169 248dependencies 103design patterns 17Doctrine 1 112 185Doctrine 2 17 101 121 185

194Doctrine DatentypDoctrine Extensions 104 121

148 167 185 187 194Doctrine Query Language

139Doctrine-Entity 113 119 120

180 186Dreiteilung des Codes 88Drive-by-Download 212DRY 126DQL 139 141 142 143 168

194 209 210 211 247 249DQL-Funktion 194

EElternklasse 126EntityManager 121 124 125

132 135 139 141 143 158166 179 180 187 218 246

EntityRepository 135 136161 180 192 247

EntityValidator 186 187 190Entwurfsmuster 15 17 18 78

98 99 100 101 102 132

FFilterung 208 210 215

Flash-Notices 172

GGetter-Methoden 47 53 64

HHashing 225 226 227 230

249Helper 130 215 216 217Hypertext Transfer Protocol

Secure 236

Iinstanceof 59 61 158 167 243

INSERT 99 129 132 133 179

Interface 46 142Inverse Side 153ISO 8601 145

JJOIN 168 169 170

KKapselung 24 28 46 81 110Kerckhoffs MaximeKISS 27Konstruktor 70 72 73 74 75

77 80 82 127 128 145 146150 156 162 190 244

LLeetspeak 222Lazy EvaluationLazy Loading 166 167 168

248

Page 42: Objektorientierte Webentwicklung€¦ · Die Verwendung der Texte und Abbildungen, auch aus- ... Strukturierung von PHP-Code 20 PHP und HTML trennen 20 Lesbaren Code schreiben 23

Law of Demeter 79lowerCamelCase 43 109 136

Mmagische Methode 67 68 69

Model-View-Controller 83MVC 83 94 96 172 183 208

Nn:m-Beziehung 153 161 162

168 169 182 247Namespaces 110 111 118

246Namenskonvention 47 125

136 163 185 186 246

Oobjekt-relationales Mapping

98ORM 98 99 102 105 106 113

115 116 117 119 125 126130 135 140 143 149 150155 162 163 185 186 188190 192 194 246 247

Output Escaping 216Owning Side 153

PPackagist 102 104 121 216Pair Programming 199Parametermanipulation 204

209Partial 89 126 173 174 188Peer Reviewing 199Phishing 212 214Platzhalter 87 104 141 142

181 184 211Post/Redirect/Get 179

Prepared Statements 141211 249

PRG 179Proxy-Klasse 167Purifier 216 217

QQueryBuilder 139 142 143

168 169 170 175 191 194

RRefactoring 198Remote File Inclusion 208Repositories 118 137 185

192 239repository 104 135 137 139

192 193 195 248Repository-Klasse 191Risiko-Management 197 249

SSalt 228 229Secure Sockets Layer 236Security through Obscurity

199SELECT 135 136 137 139 142

144 168 181 183 193 195

Server-Banner 200 202Session Riding 218Setter-Methoden 46 50 52

61 243Single Responsibility Prin-

ciple 26 28 100Skriptkiddie 202SQL-Injection 209 212 221

statische Methode 121 234Syntax-Highlighting 23 88

TTemplate 87 88 89 90 91 92

96 204 207Timestampable 147 148 150

247Type-Hinting 60 157 158 192

UUniform Access Principle 64Unit of Work 132 246Unplanned Information Dis-

closure 205UPDATE 103 119 129 148

210 237 245 248UpperCamelCase 43Usability 189 198 205 215

VValidator-Klasse 185 186 187

Variablenfunktionen 74 235Vererbung 125 126 128 167

192Verschlüsselung 225 236 237

virtuelle Attribute 63 65 243

WWhitelist 203 204 205 206

209 211 216 217 235 237

Wörterbuchangriff 221 231

XXSS-Cleaner 216