8
votes

Comment lire en toute sécurité le code de clojure non approuvé (pas seulement quelques données sérialisées)?

(def r (clojure.edn/read-string evil-code))
RuntimeException Map literal must contain an even number of forms  clojure.lang.Util.runtimeException (Util.java:219)

3 commentaires

Peut-être une overcilleuse, mais jetez un coup d'œil à Clojail


Utilisez lecture-chaîne avec * lecture-eval * définie sur false


Doc affirme que même avec [* lecture-eval * faux], il n'est toujours pas conçu pour être en sécurité. Et comment analyser le code qui repose sur # = et lire des macros? Je m'attends à ce qu'ils apparaissent d'une manière ou d'une autre dans des structures de données sans être exécutées.


3 Réponses :


2
votes

Selon le Documentation en cours Vous devez jamais em> utiliser Lire CODE> NOR READ-String CODE> Pour lire à partir de sources de données non approuvées.

WARNING: You SHOULD NOT use clojure.core/read or
clojure.core/read-string to read data from untrusted sources.  They
were designed only for reading Clojure code and data from trusted
sources (e.g. files that you know you wrote yourself, and no one
else has permission to modify them).


1 commentaires

clojure.edn / lue est déjà mentionné dans la question. Il lit bien les structures de données sérialisées comme le code de la clojure, mais il ne lit pas le code de clojure arbitraire. Comment construire en toute sécurité AST à partir d'un code de clojure (de préférence pour pouvoir le générer dans du texte)?



4
votes

Tout d'abord, vous ne devez jamais lire le code de clojure directement à partir de sources de données non soignées. Vous devez utiliser EDN ou un autre format de sérialisation à la place.

Cela étant dit depuis la clojure 1.5 Il existe une sorte de moyen sûr de lire des chaînes sans les évaluer. Vous devriez lier le lecture-eval Var à False avant d'utiliser Lecture-String. Dans le clojure 1.4 et plus tôt, cela a suscité des effets secondaires causés par des constructeurs Java invoqués. Ces problèmes ont depuis été fixé.

Voici quelques exemples de code: xxx

concernant le lecteur Macro's < p> La macro de l'expédition (#) et les littéraux marqués sont invoqués à la date de lecture. Il n'y a pas de représentation pour eux dans des données de clojure depuis à ce moment-là, ces constructions ont tous été traitées. Autant que je sache, il n'y a pas de place de manière à générer une syntaxe d'un code de clojure.

Vous devrez utiliser un analyseur externe pour conserver ces informations. Soit vous lancez votre propre analyseur personnalisé ou vous pouvez utiliser un générateur d'analyseur comme InstaParse et AntlR. Une grammaire complète de clojure pour l'une ou l'autre de ces bibliothèques pourrait être difficile à trouver, mais vous pouvez étendre l'une des grammaires EDN pour inclure les formes de clojure supplémentaires. Un rapide Google a révélé une grammaire à antlr pour la syntaxe de clojure , Vous pouvez modifier cela pour supporter les constructions qui manquent si nécessaire.

Il y a aussi SJAKET une bibliothèque faite pour les outils de clojure nécessitant des informations sur le code source lui-même. Cela semble être un bon ajustement pour ce que vous essayez de faire mais je n'ai aucune expérience avec elle personnellement. À en juger par les tests, il dispose de la prise en charge de la macro du lecteur dans son analyseur.


1 commentaires

Comment modifier de manière programmable le code de clojure, laissant # = s comme elle-même (ne pas exécuter, mais n'ignore pas). Ne pas désérialiser les données de clojure, mais lire le programme de clojure et le présenter comme arbre à travailler. Lecture avec edn / lecture-chaîne est comme essayer de lire le code JavaScript avec JSON Parser ...