Python - creating a scripting system

I am creating a wxpython application that I will compile with another freezing utility to create an executable file for several platforms.

the program will be a graphical editor for the tile-based game engine

in this application I want to provide a scripting system so that advanced users can change the behavior of the program, for example, change project data, export the project to another format, etc.

I want the system to work like this.

the user will put the python script that they want to run in the style text box, and then click the button to execute the script.

I am still happy with this; it's all very simple. get the script from the text field as a string that compiles it for the cod object with the built-in compile () function, then run the script with the status exec

script = textbox.text #bla bla store the string code = compile(script, "script", "exec") #make the code object eval(code, globals()) 

The fact is that I want this function to not cause errors or errors, say, if there is an import statement in the script. will this cause any problems given that the code was compiled using something like py2exe or py2app?
how can I make sure that the user cannot break the critical part of the program, for example, modify part of the graphical interface, thereby allowing them to change project data (data is stored in global properties in its own module)? I think that would mean modifying the globals dict, which is passed to the eval function.
How can I make sure that this eval cannot cause the program to freeze due to a long or infinite loop? How can I make sure that an error that occurs inside the user code cannot lead to the failure of the entire application?

basically, how can I avoid all those problems that may arise when a user can run his own code?

EDIT: Regarding the responses received

I donโ€™t feel that any of the answers so far really answered my questions yes, they were partially answered, but not completely. I know well that it is impossible to completely stop unsafe code. people are too smart for one person (or even abundance) to think of all the ways to circumvent the security system and prevent them.

I donโ€™t really care if they do it. I am more concerned about some unintentional violation of what they did not know. if someone really wanted them to be able to tear the application to shreds using script functions, but I didn't care. this will be their instance, and the whole problem that they create will disappear when they restart the application, if they have not corrupted the files on HD. I want to prevent problems that occur when the user doses something stupid.
such as IOError, SystaxErrors, InfiniteLoopErrors, etc.

Now answered the part about the sphere. Now I understand how to determine what functions and global capabilities can be obtained from the eval function, but is there any way to make sure that their code can be stopped if it takes too long?
maybe a green thread system? (green because it will be eval so that users worry about thread safety)

also , if the user uses the import module statement to load a module from even the default library, which is not used in the rest of the class. can this cause problems with the application being frozen by Py2exe, Py2app or Freeze? what if they call the modal side of the standard library? would it be enough for the modal to be present in the same directory as the frozen executable?

I would like to get these answers without creating a new question, but I will if I have to.

+7
python security scripting eval wxpython
source share
4 answers

Easy answer: do not.

You can ban certain keywords ( import ) and operations, as well as access certain data structures, but in the end you give your power users a lot of energy. Since this is for a rich client that runs on a user computer, an attacker can crash or even destroy an entire application if they really like it. But it is their case to crash. Document it well and tell people what not to touch.

However, I did such things for web applications that do user input, and yes, call eval like this:

 eval(code, {"__builtins__":None}, {safe_functions}) 

where safe_functions is a dictionary containing {"name": func} types of pairs of functions that you want your users to have access to. If you have any important data structure that you put, your users will never want to deflate, just release it from globals before transferring them.

By the way, Guido addressed this issue on his blog some time ago. I'll see if I can find him.

Edit: found.

+5
source share

Short answer: No

  • Does eval use bad practice in Python?

Other related posts:

  • Python 'eval' security for list deserialization

It is not easy to create a protective net. Details are too many and smart hacks:

  • Python: make eval safe

According to your design goals:

It seems you are trying to create an extensible system, giving the user the ability to change a lot of behavior and logic.

The easiest option is to ask them to write a script that you can evaluate (eval) during program startup.

Be that as it may, good design describes, is flexible, and provides a scripting mechanism through various design schemes, from configuration, from plug-ins to scripting capabilities, etc. The apis script, if well defined, can provide more meaningful extensibility. It is also safer.

+1
source share

I would suggest providing some kind of API plugin and letting users provide plugins as text files. You can then import them as modules into your own namespace, catching syntax errors in the process and calling various functions defined in the plug-in module, again checking for errors. You can provide an API module that defines functions / classes from your program that the plugin module has access to. This gives you the freedom to make changes to the architecture of your application without disassembling plugins, as you can simply adapt the API module to provide functionality in the same way.

0
source share

If you have the option to switch to Tkinter, you can use the sophisticated tcl interpreter to process your script. In this case, you can probably do this with the wxpython application if you don't run the tk event loop; just use the tcl interpreter without creating any windows.

Since the tcl interpreter is a separate thing, it is almost impossible to collapse the python interpreter if you are careful about what commands you issue in tcl. In addition, tcl simplifies the creation of DSL.

Python is the only scripting language with a built-in scripting mechanism :-).

0
source share

All Articles