IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques & Frameworks Discussion :

Sécurité : faille XSS et upload de fichiers malicieux pour l'insertion d'image


Sujet :

Bibliothèques & Frameworks

  1. #1
    Lucas Panny
    Invité(e)
    Par défaut Sécurité : faille XSS et upload de fichiers malicieux pour l'insertion d'image
    Bonjour,

    J'ai développé un site dont le backoffice utilise essentiellement des éditeurs TinyMCE avec insertion d'image par le plugin ajaxfilemanager de http://www.phpletter.com/DOWNLOAD/

    Le soucis c'est que je me demande si cet éditeur me protège des failles XSS?
    L'attaque dont je suis le plus souvent victime c'est que le hacker exploite l'upload d'image pour uploader du PHP malicieux (souvent d'extension .php.gif), puisqu'il connaît très bien le chemin de l'upload, il peut ensuite lancer ce php.

    Comment puis-je me protéger de cela?

  2. #2
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Hello

    D'une part, je pense qu'il y a un sérieux problème de sécurité dans le fait d'exposer un backoffice.
    Ensuite, tu peux tout simplement vérifier le nom de fichier uploadé mais pense à vérifier le \0 hack (je me rappelle plus mes références, si quelq'un peut confirmer ?) qui consiste à créer un fichier avec un nom illégal de la forme :
    Si je me rappelle bien, ce format de nom bypass les règles de sécurité habituelles.

    Dans un de mes script, j'utilisait ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    // Contrôler le nom du fichier
      if (preg_match('#[\x00-\x1F\x7F-\x9F/\\\\]#', $file['name']) || (substr_count($file['name'],'.') > 1))
         return $ret .= "\t- Ce nom de fichier est interdit pour des raisons de s&eacute;curit&eacute; -\n</div>\n";
     
      // Contrôler l'extention du fichier
      $mimes = array("image/jpeg","image/gif","image/png");
      $type  = mime_type_file (strtolower($file['name']));
      if (!in_array($type,$mimes))
         return $ret .= "\t- Les fichiers " . $file['type'] . " ne sont pas support&eacute;s -\n</div>\n";
    Bref, vérifie bien le PHP appellé par Ajax et ajoute des sécurités si nécéssaire.

  3. #3
    Lucas Panny
    Invité(e)
    Par défaut
    Le backoffice n'est pas exposé, il est protégé par authentification login+mdp (session).
    Le soucis c'est que c'est ajaxfilemanager qui est exposé donc, le hacker imagine juste où peut se trouver le plugin et mon site est foutu. De plus, j'utilise le framework jelix donc il arrive bien à imaginer où il peut bien être.

    L'authentification est gérée par une classe php qui crée une variable globale $GLOBAL["user"], comment peut-on l'utiliser dans ajax_file_upload.php de AjaxFileManager for TinyMCE???

  4. #4
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Dans ajax_file_upload.php tu rajoutes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if (isset($GLOBALS['user']))
    {
        // do the upload stuff...
    }
    else die('You must login before uploading');
    ça fera partir les requêtes ajax en erreur si l'utilisateur n'est pas connecté. Je ne connais pas ta classe modèle User mais tu peux rajouter un contrôle basique des droits par dessus le marché.

  5. #5
    Lucas Panny
    Invité(e)
    Par défaut
    J'ai déjà essayé cela mais cette variable est toujours NULL dans ce fichier, en effet j'utilise un framework php (JELIX) pour développer mon site, l'upload d'image étant une application tiers donc la portée de la variable paraît ne pas arriver jusque là

  6. #6
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Hello

    Je ne connais pas Jelix en détail, désolé.
    Tu ne peux pas faire les include qui vont bien ?

    -- Edit

    Remarque, Jelix, comme tout ses petits copains, doit sauvegarder une instance d'utilisateur sur la session. Fais donc un coup de var_dump($_SESSION) dans ton index.php (celui de Jelix si tu en as plusieurs) et trouve l'index correspondant à l'objet ou la structure caractérisant l'Utilisateur. Ensuite tu n'a plus qu'a mettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if (isset($_SESSION['< clé user >']))
    {
         // do upload stuff...
    }
    else die('You must be connected');

  7. #7
    Lucas Panny
    Invité(e)
    Par défaut
    Benjamin, me proposes-tu de mettre la session que j'utilise dans Jelix en variable superglobale ou session large je ne sais pas si ça existe?

    En fait, il me semble que les variables superglobales sont devenues obsolètes: http://php.net/manual/fr/security.globals.php

  8. #8
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Dieu merci, toute les variables superglobales ne sont pas obsolètes, tu dispose de:
    - $_SESSION pour la session en cours (initialisée uniquement si session_start() à été appelée précédemment)
    - $_POST pour les paramètres post
    - $_GEt pour les paramètres get
    - $_REQUEST pour les paramètres post et get
    - $_FILES pour les fichiers envoyés en multipart-formdata
    - $_SERVER pour diverses informations serveur
    - $_ENV pour diverses informations sur l'environnement
    - $GLOBALS pour enregistrer des variables globales (généralement mal vu)
    - $_COOKIES pour les cookies

    Lors qu'un utilisateur s'authentifie sur ton site, Jelix va créer une session et va mettre dans la variable $_SESSION des informations relatives à l'utilisateur.
    Tu peux, à tout moment et sous réserve d'appeler session_start(), utiliser la superglobale $_SESSION n'importe où. Y compris dans des pages qui ne sont pas originaires du framwork Jelix.

    La page que tu cites se réfère à une fonctionnalité de PHP qui permet d'utiliser les variables superglobales comme des variables habituelles sans pour autant savoir d'où elles proviennent. C'est un peu compliqué à comprendre, je vais essayer de t'éclairer sur ce point.

    Considérons le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    // Avec register_globals à 'on' dans php.ini tu peux utiliser une 
    // variable 'username' provenant de la session directement ainsi:
    session_start();
    echo $username;
    // ici username provient effectivement de $_SESSION['username']
    // et à été initialisé automatiquement par php, mais il peut
    // se produire un conflit avec $_GET['username']
    // qui se présentera également sous la forme $username
     
    // Avec register_globals à 'off' tu es obligé d'utiliser
    echo $_SESSION['username'];
    // ce qui est beaucoup plus sûr puisque dans ce cas, la 
    // collision n'aura jamais lieu avec d'autres structures
    // superglobales.
    Donc en gros, avoir register_globals à 'on' se résume virtuellement à avoir fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    extract($_SESSION);
    extract($_POST);
    extract($_GET);
    // etc...
    on comprends aisément où est la faille dans ce système.

  9. #9
    Lucas Panny
    Invité(e)
    Par défaut
    La session utilisée pour l'authentification contient donc une classe, en commençant par session_start() je n'arrive pas à soutirer les attributs et les méthodes de cette classe

    En faisant un var_dump() sur la $SESSION[], j'ai object(__PHP_Incomplete_Class)

    De plus en essayant d'appeler une méthode:
    Fatal error: main() [<a href='function.main'>function.main</a>]: The script tried to execute a method or access a property of an incomplete object.

  10. #10
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Citation Envoyé par Lucas Panny Voir le message
    La session utilisée pour l'authentification contient donc une classe, en commençant par session_start() je n'arrive pas à soutirer les attributs et les méthodes de cette classe
    La déclaration de ta classe doit être fait avant le session_start.
    session_start n'a pas à être en début de page tant que il n'ya pas de sortie (echo, print ...).

    Note que pour plus de sécurité , il est de bon ton de protéger tout les appels ajax et même de formulaire via un token.

    Une recherche "token csrf" sur google devrait t'éclairer.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. Upload de fichiers que pour certains fichiers
    Par kate59 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 09/02/2015, 19h26
  2. Réponses: 3
    Dernier message: 01/09/2012, 10h30
  3. [PHP 5.3] Uploade de fichier Zippe pour récupéré leur contenu
    Par geforce dans le forum Langage
    Réponses: 0
    Dernier message: 19/05/2010, 20h03
  4. Réponses: 0
    Dernier message: 25/01/2008, 08h55
  5. [Upload] Upload de fichiers : sécurité
    Par genova dans le forum Langage
    Réponses: 16
    Dernier message: 04/01/2006, 22h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo