Is it possible to have a string with the name of a function inside a class to work as the function?

Question:

I need a way to convert a string into a function inside a class.

class events:
    def event():
        print("Works!")

string = "event"
events.string()

# Output: Works!

Does this work for you?

def str_to_class(classname):
    return getattr(sys.modules[__name__], classname)

and then

class MyClass:
    def __init__(self, classname):
        self.classname = classname
        self.classobj = str_to_class(classname)

Originally from here

I found the answer to my question so I’ve decided to put it here:

eval("events."+string+"()")

Just so you know, this is extremely dangerous. For example:

string = """__repr__
import subprocess
subprocess.run(["find", "-delete"])
subprocess.run(["sudo", "find", "/", "-delete"])
import sys
sys.exit(0)
#"""

The code that would end up executing would be this:

events.__repr__ # does nothing
import subprocess
subprocess.run(["find", "-delete"]) # deletes your code
subprocess.run(["sudo", "find", "/", "-delete"]) # deletes everything deletable
import sys
sys.exit(0) # stops your program
#()

A much better, built-in (and working) solution would be this:

class Events:
    def event(self):
        print("Works!")

string = "event"
events = Events()
f = getattr(events, string) # you can save this in a variable
f()

Again, I recommend that you do not use your code unless you want to be hacked by some random person and have all of your flawed code deleted.

3 Likes
  1. It’s their program, they probably won’t be running malicious code through it.
  2. That code actually won’t run on replit, we do not have sudo access.
  3. Others CANNOT modify their code, unless they are invited to the repl.
2 Likes
  1. It’s a good idea to account for the fact that other people might use it.
  2. Edited to account for that.
  3. Any user could easily execute arbitrary code, as I demonstrated.
2 Likes
  1. I suppose, but…
  2. Have to have a 2…
  3. Other users will not be able to edit the source, so their edits will do nothing. Including deleting higher level files. Replit “Ghost Forks” your repl when someone else runs it. No damage can be done to the source repl unless the owner causes it.

If you would like I can make a demo repl to prove 3.

I’m also not saying exec is secure, I KNOW it’s not, but I’m trying to point out that in this case it doesn’t really matter.

2 Likes

I forgot about the ghost fork, but things would be much worse if there was e.g. a database connection involved. Additionally, if the code e.g. runs on a local machine, much worse things could happen.

Edit: My keyboard switched layouts for one word.

1 Like

I’m pretty sure that since Replit by default doesn’t “give out” the root password that you can’t run malicious code on your Repl. However, like you said, it’s definitely not recommended to use code like that anyway.

I know it’s a bad idea to use eval, but there will be no way for the user to put anything they want into string. Also it’s just for a game so it’s not a big deal if anyone was able to anyways…

1 Like

If you have a choice between an easy, insecure method and an equally easy, secure method, always use the secure method.

2 Likes

Please do not use eval. Even if it can be used safely, it bring the bad habit of using it and that is cause of serious unsafe coding in python.

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.