2010-07-15 5 views
3

J'ai travaillé sur une application qui permettra de construire des extensions tierces pour étendre les fonctionnalités de l'application. Tout cela en PHP, bien sûr. Je voulais ajouter un peu de remplissage de sécurité en exécutant des fichiers dans un certain répertoire grâce à une fonction de somme de contrôle. Si le fichier ne passe pas la somme de contrôle, le fichier n'est pas "inclus", l'administrateur de cette installation est averti et le module est désactivé jusqu'à ce que l'administrateur agisse (ré-active et enregistre l'exception, ou réinstalle le module) .PHP Checksum before include()

Le problème que j'ai en ce moment est de pouvoir exécuter cette somme de contrôle chaque fois qu'un utilisateur exécute la fonction include(). Je préfère ne pas les faire exécuter deux fonctions dos à dos juste pour inclure un fichier, mais si je dois le faire. Toutes les extensions tierces ne seront pas très disposées à exécuter deux fonctions (quelque chose comme if(checksum_function($bleh)) include($bleh);), et même si elles l'étaient, il serait beaucoup plus facile (et plus sûr) d'exécuter la somme de contrôle chaque fois que include() est exécutée, au lieu de doubler le nombre de lignes pour les instructions include(). J'ai fait quelques recherches et n'ai pas trouvé grand-chose. Des idées? Merci d'avance!

Répondre

0

Si vos includes sont des classes nommées d'après un certain système (par exemple MyPlugin_Text), vous pouvez utiliser PHP autoloading. Le chargement automatique peut être utilisé pour inclure automatiquement un fichier lorsqu'un objet d'une classe est créé pour la première fois.

exemple extrêmement simplifié:

function __autoload($class_name) { 

    require_once $class_name . '.php'; 
} 

$myTextPlugin = new MyPlugin_Text(); 

De toute évidence, vous allez vouloir étendre le chargeur automatique, par exemple Pour effectuer le préchargement uniquement pour les classes commençant par MyPlugin_ et charger celles provenant d'un dossier spécifique.

Je ne connais pas d'autre moyen de réaliser ce que vous voulez faire, sauf écrire une fonction wrapper personnalisée.

J'aime votre idée en général. Cependant, calculer une somme de contrôle - par ex. en utilisant crc32() - est relativement coûteux. Il ne devrait pas y avoir trop, et pas trop grand, inclut chargé de cette façon. Aussi, il va de soi que si un attaquant est capable de modifier les fichiers PHP sur votre système, ils peuvent également les exécuter directement sans avoir besoin de votre application centrale. Le gain de sécurité réel de cet exercice est susceptible d'être faible.

+0

Une collision crc peut être calculée en utilisant l'algèbre. – rook

+0

Merci beaucoup Pekka. J'allais utiliser md5 pour mes sommes de contrôle, mais j'imagine que ce serait encore plus cher. Je n'avais pas pensé à utiliser __autoload(). Je pourrais mettre de côté cette idée, car elle pourrait être très coûteuse une fois que tout le reste aura été mis en œuvre. Cependant, je vais certainement jouer avec __autoload() un peu. Merci! – Swivel

+0

@The Rook vous voulez dire pour un script malveillant de réparer le fichier afin qu'il passe le test? Dans la plupart des cas, je pense que cela ne constituera pas un danger car si un attaquant a) est conscient du mécanisme de sécurité et b) peut écrire des fichiers sur l'espace web en question, tout est perdu de toute façon. Toujours, bon point. –

0

envisager d'écrire un wrapper pour include:

function include_safe($library) { 
    if(checksum_function($library)) 
     include($library); 
} 

Vous ne trouverez pas beaucoup de développeurs qui sont « heureux » d'utiliser des fonctionnalités comme ça, mais vous pouvez aussi ne pas remplacer les constructions de langage PHP (comme include et require). Avoir une fonction qui enveloppe tout est pratique et rapide, donc les développeurs sont susceptibles de l'utiliser.

+0

Quelle somme de contrôle voulez-vous? Comment allez-vous vérifier que cette somme de contrôle se rapporte à quelque chose que vous voulez inclure? Que diriez-vous de ce que je vais utiliser cette fonction 'make_everything_secure_ever()' et alors personne ne me piratera. N'aimeriez-vous pas savoir ce que fait cette fonction? Moi aussi. – rook

+1

@Rook L'OP recherche une syntaxe appropriée pour la solution, pas une implémentation de sécurité.En fait, l'OP a même donné le nom 'checksum_function', si vous deviez réellement lire la question. Une réponse plus appropriée de ma part serait de conseiller le PO d'utiliser des décorateurs, bien qu'ils ne soient malheureusement pas présents en PHP. Je peux comprendre que vous êtes amer, mais voter avec véhémence et laisser des commentaires ouvertement ignorants est ce que j'appellerais «non professionnel». – mattbasta

+0

Merci, mattbasta. – Swivel

0

Dans de nombreuses plates-formes de code mobile, il est courant de voir le code exécutable signé avec un RSA Digital Signature. Cela permet à une autorité d'accepter un morceau de code qui peut ensuite être distribué. Les tiers et les clients savent que le code est sûr. Les signatures numériques sont utilisées pour aider à prévenir le piratage des jeux vidéo modernes sur console. Ils sont également utilisés pour vérifier qu'une mise à jour logicielle provient du fournisseur et non d'un attaquant.

Cette application php pourrait avoir la clé publique (ou même être distribuée avec cette clé publique). L'administrateur a accès à la fois à la clé publique et à la clé privée, ce qui lui permet de signer un fichier .php. Sur inclure la signature pourrait être vérifiée. Si le fichier php est modifié ou endommagé, la signature ne sera pas acceptée.

En pratique, les applications PHP effectuent de nombreux inclus et donc toute fonction de validation serait un goulot d'étranglement massif. Tout ce qui est sûr, va aussi être très cher. Il serait préférable de vérifier une fois la signature, puis de la transférer dans un répertoire ou une base de données figurant dans la liste blanche. Une autre façon d'améliorer la vitesse est d'utiliser une clé RSA plus petite pour la signature. Par exemple, une clé RSA 512 bits est suffisante pour SSLv3, donc c'est probablement assez bon pour cela.

MD5 est très mauvais. Si vous stockez une liste blanche des hachages de fichier md5 "sûr", cela ouvre la porte pour collision generation. C'est une situation idéale pour utiliser l'attaque de préfixation md5 car les données binaires spécialement conçues au début du fichier n'empêcheront pas le include() d'exécuter le code dans les balises php <?php ?>.

Le CRC est encore pire que md5. Le CRC n'a pas pour but de rendre les collisions de hachage plus difficiles. Le CRC sert uniquement à détecter les dommages causés par un bruit aléatoire. Utilisation de l'attaque similaire à md5 en ajoutant des données a à un message CRC collision can be generated. Sha1 est une fonction de hachage sécurisée et rapide que vous pouvez utiliser. Il y a une attaque par collision similaire qui affecte sha1. Cependant, contrairement à md5, personne n'a généré une collection sha1 et NIST still considers its use to be safe. Bien que sha256 serait un choix plus sûr.

+0

Merci. J'ai réfléchi à l'utilisation de sha256 pour les clés publiques et privées. J'ai déjà mis en place des clés publiques et privées. La clé publique est stockée dans le référentiel public et lors du téléchargement et de l'installation, la clé est vérifiée. Après l'installation, une nouvelle clé privée est générée pour chaque instance, et son intégrité est également vérifiée. SHA1 était à l'origine ce que j'avais en tête mais par défaut md5. Je suppose que c'était naïf de ma part, surtout étant donné le fait que je connaissais le manque récent d'intégrité de md5. Je vais utiliser SHA256 pour les clés, et si je finis par implémenter une somme de contrôle, je vais utiliser SHA1. – Swivel

+0

Merci encore pour la réponse. J'aime l'idée des clés publiques et privées, mais j'étais un peu hésitant parce que si je pouvais utiliser des sommes de contrôle sur les fichiers avant qu'ils soient inclus d'une manière rentable, j'aurais préféré cela plus. Je vais coller avec les algorithmes SHA-hash. Cependant, compte tenu du calibre de mon application, les signatures clés RSA seraient un peu trop! : P – Swivel

0

Je pense que vérifier une somme de contrôle sur chaque chargement est une mauvaise idée car cela ralentira votre application.

Une approche différente serait que vous mettiez quelque chose dans l'interface d'administration de votre application pour installer ou activer le plugin.

Ensuite, vous pouvez vérifier le plug-in une fois quand il est installé et l'ajouter à la liste des plugins activés avant de pouvoir l'utiliser.

Vous pouvez également vérifier tous les plugins une fois par jour pour vérifier s'ils ont été modifiés ... mais il est difficile de le sécuriser car tout ce qui a changé le plugin pendant son installation pourrait également changer vos fonctions de sécurité.