remote - url injection php




Meilleur moyen d'éviter l'injection de code en PHP (7)

Mon site Web a récemment été attaqué par ce qui me semblait être un code innocent:

<?php
  if ( isset( $ _GET['page'] ) ) {
    include( $ _GET['page'] . ".php" );
  } else {
    include("home.php");
  }
?>

Là où aucun appel SQL, donc je n'ai pas eu peur pour l'injection SQL. Mais apparemment, SQL n'est pas le seul type d'injection.

Ce site Web a une explication et quelques exemples pour éviter l'injection de code: http://www.theserverpages.com/articles/webmasters/php/security/Code_Injection_Vulnerabilities_Explained.html

Comment protégeriez-vous ce code de l'injection de code?


@pek - Cela ne fonctionnera pas, car les clés de votre tableau sont 0 et 1, pas "home" et "page".

Ce code devrait faire l'affaire, je crois:

<?php

$whitelist = array(
  'home',
  'page',
);

if(in_array($_GET['page'], $whitelist)) {
  include($_GET['page'] . '.php');
} else {
  include('home.php');
}

?>

Comme vous avez une liste blanche, il ne devrait pas non plus y avoir besoin de file_exists() .


Je sais que c'est un très vieux message et je pense que vous n'avez plus besoin de réponse, mais il me manque encore un aspect très important à mon humble avis et je l'aime à partager avec d'autres personnes lisant cet article. Dans votre code pour inclure un fichier basé sur la valeur d'une variable, vous établissez un lien direct entre la valeur d'un champ et le résultat demandé (la page devient page.php). Je pense qu'il vaut mieux éviter cela. Il y a une différence entre la demande de certaines pages et la livraison de cette page. Si vous faites cette distinction, vous pouvez utiliser de bonnes URL, qui sont très conviviales et conviviales. Au lieu d'une valeur de champ telle que "page", vous pouvez créer une URL comme "Spinoza-Ethica". C'est une clé dans une liste blanche ou une clé primaire dans une table à partir d'une base de données et renverra un nom de fichier ou une valeur codée en dur. Cette méthode présente plusieurs avantages en plus d'une liste blanche normale:

  1. la réponse de back-end est effectivement indépendante de la requête frontale. Si vous souhaitez configurer votre système dorsal différemment, vous n'avez rien à changer sur le frontal.

  2. Assurez-vous toujours que vous terminez avec des noms de fichiers codés en dur ou un équivalent de la base de données (préférablement une valeur de retour d'une procédure stockée), car il demande des problèmes lorsque vous utilisez les informations de la demande pour générer la réponse.

  3. Étant donné que vos URL sont indépendantes de la diffusion du serveur principal, vous ne devrez jamais réécrire vos URL dans le fichier htAccess pour ce type de modification.

  4. Les URL représentées pour l'utilisateur sont conviviales, informant l'utilisateur du contenu du document.

  5. De bonnes URL sont très bien pour le référencement, car les moteurs de recherche sont à la recherche de contenu pertinent et lorsque votre URL est en ligne avec le contenu, il obtiendra un meilleur taux. Au moins un meilleur taux lorsque votre contenu ne correspond pas à votre contenu.

  6. Si vous ne liez pas directement à un fichier php, vous pouvez traduire l'URL agréable en tout autre type de requête avant de la traiter. Cela donne au programmeur beaucoup plus de flexibilité.

  7. Vous devrez nettoyer la demande, car vous obtenez les informations à partir d'une source non fiable standard (le reste du Web). Utiliser uniquement de bonnes URL comme entrée rend le processus de nettoyage de l'URL beaucoup plus simple, car vous pouvez vérifier si l'URL renvoyée est conforme à votre propre format. Assurez-vous que le format de l'URL sympa ne contient pas de caractères largement utilisés dans les exploits (comme ', ", <,>, -, &, etc ..).


La règle n ° 1 lors de l'acceptation d'une saisie utilisateur est toujours la désinfecter. Ici, vous ne désinfectez pas la variable GET de votre page avant de la passer à include. Vous devez effectuer une vérification de base pour voir si le fichier existe sur votre serveur avant de l'inclure.


Pek, il y a beaucoup de choses à se soucier d'un ajout à l'injection SQL, ou même de différents types d'injection de code. Le moment est peut-être venu d’examiner plus en détail la sécurité des applications Web en général.

A partir d'une question précédente sur le passage du bureau au développement Web , j'ai écrit:

Le guide OWASP pour la création d’applications Web et de services Web sécurisés devrait être une lecture obligatoire pour tout développeur Web qui souhaite prendre la sécurité au sérieux (ce qui devrait être tous les développeurs Web). Il y a beaucoup de principes à suivre qui aident à la mentalité nécessaire pour penser à la sécurité.

Si lire un gros document n'est pas pour vous, alors regardez la vidéo du séminaire que Mike Andrews a donné à Google il y a quelques années à propos de How To Break Web Software .


Quelques bonnes réponses jusqu’à présent, valent également la peine d’indiquer quelques spécificités de PHP:

Les fonctions d'ouverture de fichier utilisent des wrappers pour prendre en charge différents protocoles. Cela inclut la possibilité d'ouvrir des fichiers sur un réseau Windows local, HTTP et FTP, entre autres. Ainsi, dans une configuration par défaut, le code de la question d'origine peut facilement être utilisé pour ouvrir un fichier arbitraire sur Internet et au-delà. y compris, bien sûr, tous les fichiers sur les disques locaux du serveur (que l'utilisateur du serveur Web peut lire). /etc/passwd est toujours amusant.

Le mode sans échec et open_basedir peuvent être utilisés pour restreindre l' open_basedir aux fichiers en dehors d'un répertoire spécifique.

Le paramètre de configuration allow_url_fopen est également utile, allow_url_fopen permet de désactiver l'accès URL aux fichiers lors de l'utilisation des fonctions d'ouverture de fichier. ini-set peut être utilisé pour définir et désélectionner cette valeur lors de l'exécution.

Ce sont tous de bons gardes de sécurité, mais veuillez utiliser une liste blanche pour l'inclusion de fichiers.


Une autre façon de nettoyer l’entrée consiste à s’assurer que seuls les caractères autorisés (no "/", ".", ":", ...) sont inclus. Cependant, n'utilisez pas de liste noire pour les caractères incorrects , mais une liste blanche pour les caractères autorisés:

$page = preg_replace('[^a-zA-Z0-9]', '', $page);

... suivi d'un file_exists.

De cette façon, vous pouvez vous assurer que seuls les scripts que vous voulez exécuter sont exécutés (par exemple, cela exclurait un "blabla.inc.php", car "." N'est pas autorisé).

Note: Ceci est une sorte de "hack", car alors l'utilisateur pourrait exécuter "home" et cela donnerait la page "home", car tout ce qu'il fait est de supprimer tous les caractères interdits. Cela n'a pas pour but d'arrêter les "smartasses" qui veulent des trucs mignons avec votre page, mais cela empêchera les gens de faire de très mauvaises choses.

BTW: Une autre chose que vous pourriez faire dans votre fichier .htaccess est d'empêcher les tentatives d'attaque évidentes:

RewriteEngine on
RewriteCond %{QUERY_STRING} http[:%] [NC]
RewriteRule .* /–http– [F,NC]
RewriteRule http: /–http– [F,NC]

De cette façon, tous les accès à la page avec l'URL "http:" (et la chaîne de requête) génèrent un message d'erreur "Interdit", n'atteignant même pas le script php. Cela se traduit par une charge moindre du serveur.

Cependant, gardez à l'esprit qu'aucun "http" n'est autorisé dans la chaîne de requête. Votre site Web pourrait en avoir besoin dans certains cas (peut-être en remplissant un formulaire).

BTW: Si vous pouvez lire l'allemand: j'ai aussi un blog sur ce sujet.


pek, pour une solution à court terme, appliquez l'une des solutions proposées par d'autres utilisateurs. Pour un plan à moyen et long terme, vous devriez envisager de migrer vers l'un des frameworks Web existants. Ils gèrent tous les éléments de bas niveau tels que le routage et l'inclusion de fichiers de manière fiable et sécurisée, pour que vous puissiez vous concentrer sur les fonctionnalités de base.

Ne réinventez pas la roue. Utilisez un cadre. Chacun d'entre eux est meilleur que rien. Le temps d’investissement initial dans l’apprentissage est presque instantané.





code-injection