Sécuriser l’accès aux fichiers d’un répertoire identifié par une variable d’environnement?

StackOverflow https://stackoverflow.com/questions/196244

Question

Quelqu'un peut-il indiquer un code traitant de la sécurité de l'accès aux fichiers via un chemin spécifié (en partie) par une variable d'environnement, en particulier pour Unix et ses variantes, mais les solutions Windows présentent également un intérêt?

C’est une très longue question. Je ne sais pas si cela convient au paradigme SO.

Considérez ce scénario:

Arrière-plan:

  • Le logiciel PQR peut être installé à un emplacement choisi par les utilisateurs.
  • La variable d'environnement $ PQRHOME est utilisée pour identifier le répertoire d'installation.
  • Par défaut, tous les programmes et fichiers sous $ PQRHOME appartiennent à un groupe spécial, pqrgrp.
  • De même, tous les programmes et fichiers sous $ PQRHOME appartiennent soit à un utilisateur spécial, pqrusr, soit à l'utilisateur root (et il s'agit de programmes racine SUID).
  • Quelques programmes sont SUID pqrusr; SGID pqrgrp est quelques autres programmes.
  • La plupart des répertoires appartiennent à pqrusr et appartiennent à pqrgrp; certains peuvent appartenir à d'autres groupes et les membres de ces groupes acquièrent des privilèges supplémentaires avec le logiciel.
  • De nombreux exécutables privilégiés doivent être exécutés par des personnes non membres de pqrgrp; les programmes doivent valider que l'utilisateur est autorisé à l'exécuter par des règles mystérieuses qui ne concernent pas directement cette question.
  • Après le démarrage, certains programmes privilégiés doivent conserver leurs privilèges élevés, car ce sont des démons de longue durée qui peuvent agir au nom de nombreux utilisateurs au cours de leur vie.
  • Les programmes ne sont pas autorisés à changer de répertoire en $ PQRHOME pour diverses raisons obscures.

Vérification en cours:

  • Les programmes vérifient actuellement que $ PQRHOME et ses répertoires de clés sont "sûrs" (détenus par pqrusr, appartiennent à pqrgrp, n'ont pas d'accès public en écriture).
  • Ensuite, les programmes accèdent aux fichiers sous $ PQRHOME via la valeur complète de la variable d'environnement.
  • En particulier, les G11N et L10N sont obtenus en accédant à des fichiers situés dans des répertoires "sûrs" et en lisant des chaînes de format pour printf (), etc. à partir des fichiers de ces répertoires, en utilisant le chemin complet dérivé de $ PQRHOME plus un sous-répertoire connu. -structure (par exemple, $ PQRHOME / g11n / en_us / messages.l10n).

Supposons que la valeur "tel qu'installé" de $ PQRHOME est / opt / pqr.

Attaque connue:

  • L'attaquant définit PQRHOME = / home / attaquant / pqr.
  • Il s'agit en fait d'un lien symbolique vers / opt / pqr. Ainsi, lorsqu'un des programmes PQR, appelez-le pqr-victime, vérifie le répertoire, il dispose des autorisations appropriées.
  • Immédiatement après la fin de la vérification de sécurité, l'attaquant modifie le lien symbolique de sorte qu'il pointe sur / home / attaquant / bogus-pqr, qui est clairement sous le contrôle de l'attaquant.
  • Il se passe des choses terribles lorsque la victime pqr accède maintenant à un fichier situé dans le répertoire supposé sûr.

Etant donné que PQR se comporte actuellement comme il a été décrit et qu’il s’agit d’un package volumineux (plusieurs millions de lignes de code, élaboré depuis plus de dix ans pour répondre à diverses normes de codage, qui ont de toute façon été ignorées), quelles techniques utiliseriez-vous pour résoudre le problème?

Les options connues incluent:

  1. Modifiez tous les appels de mise en forme pour utiliser une fonction qui compare les arguments réels aux chaînes de formatage, avec un argument supplémentaire indiquant les types réels transmis à la fonction. (Ceci est délicat, et potentiellement sujet aux erreurs en raison du grand nombre d'opérations de format à modifier - mais si la fonction de vérification est elle-même saine, fonctionne bien.)
  2. Établissez le chemin direct vers PQRHOME et validez-le pour la sécurité (détails ci-dessous), refusant de démarrer s'il n'est pas sécurisé, puis utilisant le chemin direct et non la valeur de $ PQRHOME (s'ils diffèrent). (Cela nécessite que toutes les opérations de fichier utilisant $ PQRHOME n'utilisent pas la valeur de getenv () mais le chemin mappé. Par exemple, cela nécessiterait
Était-ce utile?

La solution

L'option 2 fonctionne si vous écrivez une nouvelle valeur pour $ PQRHOME après avoir résolu son chemin réel et vérifié sa sécurité. De cette façon, très peu de votre code devra être modifié par la suite.

En ce qui concerne le maintien des privilèges setuid, il serait utile d’effectuer une séparation des privilèges de sorte que toutes les opérations impliquant une entrée de l’utilisateur réel s’exécutent sous le véritable uid. Le processus privilégié et le processus réel se parlent ensuite à l'aide d'un socketpair ou quelque chose de similaire.

Autres conseils

Eh bien, cela semble paranoïaque, mais cela dépend ou non du ou des systèmes sur lesquels votre application est exécutée et des dommages qu'un attaquant peut causer.

Donc, si votre base d'utilisateurs est probablement hostile et si les dégâts sont peut-être très importants, j'opterais pour l'option 4, mais modifiée comme suit pour supprimer ses inconvénients.

Permettez-moi de citer deux choses pertinentes:

1)

  

Les programmes vérifient actuellement que $ PQRHOME et les répertoires de clés   sous lui sont «sûrs» (appartenant à pqrusr,   appartenir à pqrgrp, ne pas avoir public   accès en écriture).

2)

  

Ensuite, les programmes accèdent aux fichiers inférieurs à $ PQRHOME via le répertoire complet.   valeur de la variable d'environnement.

Vous n'avez pas besoin de coder en dur le chemin complet, vous pouvez coder en dur uniquement le chemin relatif du "programme". vous avez mentionné en 1) le chemin mentionné en 2) où se trouvent les fichiers.

Problème à contrôler:

a) vous devez être sûr qu'il n'y a rien "accessible aux attaquants" (par exemple, en termes de liens symboliques) entre le chemin de l’exécutable et le chemin des fichiers

b) vous devez être sûr que l'exécutable vérifie son propre chemin de manière fiable, mais cela ne devrait pas être un problème dans tous les Unix'es que je connais (mais je ne les connais pas tous et je ne le fais pas ne connais pas du tout les fenêtres).

MODIFIÉ après le 3ème commentaire:

Si votre système d'exploitation supporte / proc, le meilleur moyen de résoudre b) est syslink / proc / $ {pid} / exe.

EDITE après avoir dormi dessus:

L’installation est-elle un "coffre-fort"? processus? Si tel est le cas, vous pouvez créer (au moment de l'installation) un script wrapper. Ce script doit être exécutable mais non accessible en écriture (et éventuellement non lisible). Il définirait la variable $ PQRHOME env sur le paramètre "safe". puis appelez votre programme actuel (il pourrait éventuellement faire d’autres choses utiles). Dans UNIX, les vars env d’un processus en cours ne pouvant pas être modifiés par autre chose que le processus en cours, vous êtes en sécurité (bien sûr, les vars env peuvent être modifiés par le parent avant le processus commence). Je ne sais pas si cette approche fonctionne sous Windows, cependant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top