Incidences sur la security de l'utilisation de données non analysées dans l'évaluation arithmétique de Shell

Dans un commentaire à une question récente , Stéphane Chazelas mentionne qu'il y a des implications sécuritaires pour l'arithmétique des doubles parenthèses comme:

x=$((1-$x)) 

sur la plupart des coquilles.

Mes compétences Google semblent être rouillées et je ne trouve rien. Quelles sont les implications de security de l'arithmétique des doubles parenthèses?

Le problème est dans les cas où le contenu de $x n'a pas été assaini et contient des données qui pourraient potentiellement être sous le contrôle d'un attaquant dans les cas où le code shell pourrait finir par être utilisé dans un context d'escalade de privilèges (par exemple un script invoqué par une application setuid, un script sudoers ou utilisé pour traiter directement ou indirectement des données hors réseau (CGI, hook DHCP …).

Si:

 x='PATH=2' 

Alors:

 x=$((1-$x)) 

a l'effet secondaire de mettre PATH à 2 (un path relatif qui pourrait très bien être sous le contrôle de l'attaquant). Vous pouvez replace PATH par LD_LIBRARY_PATH ou IFS … Il en est de même avec x=$((1-x)) dans bash, zsh ou ksh (qui n'acceptent que des constantes numériques dans les variables).

Dans bash , zsh et ksh (pas de dash ou de yash ), si x est:

 x='a[0$(id>&2)]' 

Ensuite, l'expansion de $((1-$x)) ou $((1-x)) provoque l'exécution de cette command id .

Notez que:

 x=$((1-$x)) 

ne fonctionnera pas correctement pour les valeurs négatives de $x dans certains shells qui implémentent l'opérateur (optionnel comme POSIX) -- (décrémenter) (comme avec x=-1 , cela signifie requestr au shell d'évaluer l'arithmétique 1--1 expression). "$((1-x))" n'a pas le problème car x est développé dans le cadre de l'évaluation arithmétique (pas avant).

En résumé, il ne faut pas utiliser des données externes non initialisées ou non-assainies dans des expressions arithmétiques dans des shells (notez que l'évaluation arithmétique peut être faite par $((...)) mais en fonction du shell dans let , [ / test , declare/typeset , return , break , continue , exit , printf , print constructions et les constructions ((..)) et [[...]] pour n'en nommer que quelques-uns.

Plus de lecture à: