Importer une bibliothèque depuis le web

a marqué ce sujet comme résolu.

Salut,

Je glandouille cet après-midi. Ne sachant pas quoi coder, je regarde ma longue TODO-list que je remplis chaque jour des idées de projets que j'ai. Et là, je tombe sur "Librairie capable d'importer du code en ligne". Cette idée peut paraître toute bête mais je n'ai jamais vu d'équivalents sur le Net. Pourtant ça me paraît une bonne idée du moins pour les petits script ne cherchant pas les performances (le temps de récupérer le code ça prend quelques millisecondes). Je me suis donc lancé sans trop savoir comment faire, j'ai tenté un truc désespéré mais contre toute attente ça marchait ! Et le tout en 2 minutes et 6 lignes de code Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import urllib.request


def tele_import(url):
    code = urllib.request.urlopen(url).read().decode('utf-8')

    class Module:
        exec(code)

    return Module

module = tele_import('http://www.telecode.esy.es/factorial.py')  # Un mini site créé pour l'occasion
print(module.factorial(5))  # Affiche 120 !

Ça fonctionne!

Je ne vois quelques trucs qui manquent à ce système:

  • Il faudrait pouvoir dire ce qu'on peut importer donc séparer API publique et privée depuis le script en lignes

  • La syntaxe est crado

  • Le code est crado (on peut pas importer de module depuis le scope global dans le script en ligne)

  • On peut pas faire de from <module> import * ni de from <module> import <objet>

Avant que je me lance dans la création d'une vraie librairie plus soignée, je voudrais connaître votre avis. Une si bonne idée (enfin je crois) doit forcément avoir un inconvénient pour ne pas avoir été déjà réalisée…

Merci d'avance,

AZ.

+0 -0

L'exécution de code venant d'un site web est assez rare, ou sinon il fait vraiment y faire confiance.

Il est courant pour exécuter un script venant du web de d'utiliser curl ou wget. Par exemple :

1
curl -sL exemple.net/script.py | python -

On utilise aussi des packages managers comme pip pour installer des bibliothèques.


De plus, ton idée est réalisable en quelques lignes de code donc il y a peu d'avantages à utiliser une bibliothèque qui ne ferait que ça. Je te conseille de chercher si tu peux faire quelques choses de plus important qui pourrait former une bibliothèque, ou prendre une autre idée de ta longue liste !

Concernant le code, je serais parti sur un objet plutôt qu'une fonction :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Bibliotheque:

    def __init__(url):
        # importation du fichier

    def executer():
        exec() # exécution

module = Bibliotheque("URL ")
module.executer()

Voilà :)

+0 -0

Merci de ta réponse :) . L'idée ici c'est de ne pas créer de fichier, les package managers comme pip stockent des fichiers sur l'ordinateur (en ROM). Les commandes comme curl nécessite un OS unixoïde (je ne sais pas si cette commande est disponible par défaut sous OS X). Ici on importe juste le code en RAM, comme si on importait un module normalement avec import.

il y a peu d'avantages à utiliser une bibliothèque qui ne ferait que ça

Bien entendu, je compte créer une librairie qui contrôlerait ce qui appartient à l'API publique et ce qui appartient à l'API privée. Mais il faudrait alors créer un nouveau protocole pour n'envoyer que le nécessaire :o . Je n'ai pas actuellement les connaissances nécessaires pour mener à terme un tel projet, mais avec un peu de documentation ça devrait aller ;)

Concernant le code, je serais parti sur un objet plutôt qu'une fonction

Python fournit dans le module standard types la possibilité de créer un module et un espace de nom comme de véritables modules. Je pense partir là dessus.

Concernant l'import absolu, je compte utiliser le module importlib qui m'a l'air adapté.

Conceptuellement, y'a un truc qui me dérange dans ce projet, tout comme les installs à base de curl : c'est un gouffre niveau sécurité.

Sinon, tout à fait à part :

Les commandes comme curl nécessite un OS unixoïde (je ne sais pas si cette commande est disponible par défaut sous OS X)

OS X est un Unixoïde. C'est pour ça qu'on l'appelle "Mac OS X (la lettre X)" et pas "Mac OS 10 (dix)".

+0 -0

OS X est un Unixoïde

C'est ce que j'entendais, la phrase est mal tournée en effet.

Conceptuellement, y'a un truc qui me dérange dans ce projet […]: c'est un gouffre niveau sécurité.

C'est sûr qu'il faut importer seulement des scripts sur des sites de confiance, mais il existe des sites d'hébergements comme Google Docs, GitHub, ou Mega qui existeront toujours. A part ça, je ne vois pas très bien quels soucis de sécurité cela peut engendrer, je n'ai aucune connaissance en sécurité informatique :( . Aurais-tu d'autres exemples de failles potentielles ? De toute façon, certaines utilisations de ce projet n'ont pas besoin d'être safe. Par exemple, si l'on veut tester une librairie avant de la télécharger.

Sinon j'ai réussi à implémenter l'import de package et de modules grâce à l'aide de Kje (quasiment tout le code vient du lien qu'il a codé, j'ai juste réécrit le script à ma façon, mais c'est fondamentalement le même code).

+0 -0

C'est sûr qu'il faut importer seulement des scripts sur des sites de confiance, mais il existe des sites d'hébergements comme Google Docs, GitHub, ou Mega qui existeront toujours.

Et qui, par définition, ne sont pas des sites de confiance. En fait il y a plusieurs trucs qui limitent l'intérêt d'importer des modules distants de cette façon :

  • Tel quel ton soft utilise http tout nu. Ça veut dire que si quelqu'un réussit à empoisonner ton DNS ou le cache ARP de ton routeur, il peut te faire exécuter ce qu'il veut, avec tes droits d'utilisateur à toi, sans même que tu puisses vérifier la source de ce que tu exécutes. En particulier il sait que ton module a accès au net, donc il pourrait parfaitement s'envoyer, disons… tous tes cookies et les mots de passe enregistrés dans ton navigateur web, par exemple ?

  • C'est d'autant plus flagrant sur les bibliothèques javascript pour lesquelles la hype est de les installer via sudo curl [URL] | sh : non seulement le site n'est à aucun moment authentifié, mais en plus le script (dont on ignore totalement le contenu au moment de taper la commande) est exécuté avec les droits root !

  • Des bibliothèques qui tiennent sur un module Python seul, y'en a vraiment très peu. Sans parler de tous ceux qui sont censés être compilés à l'installation (extensions C API…).

  • Aujourd'hui, même sur un système qui est censé être "embarqué" comme un smartphone, quelques Mo de disque pour créer des fichiers temporaires ne coûtent rien. D'ailleurs, si tu veux que ton module soit confort à utiliser ça peut valoir largement la peine de faire une mise en cache dans un .pyc pour que ça ne mette pas la vie à charger.

En somme, c'est un projet cool pour bien comprendre le système d'imports et créer un hook pour s'amuser, mais dans la réalité c'est clairement pas un truc qu'on peut utiliser sainement.

+0 -0

Tel quel ton soft utilise http tout nu. Ça veut dire que si quelqu'un réussit à empoisonner ton DNS ou le cache ARP de ton routeur, il peut te faire exécuter ce qu'il veut, avec tes droits d'utilisateur à toi, sans même que tu puisses vérifier la source de ce que tu exécutes

On pourrait donc créer un protocole pour le projet (comme HTTP, ou SMTP, protocole de la couche 7 si j'en crois Wikipedia). Cette solution résout en plus les problèmes d'open/closed principle si on veut avoir des données privées sur notre API. Sur ce protocole on aurait un site d'hébergement qui donnerait la possibilité aux personnes de créer/modifier des script avec l'accord de ses utilisateurs. Si l'un des utilisateurs utilise un script, cela notifie l'auteur. Bref, il existe plein de solution pour pallier à ces problèmes

C'est d'autant plus flagrant sur les bibliothèques javascript pour lesquelles la hype est de les installer via sudo curl [URL] | sh : non seulement le site n'est à aucun moment authentifié, mais en plus le script (dont on ignore totalement le contenu au moment de taper la commande) est exécuté avec les droits root !

La création d'un site d'hébergement permettrai de nous signaler si l'une des bibliothèques qu'on utilise est modifiée, ou même faire en sorte qu'il est impossible de modifier un script uploadé sans l'accord des utilisateurs.

Des bibliothèques qui tiennent sur un module Python seul, y'en a vraiment très peu. Sans parler de tous ceux qui sont censés être compilés à l'installation (extensions C API…).

Je suppose qu'on peut régler ce problème avec une petite fonction qui compile automatiquement selon les options d'import du script précisées par l'auteur.

Aujourd'hui, même sur un système qui est censé être "embarqué" comme un smartphone, quelques Mo de disque pour créer des fichiers temporaires ne coûtent rien. D'ailleurs, si tu veux que ton module soit confort à utiliser ça peut valoir largement la peine de faire une mise en cache dans un .pyc pour que ça ne mette pas la vie à charger.

Bonne idée, je m'y met :)

Le but de ce projet est d'offrir aux personnes la possibilité d'importer des scripts à la volée sans voir à les télécharger. Après si ça mène à des failles je suis pas responsable. Un utilisateur peut tout à fait héberger des fichiers sur son site, ce qui fait qu'il sait parfaitement ce qu'il importe. Il est clair que ce projet ne pourra jamais être "utilisé sainement", et même toutes ces solutions combinées laisseront des failles incorrigibles. En tout cas comme tu l'as dit c'est plutôt instructif, donc je vais continuer ce projet. Si des personnes en auront l'utilité, tant mieux, sinon tant pis, j'aurai quand même appris plein de trucs.

On pourrait donc créer un protocole pour le projet (comme HTTP, ou SMTP, protocole de la couche 7 si j'en crois Wikipedia). Cette solution résout en plus les problèmes d'open/closed principle si on veut avoir des données privées sur notre API. Sur ce protocole on aurait un site d'hébergement qui donnerait la possibilité aux personnes de créer/modifier des script avec l'accord de ses utilisateurs. Si l'un des utilisateurs utilise un script, cela notifie l'auteur. Bref, il existe plein de solution pour pallier à ces problèmes

Aucune de ces solutions n'attaque le problème : à aucun moment tu ne peux avoir la certitude que quelqu'un n'écoute pas l'échange (un protocole, ça se reverse, d'autant plus s'il est en mode texte comme les deux protos applicatifs que tu cites — PS : à partir de la couche 4, ce sont des protos applicatifs. La distinction est tellement floue que plus personne ne s'embête à la faire aujourd'hui), et que le dépôt auquel tu te connectes est le bon (que ton appel n'a pas été rerouté).

Un début de solution serait de forcer l'utilisation de SSL/TLS pour certifier que le dépôt est bien celui qu'il prétend être en plus de chiffrer les données. Ou encore, comme le font par exemple les dépôts d'Ubuntu, en utilisant un chiffrement asymétrique style GPG.

Je suppose qu'on peut régler ce problème avec une petite fonction qui compile automatiquement selon les options d'import du script précisées par l'auteur.

Non, examine mieux les problèmes que ça pose :

  • la bibliothèque que tu importes est composée de plusieurs modules : tu charges le premier, mais tu n'en as aucun de tous les autres, et rien dans ces dépendances n'indique où elles sont supposées se trouver.

  • le modules se basant sur une extension C sont des bindings pour du code natif : en admettant que la bibliothèque native soit cross-compilée à distance pour ton OS et ton architecture (ça commence à faire cher de l'import), qu'est-ce que tu fais du binaire que tu récupères ?

Le but de ce projet est d'offrir aux personnes la possibilité d'importer des scripts à la volée sans voir à les télécharger. Après si ça mène à des failles je suis pas responsable.

Légalement ? Peut-être pas, quoique ça se discute. Mais le problème n'est pas que ça mène à des failles : c'est que c'en soit une dès la conception. Moralement, ça me ferait plutôt mal de me rendre compte que j'ai concédé autant d'efforts dans ce qui s'avèrerait au final être une bonne grosse backdoor.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte