Auditing and securing PHP applications - FRHACK 2009
Une application en deux heure - PHP Québec Janvier 2009
1. Une application
en deux heures
Avec Symfony
vendredi 13 novembre 2009 1
2. Objectif
• Présenter symfony d’une façon
originale
• Faire une application en une heure
vendredi 13 novembre 2009 2
3. Qui suis-je?
• Philippe Gamache
•Expert en sécurité PHP
chez Sensio Labs
•Auteur du livre « Sécurité
PHP 5 et MySQL » avec
Damien Seguy, chez
Eyrolles
•http://www.phportail.net
•http://lapageamelkor.org
•naheulbeukauquebec.ca
vendredi 13 novembre 2009 3
4. Des
questions?
?
N’attendez
pas à la fin
vendredi 13 novembre 2009 4
6. symfony
• Cadre d’application WEB en PHP
• Basé sur :
• 10 ans d’expérience chez Sensio
• D’autres logiciels libres existants
• Licence MIT
• Documentation est libre
• Grande communauté
vendredi 13 novembre 2009 6
7. symfony
• Créer pour:
• Sites web professionnels
• Besoins complexes
• Environnements exigeants
• Développement rapide
vendredi 13 novembre 2009 7
8. Installer symfony
http://www.symfony-project.org/installation
• Source
• Bac à sable
• Installation via PEAR
• Installation via SVN
• Installation Linux (Debian et SUSE)
vendredi 13 novembre 2009 8
10. Création du projet
• Créer le répertoire du projet
$ mkdir -p blogue
$ cd blogue
• Vérifier la version de symfony
$ symfony -V
• Créer un projet
$ symfony generate:project blogue
vendredi 13 novembre 2009 10
11. Création du projet
• Créer une application
$ symfony generate:app /
--escaping-strategy=on /
--csrf-secret=UniqueSecret /
frontend
• Ajuster votre serveur web
vendredi 13 novembre 2009 11
13. Activation de sfDoctrine
// config/ProjectConfiguration.class.php
public function setup()
{
$this->enableAllPluginsExcept(
array('sfPropelPlugin',
'sfCompat10Plugin'));
}
vendredi 13 novembre 2009 13
14. La base de données
• Créer la base de données
$ mysqladmin -uroot -pmYsEcret /
create jobeet
• Configurer le projet
$ symfony configure:database /
--name=doctrine /
--class=sfDoctrineDatabase /
"mysql:host=localhost;dbname=blogue" /
root mYsEcret
• Effacer la connexion de Propel
vendredi 13 novembre 2009 14
19. Données de tests
BlogPost:
post_1:
Author: philippeg
title: Lorem ipsum dolor sit amet
content: |
<p>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut...</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do...</p>
is_published: true
published_at: 09-01-07
post_2:
Author: philippeg
title: Ut enim ad minim veniam
content: |
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse...</p>
is_published: true
published_at: 09-01-07
post_3:
Author: philippeg
title: Duis aute irure dolor in reprehenderit in voluptate
content: |
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse...</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p>
is_published: true
published_at: 09-01-07
...
vendredi 13 novembre 2009 19
20. Données de tests
BlogComment:
comment_1:
BlogPost: post_1
author_name: lorem
content: Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
comment_2:
BlogPost: post_1
author_name: elit
content: Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
comment_3:
BlogPost: post_3
author_name: aute
content: Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
comment_4:
BlogPost: post_3
author_name: aute
content: ESunt in culpa qui officia deserunt mollit anim id est laborum.
vendredi 13 novembre 2009 20
21. Création du code
• Utiliser le générateur de code
$ symfony doctrine:generate-crud /
--with-show frontend post BlogPost
• Effacer les actions inutiles
• executeNew()
• executeEdit()
• executeUpdate()
• executeDelete()
• processForm()
vendredi 13 novembre 2009 21
22. Création du code
• Effacer les fichiers inutiles
• templates/_form.php
• templates/editSuccess.php
• templates/newSuccess.php
• Effacer les liens vers les autres
fonctions
vendredi 13 novembre 2009 22
24. Création du code
• Modifier templates/showSuccess.php
<h2><?php echo $blog_post->gettitle() ?></h2>
<div>Par <?php echo $blog_post->getAuthor() ?> le <?php echo $blog_post-
>getpublished_at() ?></div>
<p><?php echo nl2br($blog_post->getcontent()) ?></p>
<hr /><br /><br />
<?php echo link_to('List', '@homepage') ?>
vendredi 13 novembre 2009 24
25. Création du code
• Ajouter au templates/layout.php
<div id="header">
<h1><?php echo link_to('Mon Blogue', '@homepage') ?></h1>
</div>
<div id="content">
<?php echo $sf_data->getRaw('sf_content') ?>
</div>
<div id="footer"></div>
• Ajouter web/css/blog.css
• Modifier apps/frontend/config/view.yml
vendredi 13 novembre 2009 25
26. Création du code
• Modifier actions.class.php
public function executeIndex(sfWebRequest $request)
{
$this->blog_post_list = Doctrine::getTable('BlogPost')
->createQuery('a')
->where('a.is_published = 1')
->execute();
}
public function executeShow(sfWebRequest $request)
{
$this->blog_post = Doctrine::getTable('BlogPost')
->findOneBySlug($request->getParameter('slug'));
$this->forward404Unless($this->blog_post);
}
vendredi 13 novembre 2009 26
27. Création du code
• Modifier BlogPost.class.php
public function getContentSummary()
{
$out = explode('<', nl2br(substr($this->getcontent(), 0, 500)));
return $out[0] . '...';
}
• Ajouter à routing.yml
post_show:
url: /:slug
param: { module: post, action: show }
vendredi 13 novembre 2009 27
28. Ajouter les
commentaires
• Utiliser le générateur de code
$ symfony doctrine:generate-crud /
frontend comment BlogComment
• Copier le code dont vous aurez besoin
vendredi 13 novembre 2009 28
29. Ajouter les
commentaires
• Modifier le code dans actions.class.php
public function executeIndex(sfWebRequest $request)
{
$this->blog_post_list = Doctrine::getTable('BlogPost')
->createQuery('p')
->groupBy('p.published_at, p.id')
->where('p.is_published = 1')
->execute();
}
public function executeShow(sfWebRequest $request)
{
$this->blog_post = Doctrine::getTable('BlogPost')
->findOneBySlug($request->getParameter('slug'));
$this->forward404Unless($this->blog_post);
$this->form = new BlogCommentForm();
}
vendredi 13 novembre 2009 29
30. Ajouter les
commentaires
• Ajouter le code dans actions.class.php
public function executeCreate(sfWebRequest $request)
{
$this->forward404Unless($request->isMethod('post'));
$this->blog_post = Doctrine::getTable('BlogPost')
->findOneBySlug($request->getParameter('slug'));
$this->forward404Unless($this->blog_post);
$comment = new BlogComment();
$comment->setBlogPost($this->blog_post);
$this->form = new BlogCommentForm($comment);
$this->processForm($request, $this->form);
$this->setTemplate('show');
}
vendredi 13 novembre 2009 30
31. Ajouter les
commentaires
• Ajouter le code dans actions.class.php
public function processForm(sfWebRequest $request, sfForm $form)
{
$form->bind($request->getParameter($form->getName()));
if ($form->isValid())
{
$blog_comment = $form->save();
$this->redirect('@post_show?slug=' .
$request->getParameter('slug'));
}
}
• Ajouter a routing.yml
comment:
url: /comment/:slug
param: { module: post, action: create }
vendredi 13 novembre 2009 31
41. Création du Backend
• Modifier setting.yml
...
all:
.actions:
login_module: sfGuardAuth
login_action: signin
secure_module: sfGuardAuth
secure_action: secure
.settings:
enabled_modules: [default, sfGuardAuth]
...
• Modifier setting.yml
default:
is_secure: on
vendredi 13 novembre 2009 41
42. Création du Backend
• Modifier post generator.yml
...
config:
actions: ~
fields: ~
list:
title: Liste de message
display: [is_published, author_id, =title, published_at]
filter:
display: [is_published]
form: ~
edit:
title: Modifier le message "%%title%%"
display: [is_published, author_id, title, content, published_at]
new:
title: Nouveau message
display: [is_published, author_id, title, content, published_at]
vendredi 13 novembre 2009 42
43. Création du Backend
• Modifier comment generator.yml
...
config:
actions: ~
_delete: ~
_list: ~
fields:
ContentSummary:
label: Commentaires
list:
object_actions:
_delete: ~
actions:
__: ~
title: Liste des commentaires
display: [blog_post_id, =author_name, =ContentSummary]
filter:
display: [blog_post_id]
form: ~
edit: ~
new: ~
vendredi 13 novembre 2009 43
44. Création du Backend
• Modifier myUser.class.php
class myUser extends sfGuardSecurityUser
{
}
vendredi 13 novembre 2009 44
45. Pour aller plus loins
• Ajouter étiquettes (tags)
• Ajouter un mini-calendrier
• Mettre les billets par mois
• Ajouter recherche par date
• Ajouter des flux de données (RSS,
ATOM) via sfFeed2plugins
vendredi 13 novembre 2009 45