• Votre panier est vide.

  • COMPTE

En quoi consiste la vulnérabilité de input()

En quoi consiste la vulnérabilité de input()

Si jamais quelqu’un vous demande de récupérer une chaine de caractère écrit par l’utilisateur en python, sans hésiter vous utiliserez les fonctions suivantes :

Version de python Type qui doit être retourné Fonction utilisée
Python2 string (ou str) raw_input()
entier (ou int) input()
Python3 string (ou str) input()

On remarque que si la commande input existe en python peu importe la version. La différence est le type qui est retourné. On remarque qu’ainsi, en python 3, on ne possède qu’une fonction et aucune fonction ne renvoi de int.

Nous verrons plus tard que ce n’est pas un problème.

 

En quoi consiste la vulnérabilité

Nous allons maintenant explorer le fonctionnement de la fonction input de Python 2 (tout ce qui va suivre sera en python 2, les seules fois où il sera question de python3 cela sera indiqué).

Pour commencer un help(input) s’impose :

>>> help(input)

Ce qui nous retournera :

Help on built-in function input in module __builtin__:

input(...)
    input([prompt]) -> value
    Equivalent to eval(raw_input(prompt)).

On apprend ici que input est une fonction qui est dans le module __builtin__ et qu’elle est l’équivalent de « eval(raw_input(prompt)) ».

Spoiler : il y a un problème dans cette fonction.

 

Faisons une analyse de « eval(raw_input(prompt)) » :

On appelle la fonction raw_input (qui renvoi une string je le rappelle) et on lui donne en paramètre la variable prompt. Ce prompt n’est autre que le seul argument que peut prendre input et qu’il donne ensuite à raw_input. Ce paramètre est une chaine de caractère qui sera affichée sans sauts de lignes.

Ainsi, raw_input( « entrez quelque chose :  » ) va afficher :

Entrez quelque chose :

Il faut avouer que c’est tout de même bien plus propre et beaucoup plus clair qu’une ligne vide où on l’on doit rentrer des caractères.

Notez qu’on peut obtenir le même résultat en faisant un :

print "entrez quelque chose : ", 
answer = raw_input()

Après avoir récupérer l’entrée de l’utilisateur, raw_input l’envoie comme paramètre à eval. C’est ici que commencent nos problèmes :

>>> eval( "5+2" )
7

>>> eval( "help(eval)" )
Help on built-in function eval in module __builtin__:

eval(...)
    eval(source[, globals[, locals]]) ->; value
    
    Evaluate the source in the context of globals and locals.
    The source may be a string representing a Python expression
    or a code object as returned by compile().
    The globals must be a dictionary and locals can be any mapping,
    defaulting to the current globals and locals.
    If only globals is given, locals defaults to it.

Vous ne rêvez pas. On peut faire exécuter des commandes python avec eval (Si vous ne comprenez pas. Imaginez simplement que vous retiriez les guillemets au paramètre donné à eval et que vous l’écriviez dans le shell python comme si vous exécutiez une commande.) !

Attention cependant, il faut nuancer : on ne peut pas tout faire non plus (contrairement à la fonction exec qui est vraiment faite pour exécuter des commandes). Ainsi, on ne peut pas créer de classes, de fonctions…  eval doit retourner quelque chose (peu importe le type). Tout code qui ne renvoi rien à eval provoquera une erreur.

C’est pour cela qu’on ne peut pas utiliser print, ni définir des classes, car sinon une exception sera levée et le code plantera si cette dernière n’a pas été gérée par un try.

TOUT VOIR Ajouter une remarque
VOUS
Ajouter votre commentaire
Culte du code | 2015-2020  (Vecteurs par Freepik, Parallax par fullvector)