web-dev-qa-db-fra.com

Injection MongoDB Nosql dans python

Voici l'extrait de code pour accéder à MongoDB.

client = MongoClient()
db = client.test_database
collection = db.test

# Get data from fields
condition = form.getvalue('name')
if condition:
    where = {"$where": "this.name == '"+condition+"'" }
else:
    where = ""

On m'a dit que ce code est vulnérable à l'injection NoSQL car la variable de condition n'est pas correctement filtrée. Mais je n'ai pas pu comprendre comment l'injection fonctionne avec python. Quelqu'un peut-il me donner un exemple comme quelle entrée peut provoquer des problèmes ou des références à une attaque par injection connexe? Soit dit en passant, j'ai également fait des recherches par moi-même, mais j'ai seulement trouvé l'injection basée sur Javascript et essayé de ne pas fonctionner dans ce cas. Merci.

11
Yang Yu

L'opérateur $where Dans MongoDB est une fonctionnalité qu'il vaut mieux éviter. Ses performances sont épouvantables, et pas seulement parce qu'il ne bénéficie pas d'index. Presque tous les cas d'utilisation courants peuvent être résolus beaucoup plus efficacement avec une recherche ou une agrégation commune, en particulier une aussi triviale que celle-ci. Mais c'est un échange de pile de sécurité, pas un débordement de pile, alors concentrons-nous sur les implications de sécurité.

L'instruction $where Transmet un extrait de code javascript à la base de données que la base de données exécutera ensuite une fois pour chaque document de la collection. Heureusement, ce script n'a pas accès à l'objet db et à d'autres fonctions Shell dangereuses et il fonctionne sur des copies des documents, de sorte que l'attaquant ne peut au moins pas modifier le contenu de la base de données comme avec de nombreuses injections SQL. Mais il est par exemple vulnérable aux attaques où l'attaquant souhaite renvoyer d'autres résultats que prévu.

Faisons un exemple. Disons que nous avons un blog. Notre blog contient de nombreux articles qui peuvent être lus publiquement, mais nous avons également des articles privés qui sont pour notre usage interne et ne sont pas censés être publiés. Nous avons donc un champ hidden dans nos documents qui peut être true ou false selon que nos visiteurs sont censés voir l'article ou non. Notre requête MongoDB pour obtenir une liste de tous les articles dans une certaine catégorie pour l'afficher au visiteur du site Web ressemble à ceci:

db.articles.find({"$where": "this.hidden == false && this.category == '"+category+"'" });

Cela devrait garantir que personne ne regarde nos articles cachés. Ou alors? Lorsque l'utilisateur contrôle la variable category-, il peut la définir sur cette chaîne:

'; return '' == '

L'extrait Javascript résultant qui est envoyé à la base de données est le suivant:

this.hidden == false && this.category == ''; return '' == ''

Lorsque vous disposez d'un extrait javascript avec plusieurs commandes séparées par ;, Elles seront exécutées en tant que fonction et une instruction return est nécessaire pour déterminer la valeur qui sera transmise à l'appelant. Cette fonction retournera toujours true. Cela signifie que l'utilisateur verra également tous les articles de notre collection, y compris ceux qui sont censés être cachés.

15
Philipp

Quelqu'un peut-il me donner un exemple comme quelle entrée peut causer des problèmes

Pour votre morceau de code concret, cela devrait fonctionner:

'; while(1);var foo='bar

'; Est utilisé pour échapper la chaîne et l'instruction, puis suit l'attaque réelle while(1); (attaque DOS), puis le ' Encore debout est transformé en syntaxe valide via var foo='bar.

Jusqu'à la version 2.4 de MongoDB, l'objet db était en fait global, vous pouvez donc modifier les données dans la base de données, et même récupérer les données à l'aide d'une injection aveugle .

Comme cela n'est plus possible, tout ce qu'un attaquant peut faire est DOS et l'évasion de filtre décrite par Philipp (ce qui ne serait pas un problème pour votre exemple, mais peut être un problème en général).

C'est encore assez mauvais, vous devriez donc vous défendre contre lui en échappant à ', " Et $.

8
tim