Letting user input to be executed on your server is a very huge security risk
The user could for example write code, that tries to delete all files, that it finds on the hard disk or to remove all entries from all databases, that the django server can access.
Short! This is a dangerous idea, except if you trust everybody who can access the server. Though normally you shouldn't even trust yourself ;-)
Technically however this is very simple.
You can can use a form, where you fill in the text, django parses the form data as any other form field.
If the string would be for example
import os, glob
for fname in glob.glob("/www/data/uploads/*"):
os.unlink(fname)
and the variable containing that string would be named code_to_execute
then you can just call exec(code_to_execute) in your django view to allow your user to delete all files, that were uploaded to "/www/data/uploads".
Perhaps there is a better way a more secure solution to implement what you need.
What kind of functionality should the users be able to implement?
To make things a little more difficult you could do something a little different.
You have have a , separated list of keys that should be removed from the dict and you could have a pair of key name and expressions to calculate the key name. The expression would be calculated with eval and not with exec
I would not say, that this gives you 100% security, but a little more secure than allowing exec
as you're only allowed to implement expressions and as you can limit the available symbols
import os
from math import pi
user_data = [
{"name": "item1", "location": "place1", "shape": "rectangle", "width": 5, "height": 2},
{"name": "item2", "location": "place2", "shape": "circle", "radius": 3},
{"name": "item3", "location": "place1", "shape": "square", "width": 5},
{"name": "item4", "location": "place2", "shape": "rectangle", "width": 3, "height": 2},
{"name": "item5", "location": "place1", "shape": "circle", "radius": 2},
{"name": "item6", "location": "place3", "shape": "triangle", "width": 2, "height": 5},
]
### That's what you would get from a web form
### formula to calculate a dict, that will be used to update an entry
userinput = """
{"area": item["radius"] ** 2 * pi,
"comment": "I love circles",
}
if item["shape"] == "circle"
else (
{"area": item["width"] ** 2,
"comment": "squares aren't too bad"}
if item["shape"] == "square"
else (
{"area": item["width"] * item["height"],
"comment": "I don't really like rectangles"}
if item["shape"] == "rectangle" else
{"area": "?",
"comment": "never heard of a %s" % item["shape"]}
))
"""
userinput = userinput.replace("\n"," ")
for item in user_data:
print(" ", item)
user_rslt = eval(
userinput,
{"__builtins__":{}, "pi": pi}, # add any other functions, that should be allowed
{"item": item},
)
if user_rslt:
item.update(user_rslt)
print("--->", item)
evalbut I highly recommend against it.