2009-11-13 3 views
0

Tenir compte du problème de sécurité suivant:Regexp pour la construction de chemin comme chroot dans un environnement Linux

J'ai un chemin de base statique (/home/username/) auquel j'ajouter un sous-chemin contrôlé par l'utilisateur (par exemple foo/bar.txt). Le contenu de ce fichier est ensuite lu et présenté à l'utilisateur.

Dans le cas décrit le chemin complet serait: /home/username/foo/bar.txt

maintenant au problème. Je veux contrôler de sorte que le chemin complet soit toujours un sous-répertoire du chemin de base statique. En d'autres termes, je ne veux pas que l'utilisateur fournisse un chemin tel que le chemin de base soit échappé.

Le chemin complet suivant est OK:

/home/username/foo/bar.txt 

Alors que celui-ci est un est clairement pas sûr:

/home/username/foo/../../../etc/passwd 

Pour compliquer encore la bonne solution de chroot: ing sur le chemin de base n'est pas disponible. Pour diverses raisons, la seule solution disponible consiste à utiliser une expression rationnelle pour différencier les chemins sûrs et non sécurisés.

Étant donné le problème décrit ci-dessus, quelle est la regexp appropriée?

S'il vous plaît noter:

  • Le code fonctionne sous Linux. Le séparateur de chemin est donc /.
  • La question est totalement agnostique de la langue.
  • Veuillez ne pas suggérer d'autres moyens de résoudre le problème. Je sais qu'il existe d'autres meilleures façons de le résoudre (comme chroot: ing), mais cette question est limitée à la solution regexp seulement.
+0

Il n'existe pas d'expression régulière agnostique en langage. Quelle implémentation de regex utilisez-vous? –

+0

BipedalShark: PCRE. – knorv

+0

Toutes les expressions regex PCRE ne sont pas identiques. Quel langage de programmation utilisez-vous? –

Répondre

1

Si vous ne voulez pas rejeter purement et simplement, bande juste une « ../ » du chemin, comme celui-ci:

sed -e 's/\..\///g' 

Vous devez savoir qu'il pourrait y avoir des fichiers dans la hiérarchie des répertoires que vous autorisez qui sont liés à des répertoires en dehors de cette hiérarchie. Sans utiliser chroot, je ne pense pas qu'il existe un moyen de garantir la sécurité totale de celui-ci.

1

Vous pouvez simplement rejeter toute entrée d'utilisateur qui correspond /(^|\/)\.\.(\/|$)/

Cela signifie: si elle contient /../ ou commence par ../ ou se termine par /.. ou est ..

+1

Mais vous devez vous assurer que vous préfixez '/ home/username /', sinon '~/something' ou'/var/log' causeront des problèmes. – Leventix

0

Je crois qu'il ne peut se faire en utilisant une seule expression rationnelle. Les expressions rationnelles ne peuvent pas compter quoi que ce soit, alors ici vous devez absolument compter le nombre de ../

Cependant, vous pouvez essayer d'utiliser des regexps récursifs et vérifier l'imbrication récursive de ([[: alpha:]] +/..), comme [[: alpha:]] + (\ R) | ..

Je suis d'accord qu'il est préférable d'interdire ../ du tout

Questions connexes