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: > Transitional//EN"> (...) 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