Comment prévenir les attaques par injection de code en PHP?

je suis confus, il y a tellement de fonctions dans PHP, et certaines utilisant ceci, d'autres utilisant cela. Certaines personnes utilisent: htmlspecialchars() , htmlentities() , strip_tags() etc

qui est le bon et qu'est-ce que vous utilisez d'habitude?

Est-ce correct (me conseiller un meilleur, le cas échéant):

$var = mysql_real_escape_string(htmlentities($_POST['username']));

cette ligne peut empêcher L'injection MySQL et XSS attact??

Btw, est-il y a-t-il autre chose que je dois faire attention à côté de XSS attack et MySQL injection?

MODIFIER

pour conclure:

Si je veux insérer une chaîne de base de données, je n'ai pas besoin d'utiliser htmlentities , il suffit d'utiliser la mysql_real_escape_string . En affichant les données, utilisez htmlentities() , est-ce que c'est ce que vous voulez dire??

Résumer:

  • mysql_real_escape_string utilisé lors de l'insertion dans la base de données
  • htmlentities() utilisé lors de la sortie des données dans la page Web
  • htmlspecialchars() utilisé quand?
  • strip_tags() utilisé quand?
  • addslashes() utilisé quand?

Quelqu'un peut-il remplir le point d'interrogation?

47
demandé sur Gumbo 2009-07-30 15:04:05

8 réponses

  • mysql_real_escape_string utilisé lors de l'insertion dans la base de données
  • htmlentities() utilisé lors de la sortie des données dans la page web
  • htmlspecialchars() utilisé quand?
  • strip_tags() utilisé quand?
  • addslashes() utilisé quand?

htmlspecialchars() utilisé quand?

htmlspecialchars est à peu près le même que htmlentities . La différence: les encodages de caractères.

les deux encodent des caractères de contrôle comme < , > , & et ainsi de suite utilisé pour ouvrir des étiquettes, etc. htmlentities permet également d'encoder des caractères d'autres langues comme les umlauts, les euro-symboles et autres. Si vos sites Web sont UTF, utilisez htmlspecialchars() , sinon utilisez htmlentities() .

strip_tags() utilisé quand?

htmlspecialchars / entities coder le spécial les caractères, donc ils sont affiché mais pas interprété . strip_tags les supprime.

Dans la pratique, cela dépend de ce que vous devez faire.

un exemple: vous avez codé un forum, et donnez aux utilisateurs un champ de texte pour qu'ils puissent poster des trucs. Les méchants essaient juste:

pictures of <a href="javascript:void(window.setInterval(function () {window.open('http://evil.com');}, 1000));">kittens</a> here

Si vous ne faites rien, le lien sera affiché et une victime qui clique sur le lien obtient beaucoup de pop-ups.

si vous htmlentity/htmlspécialchar votre sortie, le texte sera là tel quel. Si vous le strip_tag, il supprime simplement les tags et l'affiche:

pictures of kittens here

parfois vous pouvez vouloir un mélange, laissez quelques étiquettes là, comme <b> ( strip_tags peut laisser certaines étiquettes là). C'est dangereux aussi, donc mieux utiliser une bibliothèque complète contre XSS.

addslashes

pour citer un Vieux version du manuel PHP :

renvoie une chaîne avec des antislashs avant les caractères qui doivent être cités dans les requêtes de base de données, etc. Ces caractères sont single quote ( '), double quote ( " ), backslash (") et NULL ( Byte").

un exemple d'utilisation de addslashes () est lorsque vous saisissez des données dans une base de données. Par exemple, pour insérer le nom O'reilly dans une base de données, vous aurez besoin d'y échapper. Il est fortement recommandé d'utiliser la fonction d'échappement spécifique au SGBD (par exemple mysqli_real_escape_string() pour MySQL ou pg_escape_string() pour PostgreSQL), mais si le SGBD que vous utilisez n'a pas de fonction d'échappement et que le SGBD utilise \ pour échapper à des caractères spéciaux, vous pouvez utiliser cette fonction.

la version actuelle est formulée différemment.

59
répondu stefs 2018-02-24 20:14:25

ne coder les données qu'au point où elles entrent dans le système pour lequel elles doivent être codées - sinon, vous vous retrouverez dans des situations où vous voulez manipuler les données réelles.

Pour l'injection SQL - utiliser des variables liées, comme décrit dans Comment puis-je prévenir l'injection SQL en PHP? (il parle de déclarations préparées, mais c'est le liant qui vous donne la protection, pas la préparation).

pour XSS - si vous écrivez en HTML au point où soit HTML soit texte est spécifié. Utilisez htmlentities au point où vous générez votre document. J'éviterais de stocker les données sous cette forme dans la base de données (sauf possible dans un système d'écriture-rare-read-often où les performances du CPU/les temps d'accès au disque devenaient et émettaient - alors j'aurais une version raw_ et html_ de la colonne ... ou juste utiliser memcached ou similaire).

si vous laissez les utilisateurs entrer des URLs, alors vous devez être plus prudent, comme javascript:do_evil() est un URI valide qui exécutera (par exemple comme un href pour un lien cliqué sur ou (dans certains navigateurs) Le src d'une image qui vient d'être chargée).

5
répondu Quentin 2017-05-23 10:31:15

j'ai pensé à cette courte liste:

  • Utilisez toujours HTTPS, sans HTTPS votre site est totalement non crypté . Et non, crypter des choses côté client et les envoyer ne marchera pas, pensez-y. les certificats HTTPS invalides vous rendent également vulnérable à une MITM attack . Il suffit d'utiliser Let's Encrypt si vous ne pouvez pas vous permettre un certificat.
  • Utilisez toujours htmlspecialchars() sur n'importe quelle sortie de votre code PHP, c'est-à-dire, ou contient une entrée utilisateur . La plupart des moteurs de templage vous aident à le faire facilement.
  • utilisez L'option HTTP-only dans votre php.ini pour empêcher les scripts d'accéder à vos cookies
  • prévenir les problèmes liés aux sessions
    • ne Jamais exposer l'utilisateur PHPSESSID (session ID) à l'extérieur du cookie , si quelqu'un apprend à connaître un ID de Session de quelqu'un d'autre, ils peuvent simplement l'utiliser pour se connecter à leur compte
    • soyez très prudent avec la fonction Remember me , montrez un petit avertissement peut-être.
    • Actualiser ID de session lorsque l'utilisateur se connecte (ou quel que soit le cas)
    • Délai d'attente de sessions inactives
  • jamais faites confiance à un cookie, il peut être changé, supprimé, modifié et créé par un script/utilisateur à tout moment
  • prévenir les problèmes liés à SQL
    • toujours utiliser les déclarations préparées . Les instructions préparées font passer l'entrée de l'utilisateur séparément et empêchent injection SQL
    • "
    • faites que votre code jette une exception quand il échoue. Parfois votre serveur SQL peut être en panne pour une raison quelconque, les bibliothèques comme PDO ignorent cette erreur par défaut, et enregistrez un avertissement dans les journaux. Cela provoque les variables que vous obtenez à partir de la base de données pour être null, en fonction de votre code, cela peut causer un problème de sécurité.
    • certaines bibliothèques comme PDO émulent déclarations préparées. Désactiver cette fonction.
    • utiliser UTF-8 encodage dans vos bases de données, il vous permet de stocker pratiquement tous les caractères et d'éviter les attaques liées à l'encodage
    • Jamais concaténer n'importe quoi pour votre requête . Des choses comme $myquery = "INSERT INTO mydb.mytable (title) VALUES(" . $user_input . ")" signifient à peu près que vous avez un énorme risque de sécurité d'une injection SQL.
  • stocke les fichiers téléchargés au hasard,sans extension. Si un utilisateur télécharge un fichier avec l'extension .php , à chaque fois que votre code charge ce fichier, il l'exécute et permet à l'utilisateur d'exécuter du code d'arrière-plan
  • assurez-vous que vous n'êtes pas vulnérable à un CSRF attaque .
  • Toujours mettre à jour votre copie PHP pour assurer les dernières corrections de sécurité et les améliorations de performance""
5
répondu OverCoder 2018-02-24 19:38:51

il vous suffit d'utiliser mysql_escape_string() lors de l'insertion dans une base de données et htmlentites lors de l'affichage du HTML. Ceci est suffisant si vous voulez éviter une simple attaque par injection, mais il y a sans doute beaucoup d'autres problèmes de sécurité que vous devriez être au courant lors du développement d'une application web, un autre important étant la falsification de requêtes intersite.

3
répondu Sam152 2009-07-30 11:08:22

htmlspecialchars() virages & , ' , " , < , et > dans un format d'entité HTML ( &amp; , &quot; , etc.)

htmlentities() transforme tous les caractères applicables en leur format d'entité HTML.

strip_tags() supprime toutes les balises HTML et PHP.

à la fois htmlspecialchars() et htmlentities() prendre un paramètre optionnel indiquant comment les guillemets doivent être manipulés. Voir la Manuel PHP pour les détails.

la fonction strip_tags() prend une paramètre optionnel indiquant quelles balises ne doit pas être dépouillé.

 $var = strip_tags ($var, '<p><br />');

la fonction strip_tags() supprimera même les balises HTML invalides, qui peuvent causer des problèmes. Exemple, strip_tags() arrachera tout le code qu'il pense être une balise HTML, même si c'est mal formé, comme

<b I forgot to close the tag.
3
répondu Faraz Kelhini 2018-02-24 19:26:21

Je n'utiliserais pas htmlentities() pour insérer des données dans la base de données ou pour interroger la base de données. Si les données dans votre base de données sont stockées en tant qu'entités, ces données ne sont alors utiles que pour quelque chose qui comprend les entités html.

vous devez utiliser différents mécanismes d'échappement pour différents types de sortie, p.ex. SQL - mysql_real_escape_string () , HTML - htmlentities () ou htmlspecialchars () , shell - escapeshellarg () . C'est parce que les caractères qui sont "dangereux" sont différents pour chacun d'eux - il n'y a pas de moyen magique de rendre n'importe quelles données sûres pour n'importe quel médium de sortie.

2
répondu Tom Haigh 2009-07-30 11:11:13

consultez ce site PHP Security Consortium . J'ai trouvé que C'était un bon site pour une vue d'ensemble sur la sécurité PHP (injection SQL et XSS inclus).

1
répondu Henrik P. Hessel 2009-07-30 11:07:15

je sais que c'est une vieille question, mais de nos jours la réponse la plus votée peut être trompeuse pour les débutants.

en date de 2017

  1. vous ne devez jamais utiliser mysql_real_escape_string. Même mysqli_real_escape_string est trop faible pour protéger votre base de données des injections SQL. Au lieu de cela, vous devriez utiliser AOP, et des techniques similaires. (voir ce guide )

  2. XSS (ici je veux dire: strip_tags() , addslashes() , htmlspecialchars() , htmlentities() ) - ici, la réponse la plus votée est toujours correcte, mais je suggérerais de lire cet article

1
répondu Thomas 2017-12-10 22:14:46