Partage
  • Partager sur Facebook
  • Partager sur Twitter

Sécuriser un fichier PHP

    26 avril 2017 à 20:06:55

    Salut !

    Voici la question: comment bien sécuriser un fichier PHP des requêtes extérieures ?

    Je m'explique, j'ai plusieurs AJAX sur mon site qui font des requêtes POST et GET à des fichier PHP. On peut donc voir le chemin d'accès des fichiers sur le fichier JS. Et j'aimerais éviter que des personnes s'amusent à requêté ce fichier.

    Première solution: l'utilisation du HTTP_REFERER qui indique d'où provient la requête, donc j'ai eu l'idée de tester cette variable pour voir si la requête provient de mon site. Or la doc PHP indique que cette variable n'est pas fiable car certain navigateur donne la possibilité de la changer, ou ne la remplisse même pas.

    Deuxième solution: "Chiffrer les fichiers JS", c'est à dire que la string indiquant le chemin d'accès sera illisible par un humain en utilisant des caractères haxedecimal etc... Cela marche très bien mais des sites permettent de "déchiffrer" ces mêmes fichiers.

    J'ai pensé aux tokens de connexion stocké en $_SESSION, mais s'il est connecté en même temps sur le site bah sa requête passera sans problème.

    Du coup j'attends d'autres idées ! :D

    Je suis curieux de savoir comment vous sécurisez vos fichiers PHP !

    • Partager sur Facebook
    • Partager sur Twitter
      27 avril 2017 à 0:00:41

      Bonjour,

      Il y a des astuces qui te permettent de déjouer les moins malins, notamment en regardant les headers ou en cachant le JS.
      Mais il est impossible de le rendre complètement inaccessible. :)

      • Partager sur Facebook
      • Partager sur Twitter
        27 avril 2017 à 1:04:09

        Aro a écrit:

        Bonjour,

        Il y a des astuces qui te permettent de déjouer les moins malins, notamment en regardant les headers ou en cachant le JS.
        Mais il est impossible de le rendre complètement inaccessible. :)


        J'aimerais le sécuriser un maximum, car je me suis déjà fait avoir sur d'ancien site ;) Je continu mes recherches !
        • Partager sur Facebook
        • Partager sur Twitter
          27 avril 2017 à 7:28:13

          Bonjour,

          1. En Php tu n'as qu'a accepter uniquement les requetes en AJAX
          Du coup, si une personne essaie de faire une requete depuis un autre endroit que ta page, ca ne fonctionnera pas (car il y aura une erreur de cross domaine)

          2. En parallele de la solution 1 (qui n'est pas infaible), met en place un token unique qui te permettra d'etre certain de la provenance du message

          3. Ensuite, je te conseille de creer une page de simulation de success

          En gros, si la personne essaie d'acceder a ta page sans faire une requete AJAX au lieu d'afficher une grosse erreur. Simule un succes !
          C'est ce que je fais sur pas mal de site.
          En effet, si apres un test le pirate arrive sur une page d'erreur, il essayera une autre piste. En revanche si il arrive sur une page de succes il continuera son inspection et ne comprendra plus rien.
          Toi de ton cote, tu dois mettre en place un script qui te permet de detecter les personnes qui ont accede a ces pages de fake success (car en temps normal ils de devraient pas y arriver). Ensuite block ces personnes par exemple. Ces personnes seront bloques sans avoir compris pourquoi (si tu fais ca rapidement).

          • Partager sur Facebook
          • Partager sur Twitter
            27 avril 2017 à 10:12:37

            Quand tu dis que tu fais une requête ajax, tu parle d'une url type : /ajax/mon_traitemant_ajax.php ? ou plutôt d'une url /traitement-ajax ?

            Si tu fais le premier cas je te conseil de passer à l'url rewriting. Déjà tu n'aura plus de soucis car l'url ne reflète pas ton architecture.

            Par contre ça n'empêche pas de connaitre l'url et donc il faut que tu sécurise comme expliqué par @Scion

            • Partager sur Facebook
            • Partager sur Twitter
              27 avril 2017 à 18:05:20

              Scion a écrit:

              1. En Php tu n'as qu'a accepter uniquement les requetes en AJAX

              Du coup, si une personne essaie de faire une requete depuis un autre endroit que ta page, ca ne fonctionnera pas (car il y aura une erreur de cross domaine)

              2. En parallele de la solution 1 (qui n'est pas infaible), met en place un token unique qui te permettra d'etre certain de la provenance du message


              Pour la solution 1, comme je le disais, en vérifiant les headers notamment, tu peux savoir si c'est de l'aJax, mais il est très (très) facile avec une simple extension de navigateur de faire mentir ces headers et de faire passer ta requête normale pour une requête aJax.

              Pour ta solution 2, je suis curieux, comment tu la mets en place concrètement ? Au moment où tu génères la page qui va faire la requête aJax, tu vas créer un jeton que tu insères en BDD avec une durée de vie limitée et que tu vas coller en argument dans la requête aJax ? Ce qui veut dire que tu as en BDD un nombre de jetons équivalent au nombre d'utilisateurs multiplié par le nombre de pages visitées au cours des dernières 5 minutes si le jeton a une durée de vie de 5 minutes ? L'idée est pas mauvaise, je t'ai bien compris ?

              • Partager sur Facebook
              • Partager sur Twitter
                27 avril 2017 à 22:53:37

                Scion a écrit:

                Bonjour,

                1. En Php tu n'as qu'a accepter uniquement les requetes en AJAX
                Du coup, si une personne essaie de faire une requete depuis un autre endroit que ta page, ca ne fonctionnera pas (car il y aura une erreur de cross domaine)

                2. En parallele de la solution 1 (qui n'est pas infaible), met en place un token unique qui te permettra d'etre certain de la provenance du message

                3. Ensuite, je te conseille de creer une page de simulation de success

                En gros, si la personne essaie d'acceder a ta page sans faire une requete AJAX au lieu d'afficher une grosse erreur. Simule un succes !
                C'est ce que je fais sur pas mal de site.
                En effet, si apres un test le pirate arrive sur une page d'erreur, il essayera une autre piste. En revanche si il arrive sur une page de succes il continuera son inspection et ne comprendra plus rien.
                Toi de ton cote, tu dois mettre en place un script qui te permet de detecter les personnes qui ont accede a ces pages de fake success (car en temps normal ils de devraient pas y arriver). Ensuite block ces personnes par exemple. Ces personnes seront bloques sans avoir compris pourquoi (si tu fais ca rapidement).


                Pour ta solution 1 j'ai vu ça oui et je l'ai noté !

                Concernant la solution 2 j'y ai pensé, mais si en parallèle il est connecté et qu'il regarde les headers par exemple il pourra avoir le token et si je le stocke en SESSION il suffira qu'il soir connecté.

                Ta solution 3 est pas mal et c'est à peu près le genre de choses dont j'aurais besoin.

                quenti77 a écrit:

                Quand tu dis que tu fais une requête ajax, tu parle d'une url type : /ajax/mon_traitemant_ajax.php ? ou plutôt d'une url /traitement-ajax ?

                Si tu fais le premier cas je te conseil de passer à l'url rewriting. Déjà tu n'aura plus de soucis car l'url ne reflète pas ton architecture.

                Par contre ça n'empêche pas de connaitre l'url et donc il faut que tu sécurise comme expliqué par @Scion


                Oui j'utilise déjà l'URL rewriting c'est plutôt utile pour ne pas montrer l'architecture comme tu dis.
                • Partager sur Facebook
                • Partager sur Twitter
                  28 avril 2017 à 1:55:02

                  "Et j'aimerais éviter que des personnes s'amusent à requêté ce fichier."

                  Tu n'as qu'a afficher ton script js via Php directement.
                  Php va te permettre de controler ce que tu veux. Dans ton cas c'est le nombre de requete effectue.

                  Facebook utilise ce systeme par exemple avec ses images. C'est generer par Php et il y a un controle dessus (ici, c'est si tu n'est pas mon ami tu ne peux pas voir l'image du coup a la place de l'image tu as un autre truc).

                  Twitter, Instagrem, etc... font la meme chose par exemple avec leur fichier json. Il y a un controle sur le nombre de requete par utilisateur.

                  ==> tu n'as plus qu'a faire la meme chose.

                  Un exemple (pas propre mais tu vas voir l'idee):

                  <?php
                  	header('Content-Type: application/json');
                  	// Ici je controle
                  
                  	$file = "./fake.js";
                  	if ( /* TON TEST EST OK */ ) {
                  		$file = "./good.js"; 
                  	}
                  	echo json_encode(file_get_contents($file));
                  ?>
                  Ensuite via de l'URL rewriting tu fais en sorte que ton URL ne soit pas avec un extension .php mais .js par exemple

                  -
                  Edité par Scion 28 avril 2017 à 1:55:29

                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 avril 2017 à 17:17:49

                    Scion a écrit:

                    "Et j'aimerais éviter que des personnes s'amusent à requêté ce fichier."

                    Tu n'as qu'a afficher ton script js via Php directement.
                    Php va te permettre de controler ce que tu veux. Dans ton cas c'est le nombre de requete effectue.

                    Facebook utilise ce systeme par exemple avec ses images. C'est generer par Php et il y a un controle dessus (ici, c'est si tu n'est pas mon ami tu ne peux pas voir l'image du coup a la place de l'image tu as un autre truc).

                    Twitter, Instagrem, etc... font la meme chose par exemple avec leur fichier json. Il y a un controle sur le nombre de requete par utilisateur.

                    ==> tu n'as plus qu'a faire la meme chose.

                    Un exemple (pas propre mais tu vas voir l'idee):

                    <?php
                    	header('Content-Type: application/json');
                    	// Ici je controle
                    
                    	$file = "./fake.js";
                    	if ( /* TON TEST EST OK */ ) {
                    		$file = "./good.js"; 
                    	}
                    	echo json_encode(file_get_contents($file));
                    ?>

                    Ensuite via de l'URL rewriting tu fais en sorte que ton URL ne soit pas avec un extension .php mais .js par exemple

                    -
                    Edité par Scion il y a environ 15 heures

                    Salut ! Merci de ta réponse mais je n'ai pas très bien compris. Tu veux donc afficher le script JS grâce au PHP, mais je ne comprend pas comment bloqué les requêtes extérieures. Peux-tu expliquer ton exemple il m'intéresse beaucoup !
                    • Partager sur Facebook
                    • Partager sur Twitter
                      28 avril 2017 à 18:43:32

                      Salut,

                      Techniquement tu ne peux pas empècher quelqu'un de lancer une requete AJAX sur ton site, la seule chose sur laquelle tu peux agir c'est vérifier que ce quelqu'un a bien le droit d'accèder à la resource dans un contexte particulier et de bloquer l'execution de cette page/resource si les critères ne sont pas respectés.

                      Donc par exemple tu peux :

                      1) Commencer par mettre tous tes scripts de reception AJAX en POST, ça évite les petit malins qui traficotent les URLs et ça démotive une grande partie du reste qui devront utiliser ou developper des outils pour envoyer les requetes.

                      2) Ajouter un jeton CSRF pour empècher une grande partie les scripts automatiques sur tes pages AJAX, sa démotive les developeurs amateurs qui voudrait lancer une requete directe sur tes scripts, dans ce cas là ils doivent se connecter automatiquement au site, récupérer le jeton, et générer la requete en POST, c'est un peu plus chiant à mettre en place.

                      3) Vérifier que l'utilisateur ait le droit d'accèder à la ressource, tous les utilisateurs n'ont pas le droit d'acceder aux mêmes ressources, en vérifiant par exemple que l'utilisateur soit bien authentifié/connecté à son compte.

                      4) Vérifier que l'utilisateur ait le droit d'effectuer une action, i.e. seuls les admins peuvent effectuer certaines actions, seul un utilisateur peut supprimer ses propres dossiers/fichiers, etc...

                      5) Vérifier l'utilisation que font les utilisateurs des scripts AJAX, par exemple on peut limiter le nombre de requetes/actions par unité de temps, et bloquer les scripts si les quotas sont dépassés + logger les excès + bloquer les utilisateurs de façon temporaire ou permanente selon les cas.

                      C'est déjà largement suffisant!

                      -
                      Edité par Sombrelune 28 avril 2017 à 18:45:14

                      • Partager sur Facebook
                      • Partager sur Twitter
                      - Activer les erreurs : PHP - PDO - MYSQLI - ¯\_ツ_/¯ - Documentations : PHP - MySQL -
                        29 avril 2017 à 1:11:09

                        Voici un exemple de code pour le fichier toto.php (que je n'ai pas teste mais il devrait etre bon):

                        	header('Content-Type: application/json');
                        
                        	// On demarre la session
                        	session_start();
                        
                        	// Quelque fonctions utile...
                        
                        	function isAjax() {
                             return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
                        	}
                         
                        	function getIp() {
                        		if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
                        			$ip = $_SERVER['HTTP_CLIENT_IP'];
                        		} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                        			$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                        		} else {
                        			$ip = $_SERVER['REMOTE_ADDR'];
                        		} else {
                        			$ip = "UNDEFINED";
                        		}
                        		return $ip;
                        	}
                        
                        	// Le fichier js par defaut 
                        	$file = "./fake.js";
                        
                        	// On recupere la session de l'utilisateur
                        	$ip = getIP();
                        
                        	// On met en session l'ip de l'internaute
                        	if (!empty($_SESSION[$ip])) {
                        		$_SESSION[$ip]++; // On l'incremente
                        	} else {
                        		$_SESSION[$ip] = 1; // Ou on la cree si elle n'existe pas
                        	}
                        
                        	// Si on ce script est affiche via une requete AJAX et si ce n'est pas une tentative plus grande que 5
                        	if (isAjax() && $_SESSION[$ip] < 5) {
                        		$file = "./good.js";
                        	}
                        
                        	// On recupere le contenu du fichier $file est on l'affiche
                        	echo json_encode(file_get_contents($file));
                        
                        ?>

                        Dans un 1er temps je definis le header. Je dis que cette page est du json (mais tu peux dire que ta page est une image, une video, un pdf, etc..)

                        Dans un second temps je demarre une session (afin de pouvoir stocker les infos et quelle soit dispo si on recharge la page)

                        Ensuite je definis des fonctions qui me seront utile comme par exemple isAjax() qui me permet de savoir si il s'agit bien d'une requete fait en AJAX (potentiellement une personne pourrait simuler une requete AJAX mais dans 90% des cas il ne le ferra pas sauf si il realise qu'il y a une difference entre une requete classique et un requete AJAX)

                        Ensuite je definis le fichier par defaut fake.js

                        Ensuite je recupere l'ip de l'internaute et je la met en session (si elle n'y est pas encore) et je l'ncremente de 1.

                        Pourquoi?

                        Imaginons que j'ai envie que mon script ne soit consultable que maximum 4 fois (un peu comme les API de twitter, google maps, etc.. qui limite le nombre de requete par heure et par jour). Eh bien avec la session et l'ip je peux potentiellement savoir combien de fois un internaute a afficher la page et donc le limiter a 4 fois.
                        ---> Encore une fois ce n'est pas infaible, car un internaute pourra passer par un proxy si il realise qu'au 5ieme affichage il est bloque. Mais encore une fois il ne le ferra pas sauf si il realise qu'il y a une difference entre une requete classique et un requete AJAX.

                        Ensuite tu fais ta condition, dans mon cas la condition est : 

                        - si c'est une requete AJAX 
                        - et si c'est une tentative inferieur a 4

                        Je definis le bon fichier good.js

                        Ensuite je recupere le contenu de ce fichier et je l'affiche.

                        Puis via l'URL Rewriting, tu peux faire en sorte que si l'internaute va sur http://tonsite.com/machin.js eh bien ca affiche en fait le contenu de toto.php 

                        RewriteRule ^machin.js$ /toto.php [L]


                        Tu as compris l'idee ?

                        Moi j'ai fais un cas simple mais toi tu peux modifier les conditions. L'idee c'est qu'il y est toujours un resultat positif
                        En effet il faut te mettre a la place du hacker:

                        - tu test une url
                        - puis l'url ne fonctionne plus (en affichant un message d'erreur ou une page blanche) alors qu'elle fionctionne avant
                        - donc par exemple tu supprime les variable de cookies et tu recommence et la ca fonctionne a nouveau
                        - puis ca ne fonctionne plus bizarrement (en affichant un message d'erreur ou une page blanche)

                        Ah ce moment la si tu es logique tu vas comprendre que le site utilise les sessions pour te faire chier
                        donc tu n'auras juste qu'a trouver une solution

                        Alors que si l'url fonctionne toujours le hacker aura plus de mal a trouver le probleme.

                        Ensuite, je te conseille de :

                        - mettre du code inutile dans tes fichier fake.js et good.js

                        - et de comnpresser les fichier fake.js et good.js (exemple en utilisant: https://closure-compiler.appspot.com/home)

                        Le fait de compresser le code rendra son analyse plus difficile a decrypter + si il y a du code inutile (aui plus est crypte en plus) ca sera chiant pour une personne

                        PS: Si une personne veut vraiment ton source, il y arrivera mais si tu lui met des batons dans les roues je pense qu'il abandonnera car est ce que ton site en faudra la peine pour lui?

                        voila...

                        • Partager sur Facebook
                        • Partager sur Twitter
                          29 avril 2017 à 2:17:34

                          @Scion super merci ! Je pense avoir compris, je vais installer un maximum de sécurité et compressé le JS. Ensuite le résultat qu'il peut obtenir en hackant le site ne lui sera quasiment pas bénéfique.

                          Merci beaucoup pour le temps que tu as pris a expliqué et pour le morceau de code. (si seulement les dev que j'avais essayé de recruté avait été aussi performant que toi ^^)

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Sécuriser un fichier PHP

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown