logo Homepage
+  NewbieContest
|-+  Programmation» Langages Web» [PHP] securisation
Username:
Password:
Pages: [1]
  Imprimer  
Auteur Fil de discussion: [PHP] securisation  (Lu 10641 fois)
parayes

Profil challenge

Classement : 5848/54283

Néophyte
*
Hors ligne Hors ligne
Messages: 23


Voir le profil
« le: 28 Juillet 2013 à 18:25:43 »

Salut a tous et a toutes,
j'ai entrepris la conception d'un scripte possible a utilisé comme base de chaque site.
Alors pour le tester, quoi de mieux que de demander de l'aide a plusieurs communautés.

Code:
<?php
/* ----------
 * Beta 1.0 -
 * ----------
 * Merci aux personnes qui m'ont permi
 * de prendre consiance de mes erreurs
 * et de leur divers aides :
 * ----------
 * www.developpez.net
 * www.newbiecontest.org
---------- */


// Filtres de nettoyage
function filtre_nettoyage($valeur)
{
    
$valeur trim($valeur);
    
$valeur htmlentities($valeurENT_QUOTES);
    
// $valeur = strip_tags($valeur); // SHOULD -- You never know
    
return $valeur;
}

// Filtre pour fichier
function filtre_fichier($valeur$chemin)
{
    
$chemin dirname(__FILE__).$chemin;
    
    if(!
strstr($valeur".."))
    {
        if(!
file_exists($chemin))
        {
            echo 
"Erreur : Le fichier demandé n'existe pas ou n'est pas autorisé !";
            exit();
        }
        else
        {
            return 
$valeur;
        }
    }
    else
    {
        echo 
"Erreur : Tentative interdite !";
        exit();
    }
}

// Filtre pour shell (use filtre_nshell($valeur, TRUE | FALSE))
function filtre_nshell($valeur$chaine)
{
    if(
$chaine)
    {
        
$valeur escapeshellarg($valeur);
    }
    else
    {
        
$valeur escapeshellcmd($valeur);
    }
    
    return 
$valeur;
}

// Parseur de securisation
function parse_secur($parseCode
{

    if (
is_array($parseCode))
    {
        foreach (
$parseCode as $clef => $valeur)
        {
            
$valeur filtre_nettoyage($valeur);
            
$parseCode[$clef] = utf8_enc($valeur);
        }
    }
    else
    {
        
$parseCode filtre_nettoyage($parseCode);
        
$parseCode utf8_enc($parseCode);
    }

    return 
$parseCode;
}

// Verif email/url/ipv4/ipv6
function parse_verif($valeur)
{
    
$parseCode filtre_nettoyage($valeur);

    if(
filter_input($parseCodeFILTER_VALIDATE_EMAIL))
    {  
        
$parseCode filter_var($parseCodeFILTER_SANITIZE_EMAIL);
    }
    elseif(
filter_input($parseCodeFILTER_VALIDATE_URL))
    {
        
$parseCode filter_var($parseCodeFILTER_SANITIZE_ENCODED);
    }
    elseif(
filter_input($parseCodeFILTER_VALIDATE_IPFILTER_FLAG_NO_PRIV_RANGE)) {}
    else {
$erreur false;}

    if(!isset(
$erreur))
    {
        return 
$parseCode;
    }
    else {echo 
'Les argument passé ne sont pas valides';}
}

// Function debug
function mod_debug($valeur)
{
    echo 
'<br />';
    
var_dump($valeur);
    
$memUse round((memory_get_usage()/1024)/10242);
    echo 
'<br />',$memUse,' / Mo.';
}

Un "strip_tags" est présent en plus d'un "htmlentities", car j'avais croisé un détournement possible du "htmlentities" corrigé comme cela. Mais impossible de retrouver ce sujet ...
Je ne suis pas persuadé du point de vue pertinent de "utf8_enc" vue qu'il est aussi présent avec le "htmlentities".

Le tout n'est pas codé en Objet, c'est un chois personnel. Mais si vous avez des indications sur un réel besoin de l'utilisation d'Objet sur ce genre de projet. Je suis tout ouie

Remarques retenue :
- Faille dans le filtre shell pour ";" => remède trouvé pour ça "escapeshellcmd"
- Faille dans "fichier" si chemin non dev => corrigé avec "dirname(__FILE__)"
- "ENT_IGNORE" est déprécié (dangereux)
- "strip_tags" inutile a son emplacement, retrait ou mod pour "allowable_tags"
- Retrais du force UTF-8 de htmlentities, conservation de "utf8_enc" a la place

Des retours, des corrections ?
Merci

PS : Wao je n’étais pas venu depuis ... sur ce site, qu'il soit toujours actif est génial. Ca donne envie de reprendre les challenges après toutes ces années.
« Dernière édition: 29 Juillet 2013 à 16:12:42 par parayes » Journalisée

Liberté implique responsabilité. C'est là pourquoi la plupart des hommes la redoutent.
 de George Bernard Shaw
Extrait de Maximes pour révolutionnaires
the lsd
Administrateur

Profil challenge

Classement : 190/54283

Membre Héroïque
*****
Hors ligne Hors ligne
Messages: 3096

poulping for fun & profit


Voir le profil WWW
« #1 le: 28 Juillet 2013 à 20:53:08 »

Rapidement, j'ai vu la fonction filtre_nshell. Tu es sur de vouloir ça ? Permettre de lancer des commandes shell à partir de PHP, c'est dangereux imho. Et surtout, tu ne filtres que sur le pipe ? Là, c'es TRES dangereux. SI je fais un ; il se passe quoi ? Je peux lancer deux commandes. Au hasard date ; cat /etc/passwd

Bref, pour moi tu devrais carrément virer cette fonction et ne jamais lancer de commande shell de cette manière.

Enjoy

The lsd
Journalisée

Newbie Contest Staff :
The lsd - Th3_l5D (IRC)
Statut :
Administrateur
Citation :
Cartésien désabusé : je pense, donc je suis, mais je m'en fous !
parayes

Profil challenge

Classement : 5848/54283

Néophyte
*
Hors ligne Hors ligne
Messages: 23


Voir le profil
« #2 le: 28 Juillet 2013 à 22:52:20 »

Je l'avais pas vu tien
Même sans l'utiliser ça peut être pratique de savoir sécuriser ça.

Après je ne pense pas que lister les | et/ou ; soit la meilleure façon de procéder.
Tu aurais une proposition sur cette "sécurisation" ?

EDIT : Je retourne ça dans ma tête, sans avoir la sensation que "escapeshellcmd" et "escapeshellarg" soit forcément complémentaire.
EDIT : "elle autorise les personnes mal intentionnées de passer un nombre d'arguments arbitraire. Pour échapper un seul argument, la fonction escapeshellarg() devrait être utilisée à la place." Donc pour un traitement, c'est complémentaire... A voir comment procéder pour isoler individuellement des chaines voulues.

EDIT : A si j'ai déjà utiliser du shell en php, mais seulement sur un script local
EDIT : Merci, ton recule me fait remarquer cette grosse ... faille. Je suis content d’avoirs soumis ce script !
« Dernière édition: 29 Juillet 2013 à 04:03:48 par parayes » Journalisée

Liberté implique responsabilité. C'est là pourquoi la plupart des hommes la redoutent.
 de George Bernard Shaw
Extrait de Maximes pour révolutionnaires
the lsd
Administrateur

Profil challenge

Classement : 190/54283

Membre Héroïque
*****
Hors ligne Hors ligne
Messages: 3096

poulping for fun & profit


Voir le profil WWW
« #3 le: 29 Juillet 2013 à 09:22:44 »

Pour ta fonction htmlentities dans filtre_nettoyage, d'après la doc PHP, ENT_IGNORE est déconseillé, donc je ne le mettrais pas. Par contre, forcer en UTF8, je ne sais pas ce que ça donne. Imagine que ton charset est différent (au hasard du BIG5, le charset chinois), il va mal interpréter et peut être zapper des caractères.

Pour filtre_fichier, si je met un chemin absolu,, il se passe quoi à ton avis ?
Exemple : tu as l'archi suivante :
/var/www/site/uploads/test_upload.jpg
/var/www/site/admin/

Si ta fonction est utilisée pour lire un fichier dans uploads/ et que je met ../admin/index.php, effectivement, je ne pourrais pas.
Par contre, si je met /var/www/site/admin/index.php, je ne met pas de .. donc je ne matche pas ta condition.

Pour filtre_nshell, comme proposition de sécurisation, je te propose tout simplement de la supprimer, pas de shell depuis PHP, stoo.

Les deux autres fonctions me paraissent pas trop mal.

Enjoy

The lsd
Journalisée

Newbie Contest Staff :
The lsd - Th3_l5D (IRC)
Statut :
Administrateur
Citation :
Cartésien désabusé : je pense, donc je suis, mais je m'en fous !
parayes

Profil challenge

Classement : 5848/54283

Néophyte
*
Hors ligne Hors ligne
Messages: 23


Voir le profil
« #4 le: 29 Juillet 2013 à 14:53:57 »

J'ai tout ajouté a la petite liste.

pour le filtre de fichier, utilisant toujours une sécurisation et un chemin en plus de ce script je n'aurais pas eu de problème, mais du coup je n'avais pas vu cette faille.

Par principe je préfère garder "filtre_nshell", même si je suis d'accord avec toi.
Échapper les chaines demandé et utiliser "escapeshellcmd" pour les groupement, ça me semble déjà bien plus sécurisé. Si tu as une autre proposition ? (hors supprimer shell)  

EDIT :

j'avais oublié une minmini page :
Code:
<?php
// Verification de l'UTF8
function utf8_enc($valeur)
{
    if(
mb_detect_encoding($valeur) != "UTF-8")
    {
        
$result utf8_encode($valeur);
    }
    else
    {
        
$result $valeur;
    }

    return 
$result;
}
« Dernière édition: 29 Juillet 2013 à 15:40:38 par parayes » Journalisée

Liberté implique responsabilité. C'est là pourquoi la plupart des hommes la redoutent.
 de George Bernard Shaw
Extrait de Maximes pour révolutionnaires
Panday

Profil challenge

Classement : 243/54283

Néophyte
*
Hors ligne Hors ligne
Messages: 11


Voir le profil
« #5 le: 29 Juillet 2013 à 20:43:12 »

Bonjour,

Le tout n'est pas codé en Objet, c'est un chois personnel. Mais si vous avez des indications sur un réel besoin de l'utilisation d'Objet sur ce genre de projet. Je suis tout ouie

Je reprend ce point pour répondre à ta demande.

L'intérêt majeur de développer en objet pourrait être une gestion fine des exceptions plutôt que de simples booléens en retour de tes fonctions.
L'idée principale consiste à dériver la classe "Exception" pour en faire un certain nombre personnalisées, ce qui offre notamment la possibilité de se passer du "exit()" ou du "die()" et de préferer l'utilisation des try/catch.

Cela peut prendre tout son sens si tu envisages de mettre en place un système de logs (ou d'utiliser simplement la fonction "error_log()" de php).

Néanmoins, le php objet reste assez loin d'autres langages objets en terme de flexibilité et sa mise en place n'est pas "forcément" justifiée.


Panday
Journalisée
the lsd
Administrateur

Profil challenge

Classement : 190/54283

Membre Héroïque
*****
Hors ligne Hors ligne
Messages: 3096

poulping for fun & profit


Voir le profil WWW
« #6 le: 29 Juillet 2013 à 21:47:35 »

Le PHP OO n'a aucun sens. Il n'est pas complet, comparé à des vrais langages de POO, et accesoirement, ça ne sert pas à grand chose imho. Pour des gros projets, jor forum pourquoi pas. Sinon, tu perds plus de temps à faire tes classes qu'autre chose.

Pour ta fonction d'UTF8, je complète ce que je te disais tout à l'heure, concernant htmlentities, il y a incohérence. Tu fais juste un check pour vérifier le charset UTF8 (en soi, c'est bien), mais après tu forces ton htmlentities pour de l'UTF8, ça cloche

Enjoy

The lsd
Journalisée

Newbie Contest Staff :
The lsd - Th3_l5D (IRC)
Statut :
Administrateur
Citation :
Cartésien désabusé : je pense, donc je suis, mais je m'en fous !
parayes

Profil challenge

Classement : 5848/54283

Néophyte
*
Hors ligne Hors ligne
Messages: 23


Voir le profil
« #7 le: 29 Juillet 2013 à 21:52:14 »

Oui, je comprends ou tu veux en venir et j'avais a un moment envisagé le log.
Mais comme je ne l'ai finalement pas mis en pratique, l'objet ne me semble pas percutant en l’état actuel.

C'est vraiment un tout petit projet, donc le réécrire en objet ne prendrais pas beaucoup de temps même en y intégrant les  try/catch.

Verrais tu une réel utilité d'un log ? Après tout ce ne sont pas de grosses attaques et en cas de risque majeur apache/fail2ban le log de son cotée.

PS : D'un point de vue tout a fait personnel, je n'aime pas l'objet. Quel que soit le langage ça m'énerve, et ce sans savoir trop pourquoi. La construction en objet sous php ok, mais je ne trouve pas son utilisation, sa mise en pratique très ... judicieuse mais plutôt fastidieuse.  

--- --- EDIT --- ---
*Oups, LSD a répondu avant moi.

Oui c'est ce que je voulais dire ... ce forçage, c'est crade.
Au passage après les conseils de ce forum et l'autre, j'ai maj ma source qui passe du coup en Beta 1.

Et donc, phase d'optimisation, listage des erreur possible a engendrer et recherche de d'autres fonctions utiles !

Merci en tout cas.
« Dernière édition: 29 Juillet 2013 à 21:59:44 par parayes » Journalisée

Liberté implique responsabilité. C'est là pourquoi la plupart des hommes la redoutent.
 de George Bernard Shaw
Extrait de Maximes pour révolutionnaires
Panday

Profil challenge

Classement : 243/54283

Néophyte
*
Hors ligne Hors ligne
Messages: 11


Voir le profil
« #8 le: 29 Juillet 2013 à 22:36:21 »

Je te confirme que PHP OO est laborieux et vraiment irritant à écrire.
En ce qui concerne l'utilisation de logs, il t'appartient de décider si tu en as besoin ou non.

Pour finir, je n'irai pas jusqu'à déconseiller complètement l'objet en PHP, mais réfléchis bien à ton objectif et vois si cela est vraiment nécessaire.

Si j'ai un dernier petit conseil à te donner, ça concerne les bases de données.
J'ignore si tu comptes utiliser une DB pour ton projet, mais je te conseille vivement d'utiliser PDO ou encore ADODB (de l'objet   ) afin de protéger efficacement tes requêtes contre les SQL injections (avec les requêtes préparées).


Panday
Journalisée
parayes

Profil challenge

Classement : 5848/54283

Néophyte
*
Hors ligne Hors ligne
Messages: 23


Voir le profil
« #9 le: 29 Juillet 2013 à 23:16:46 »

oui justement, php objet serait utile pour un log. Mais sans log dans un projet comme celui là ... bof quoi.

Je n'utilise que TRES rarement des db et je ne m'y connais pas bien sur ce point là.
la puissance de sql sqlite etc ... ne m'a jamais vraiment motivé (sauf pour un forum ou ce genre d'utilisation) ... du coup j'utilise des fichiers en dur(souvent généré par php) et du .ini pour les config.
« Dernière édition: 29 Juillet 2013 à 23:18:28 par parayes » Journalisée

Liberté implique responsabilité. C'est là pourquoi la plupart des hommes la redoutent.
 de George Bernard Shaw
Extrait de Maximes pour révolutionnaires
the lsd
Administrateur

Profil challenge

Classement : 190/54283

Membre Héroïque
*****
Hors ligne Hors ligne
Messages: 3096

poulping for fun & profit


Voir le profil WWW
« #10 le: 31 Juillet 2013 à 22:22:44 »

J'vois pas trop votre histoire de POO pour des logs en fait ^^' J'suis preneur d'un exemple

Les bases de données sont très puissantes, tu as tort de ne pas les utiliser. Rien que le principe de clés étrangères, c'est un gain de temps incroyable imho. Bon après, pour moi, les bases de données devraient se limiter à du CRUD et rien d'autres. Un langage de requête doit faire des requêtes, pas du md5, du substr, etc.
Comme dit Panday, si tu te mets à la base de données, utilise des prepared statements, ça évite en grande partie les injections SQL.

Pour en reenir à ton script, le fait est il vraiment plus secure ? C'est une vraie question, je n'ai pas la réponse, et n'ai pas l'envie de tester ce soir. Si ton file_exists gère les variable d'environnement, et que je met dans mon chemin un $HOME/.bash_history (si tu es sur un linux bien sur), je peux me retrouver dans ton file system (mwahaha). Attention, encore une fois, je ne connais pas le comportement de file_exists, je dis peut etre une connerie, c'est à tester



Enjoy

The lsd
Journalisée

Newbie Contest Staff :
The lsd - Th3_l5D (IRC)
Statut :
Administrateur
Citation :
Cartésien désabusé : je pense, donc je suis, mais je m'en fous !
parayes

Profil challenge

Classement : 5848/54283

Néophyte
*
Hors ligne Hors ligne
Messages: 23


Voir le profil
« #11 le: 01 Août 2013 à 03:56:19 »

Avec POO tu as "try" et "catch", ça permet d’"attraper les erreurs". C'est relativement pointu (suivant comment tu l'utilise/code) tu peux donc rediriger sous forme de log. Avec ça tu peux listé l'ip lié a l'erreur, la requête etc, mais ça c'est comme dab... pas besoin de POO ^^

haaa ça m’énerve ! J'avais réalisé un teste de db vs file. La db était très rapide sur des demandes basé sur de l'indexation (logique), mais bien plus lente dans les autres cas. Impossible de retrouver le result... Teste effectué avec une boucle de 50.000. Apres, j'utilise des fichiers avec un réalisé sous forme d'indexation, du coup ça reviens surement presque au même ... (en moins complexe et sans mdp etc ...)

Remarque tres intéressante, j'ai de suite testé et .... nan ça ne marche pas. Meme en désactivant "function filtre_nettoyage". Peut être qu'avec une mauvaise configuration du serveur cela pourrait marcher ... hum.
« Dernière édition: 01 Août 2013 à 03:59:03 par parayes » Journalisée

Liberté implique responsabilité. C'est là pourquoi la plupart des hommes la redoutent.
 de George Bernard Shaw
Extrait de Maximes pour révolutionnaires
Panday

Profil challenge

Classement : 243/54283

Néophyte
*
Hors ligne Hors ligne
Messages: 11


Voir le profil
« #12 le: 01 Août 2013 à 19:35:32 »

J'vois pas trop votre histoire de POO pour des logs en fait ^^' J'suis preneur d'un exemple

Typiquement, pour essayer de donner un exemple concret, j'ai développé récemment une API webservice en "full" objet. Je dis "full" avec des pincettes car avec PHP, on se retrouve souvent avec des comportements qui singent Java ou C++.

Cela étant, le principe est relativement simple :
- J'ai un contrôleur frontal qui reçoit toutes les requêtes clients et qui dispatche vers les diverses actions à effectuer
- L'action selectionnée va construire la réponse
- J'évite les branchements interminables de if/else pour gérer tous les cas de figure possibles : quand ça ne va pas, je throw et c'est le contrôleur qui catch tout et qui log

Le deuxième avantage réside dans l'héritage et l'abstraction de classe : toutes mes classes d'actions dérivent de la classe mère abstraite "Action", et je peux ainsi unifier le comportement des actions (et par la même des actions à implémenter dans le futur).

Donc pour conclure, si le projet de parayes tend à évoluer régulièrement dans l'avenir, l'objet peut très bien être un choix judicieux. Dans le cas contraire, la méthode habituelle suffira largement et l'objet pourra vite devenir une entrave plutôt qu'un atout  


Panday

Edit: Je rajouterai quand même pour appuyer the lsd que permettre des appels systèmes ou l'execution de shell est vraiment une très mauvaise idée, à moins d'y être contraint.
« Dernière édition: 01 Août 2013 à 19:40:02 par Panday » Journalisée
Pages: [1]
  Imprimer  
 
Aller à: