From lol at lzi.ch Fri Jul 4 19:19:57 2003
From: lol at lzi.ch (Lol Zimmerli)
Date: Fri, 4 Jul 2003 19:19:57 +0200
Subject: [cours-linux-esnig] cloture 2002-2003
Message-ID: <200307041720.h64HK2t04081@lolette.lzi.ch>
Hello,
comment s'est termin?e la saison, les TP ont ils ?t? bons?
A+
--
Lol Zimmerli
Tu es assis pr?s d'un ruisseau et tu as soif.
M?me si tu es idiot, tu sais que l'eau va te d?salt?rer.
C'est ?a comprendre..
Ren? Barjavel
From schaefer at alphanet.ch Sun Jul 6 12:20:35 2003
From: schaefer at alphanet.ch (Marc SCHAEFER)
Date: Sun, 6 Jul 2003 12:20:35 +0200
Subject: [cours-linux-esnig] cloture 2002-2003
In-Reply-To: <200307041720.h64HK2t04081@lolette.lzi.ch>
References: <200307041720.h64HK2t04081@lolette.lzi.ch>
Message-ID: <20030706102035.GB2008@defian.alphanet.ch>
On Fri, Jul 04, 2003 at 07:19:57PM +0200, Lol Zimmerli wrote:
> comment s'est termin?e la saison, les TP ont ils ?t? bons?
Le compte rendu sera post? tant?t.
From schaefer at alphanet.ch Thu Jul 10 10:00:07 2003
From: schaefer at alphanet.ch (Marc SCHAEFER)
Date: Thu, 10 Jul 2003 10:00:07 +0200
Subject: [cours-linux-esnig] Commentaires sur le projet
Message-ID: <20030710080007.GA2003@defian.alphanet.ch>
Bonjour,
apr?s avoir test?, lu la documentation et vu vos sources pour le projet,
j'ai constat? que le code est tout ? fait correct dans la grande partie,
que les fonctionnalit?s sont pr?sentes et que des efforts sensibles
pour la s?curit? ont ?t? consentis.
Malgr? tout, quelques critiques g?n?rales dans le but d'am?liorer la
qualit?:
HTML
- Il est important de comprendre la diff?rence entre code PHP et
code HTML. En particulier, on vous demandait de valider, via
http://validator.w3.org/, le *code HTML* _g?n?r?_ par les scripts
PHP. En bref, cela signifie que si votre serveur WWW est accessible
depuis Internet, vous entrez simplement l'URL de votre script PHP
ex?cutable
Sinon vous acc?dez ? vos scripts acc?dez via un client WWW (w3m, Mozilla,
Konqueror, etc) et vous sauvez le document retourn? en HTML.
C'est ce fichier que vous pouvez transf?rer via Validate file. Et
non pas un fichier contenant du code PHP.
- Il est important d'avoir un
...
Exemple: faire un `view source' sur http://www.cril.ch/,
s?lectionner le lien de validation.
- Oublier de terminer certains tags:
...
- Oublier de sp?cifier les listes:
( est optionnel)
- n'a pas de tag de fermeture.
Qualit?
- Un code de qualit? doit ?tre compr?hensible, r?utilisable et
param?trable.
Mettre les fonctions souvent utilis?es dans un fichier
d'include (cela a souvent ?t? fait). En particulier les
mots de passe!
En PHP:
include("include/password.inc");
include("include/fonctions.inc");
NB: regardez ce qu'il se passe si vous demandez
http://votre-site/projet/include/password.inc. Si vous
voyez vos mots de passe, prot?gez ce r?pertoire dans la
configuration Apache ou appelez le fichier .php, ce qui
devrait le rendre interpr?table mais non visible.
Peut-?tre s?parer le traitement de l'affichage HTML:
- v?rification des param?tres (filtrage, s?curit?)
- requ?tes de base de donn?es
- affichage
(en trois fonctions ou s?quences d'instructions clairement
s?par?es).
Peut-?tre d?velopper une fonction d'affichage de table g?n?rique
(certains l'ont fait).
Mettre des commentaires directement dans le code.
- Peut-?tre qu'il faut ?viter certains artifices, comme les REFRESH
(le standard HTML 4 les interdit). Une strat?gie int?ressante peut
?tre d'avoir toute la fonctionnalit? dans un seul script
(biblio.php3) et d'ensuite impl?menter les fonctions r?elles via
des fichiers include: ainsi l'utilisateur ne doit pas jongler
avec des boutons back/forward, il revient imm?diatement au bon
endroit.
- Certains ont fait de r?els efforts de design! J'ai tendance ? penser
que (surtout si l'on utilise un programme souvent), on pr?f?re
avoir un syst?me fiable et simple plut?t qu'une interface trop
design, mais un design efficace et agr?able peut aussi rendre les
choses bien plus efficaces, en particulier s'il repose sur une
base simple et solide. En particulier les CSS permettent -- sur les
navigateurs pas trop anciens -- de s?parer structure et pr?sentation
et de rendre la pr?sentation facilement modifiable.
- Ce n'est pas tr?s beau d'avoir des `warnings' ou des erreurs
difficilement identifiables. Ajouter des tests d'erreur circonstanci?s,
ce qui peut simplifier le debug ? l'installation ou en cas de probl?me.
$db = $mysql_connect("test", "abcd");
// ici tester $db
De m?me pour mysql_select_db(), mysql_query(), mysql_fetch_array().
Ne pas h?siter ? lire les documentations PHP de ces fonctions.
- Une id?e peut ?tre d'avoir une variable globale $debug, normalement ?
z?ro (dans un fichier d'include), et qui peut ?tre activ?e et
ajouter des messages de debug:
message_si_debug()
la fonction n'affiche quelque chose que si $debug est ? 1.
Certaines personnes ont utilis? cette id?e.
- La question de savoir si des GET ou des POSTs sont mieux m'a
?t? pos?e. Dans le premier cas, les variables (param?tres) sont
visibles dans l'URL: ....
Dans le deuxi?me ils sont invisibles, et ne peuvent ?tre cach?s ou
`bookmark?s'.
Tout d?pend ce que l'on fait: pour les fonctions de bases, je dirais
que c'est un avantage de pouvoir `bookmarker' et faire `back/forward'
sans que les donn?es n'expirent dans le cache ? cause d'un POST.
Par contre, pour le cas o? l'on a des valeurs temporaires ou une
succession de questions avec un contexte, un POST est mieux.
On peut aussi sauver les variables dans un cookie, ou dans un
param?tre, et associer la valeur du cookie ? une structure de donn?es
d'?tat complexe dans la base de donn?es: ce qui rend impossible
les probl?mes de navigation ou de `submit' multiple vu que le contexte
est sauv? sur le serveur. Le cookie peut ?tre invalid?
apr?s un logout ou un d?lai d?pass?.
- Casse: en r?gle g?n?rale, utiliser des majuscules uniquement et
utiliser le soulign? '_' comme s?parateur. En effet, les noms de tables
et d'identificateurs peuvent ?tre parfois significatifs (MySQL sous
UNIX), et les noms de fichiers -- donc les noms de scripts ?galement
aussi. Faire ainsi ?vitera des probl?mes de portabilit?, en particulier
de Windows ou MacOS ? UNIX.
Documentation
- Il peut ?tre int?ressant de documenter le sch?ma de la base de
donn?es: certains l'ont fait. Il semble m?me que des outils existent
pour convertir un mod?le EA ?crit sous l'?diteur DIA directement
en SQL exploitable.
- Si l'on ne fournit pas d'installation automatis?e, et m?me si,
documenter celle-ci peut ?tre une bonne id?e.
- Documenter la liste des fichiers et ce qu'ils font est un strict
minimum (fichier README, cr?? par un `ls -1' puis manuellement
en ajoutant des commentaires).
- Id?alement, lorsqu'on archive un projet (pour le transmettre ou
comme sauvegarde), il faudrait archiver le r?pertoire. De mani?re ?
ce que le d?sarchivage soit facile.
Par exemple:
cd ..
tar cf - nom_projet | gzip -9 > nom_projet.tar.gz
Aussi, faire attention aux fins de ligne MS-DOS dans les fichiers texte.
Dans certains cas, cela peut poser des probl?mes sous UNIX.
sed 's/^V^M//g' < fichier.txt > fichier
(^V et ^M signifient Control-V et Control-M). Certaines distributions
ont un outil dos2unix pour le faire. Dans vi, ces fichiers apparaissent
comme [dos mode].
Fonctionnalit?s
- Dans l'ensemble, les fonctionnalit?s demand?es ont ?t? impl?ment?es.
Parfois on est all? plus loin.
- Parfois, malheureusement, tout n'a pas ?t? impl?ment? ou des fichiers
manquaient (j'ai contact? les personnes dans l'espoir de corriger
cela). C'est un peu dommage d'avoir des fonctionnalit?s non demand?es
pr?sentes sans toutes les fonctionnalit?s demand?es.
S?curit?
Il y a un cours s?curit? l'ann?e prochaine ? l'ESNIG, mais je vais
essayer de faire un r?sum? de 150 p?riodes en quelques lignes :))
1. introduction/alt?ration/consultation de donn?es non autoris?es
Dans un premier lieu, on pensera ? l'authentification (par
mot de passe, .htaccess avec Apache, ou par cookie p.ex.).
Mais ce n'est pas tout.
Cette classe contient ?galement les attaques de
cross-scripting: la base de donn?es contient un champ `nom'
qui contient '. Visualiser
une table contenant ce champ, p.ex., fera activer le lien
image sans poser de question ? l'utilisateur. Si celui-ci s'est
identifi? sur le site concern? (cookie, BASIC-AUTH), le premier
script (ou tout utilisateur pouvant ins?rer des donn?es dans la
DB) peut abuser cette authentification et alt?rer des donn?es
p.ex.
Solution: passer ? la moulinette (htmlspecialchars()) avant
d'envoyer au client WWW toute cha?ne provenant de
donn?es pouvant ?tre contr?l?es par l'utilisateur
(au minimum: champs de formulaires, donn?es DB).
Sch?ma: (se lit mieux avec une fonte non proportionnelle!)
|register_global = off
|(?vite attaque sur variables
|de script, utiliser $_POST[])
|
| |?viter cross-scripting
| |en n'envoyant en HTML
| |que des donn?es via
| |htmlspecialchars()
| |
FORM ----> script ----> DB ----> script ----> HTML
|
|?viter attaque SQL insertion via
|magic_quote = On, ou, mieux,
|addslashes() au bon endroit suivant la
|DB.
(une FORM entre les donn?es dans la DB via le script,
et plus tard le script g?n?re du HTML depuis les donn?es
stock?es dans la DB)
Attention: si magic_quote n'est pas ? off, PHP rajoute des
backslashes dans les FORMs et ce n'est pas le mod?le correct.
Une solution robuste de scripts acc?dant ? une base de donn?es
pourrait:
- limiter la lecture ? l'utilisateur MySQL usuel
- les scripts d'administration utilisent un autre utilisateur
qui a acc?s lecture/?criture, mais sont prot?g?s p.ex. par
un .htaccess
- ?ventuellement utiliser des m?canismes de la base de donn?es
(contraintes d'int?grit?, triggers) pour ?viter de modifier
certaines donn?es (-> plut?t PostgreSQL que MySQL).
Exemple: un salaire ne peut ?tre n?gatif, la somme des
salaires ne peut exc?der le budget, une ?criture
de comptabilit? ne peut ?tre qu'extourn?e, pas
effac?e.
- en cas de serveur partag? utiliser le safe_mode PHP ou le
mode CGI suexec.
2. introduction/alt?ration de donn?es contradictoires/incorrectes
Voir la derni?re partie du 1.
4. abus des scripts pour passer outre les s?curit?s du script,
de la base de donn?es, ou du syst?me Linux.
$sql = " SELECT * from livres, ";
$sql = $sql . "auteurs where livres.auteurid=auteurs.auteurid and";
$sql = $sql . " (auteurs.nom=\"$Auteur\" or livres.titre=\"$Titre\")";
Premi?rement, $Auteur n'est pas acc?d? via le tableau
$_POST[]
ce qui signifie que l'espace des variables du script et l'espace
des variables sous contr?le de l'utilisateur du script via WWW
est le m?me. Rappelons que seulement si register_globals=off est
configur?, il est impossible de manipuler les variables du script
de l'ext?rieur (et $var ne marche plus pour acc?der
$_POST[var]). Cf le php.ini.
Deuxi?mement, si $Auteur contient des guillemets, il y aura
erreur.
Finalement, si $Auteur contient '"; DROP DATABASE biblio;
SELECT * FROM LIVRES WHERE (auteur.nom="', il est possible
d'abuser le script en ajoutant des ordres SQL (on appelle
cela: `SQL INSERTION ATTACK').
Solution:
- mettre tous les magic_* ? `off'
- utiliser addslashes(): avec la plupart des DB, rendra
les cha?nes inoffensives.
Autre solution:
- Le `binding' de Perl.
Exemple: (pseudo-code)
$query = 'SELECT * FROM utilisateurs WHERE (nom LIKE ?)'
do_query($query, [ $nom ]) or die("error");
(on lie les variables dans la cha?ne avec ? au lieu de
faire du traitement de texte. La fonction do_query() passe
les param?tres directement ? la DB, en `binaire'
(structures de donn?es langage C), ou s'occupe de
faire un `addslashes' appropri?. Cf man DBI.
5. erreurs non communiqu?es ? l'utilisateur qui croit que tout
marche parfaitement.
Exemple typique:
$result = mysql_query($query);
if ( !$result ) {
... traitement d'erreur
}
else {
... traitement normal
}
6. atomicit?
Ce probl?me est assez ennuyeux. Il s'agit par exemple de d?terminer
si un produit command? existe r?ellement. MySQL, du moins jusqu'?
la version 4 non comprises, n'avait aucun concept de transaction ni
d'int?grit? r?f?rentielle correcte.
D'autres bases de donn?es relationnelles, je pense ? PostgreSQL
impl?mentent:
- les contraintes r?f?rentielles
(on ne peut ins?rer une r?f?rence ? un produit dans ligne
de commandes que si ce produit existe; on ne peut supprimer
un produit que si aucune ligne de commandes ne le r?f?rence)
- les transactions
Dans notre cas l'int?grit? r?f?rentielle suffirait: on ferait
l'insert dans ligne_de_commandes et la base de donn?es nous dirait
si le produit n'existe pas.
En conclusion:
M?me dans un cas aussi simple que notre syst?me de commande, on
se rend vite compte des limites de bases de donn?es simples
comme MySQL qui forcent ? effectuer les contraintes d'int?grit?
dans le code de script (p.ex. PHP) et ne garantissent pas grand
chose en cas d'ex?cution concurrente.
Voil?! Je vous remercie et j'esp?re que je ne vous ai pas trop fait peur!
Le but d'un tel projet est d'apprendre, et je crois que cela a ?t? le cas.
Je reste ? disposition pour des questions en public (sur la liste) ou en priv?.
Bonne continuation et bonnes vacances pour ceux qui en prennent
maintenant!
From lol at lzi.ch Thu Jul 10 11:36:41 2003
From: lol at lzi.ch (Lol Zimmerli)
Date: Thu, 10 Jul 2003 11:36:41 +0200
Subject: [cours-linux-esnig] Commentaires sur le projet
In-Reply-To: <20030710080007.GA2003@defian.alphanet.ch>
References: <20030710080007.GA2003@defian.alphanet.ch>
Message-ID: <200307100936.h6A9akt17887@lolette.lzi.ch>
Hello,
schaefer at alphanet.ch (Marc SCHAEFER) ?crit/wrote:
> HTML
> - Structure du HTML:
>
(...)
Attention ? la casse, je pense que c'est mieux d'habituer les gens ?
faire leurs tags en minuscules, vu que c'est requis pour l'XHTML
> NB: regardez ce qu'il se passe si vous demandez
> http://votre-site/projet/include/password.inc. Si vous
Hihihi! On avait pourtant vu ?a!
A bient?t!
--
Lol Zimmerli
Il faut bien mentir quelquefois quand on est ?v?que.
Jean-Jacques Rousseau