I'm making a django model that takes a string from the user and that string would be something like '(some var)+15+IF((condition),(passed),(not passed))' and I want it to solve all of this and probably add other personalized functions in the future so mainly for the if this would initially not work with eval from what I looked at.
-
2The short answer is yes but you should never combine user input with `eval()`, it's just way too dangerous. I would suggest creating your own parser or structuring the user input. If you have any specific questions then providing some code will help people help you. – 0sVoid Jul 21 '22 at 20:19
-
@0sVoid - I hear you, but... it is very situation dependent. If the users are internal to the organization then doing something like exec on strings contained in a database is no more risky than letting people add .py files to the source. – tdelaney Jul 21 '22 at 20:25
-
The main part of this side of the app is to ask the user for the math formulas that would be used in calculating the sizes and prices of a project, and the person adding the formulas would not be knowlegeable about python so i would like to make as simple as possible. Should I look into creating a parser? What would be involved into structuring the user input? – Pac Jul 21 '22 at 20:29
-
@tdelaney: I would say it is still more dangerous, since if people find a way to inject data in the database or pass it somehow as a string, it can lead to privelege escalation and thus eventually a "hacker" can exploit a single vulnerability, into a more serious one. – Willem Van Onsem Jul 21 '22 at 20:30
-
@tdelaney it *should* be harder to get a .py file into production, allowing user input into `eval()` is far more likely to go wrong. Not just from a malicious user but also a careless one! – 0sVoid Jul 21 '22 at 20:38
-
Even though you have users internal to an org, social engineering reality is users can compromise their account. With that in mind, I would prefer to structure user input through `forms.py` and use `views.py` to do the necessary grunt work. As for your comment about wanting to get math formulas from users I see that as a big UX risk. I would prefer to break down the functional concepts, and then engineer a form to get inputs, and use views to build the formula. I much prefer to use the presentation layer to simplify the user's experience. Rule of thumb - I don't trust users that much. – Carewen Jul 21 '22 at 20:41
-
@0sVoid - Hmmm... I didn't say "production" or "outward facing" or anything like that. I used a database example because it can be locked down as a well as a source repo. Depending on your goals, you may need a high level of access from the user. Suppose its a test case database and you want python snippets in there to fully document the steps being taken. What about a build system like Jenkins? It lets you store and run python. There are valid reasons to do it, just eyes wide open. – tdelaney Jul 21 '22 at 20:48
-
@Carewen - So you wouldn't use Jenkins or any GUI based build system that lets you enter scripts that are run on a back end server? – tdelaney Jul 21 '22 at 20:49
-
@tdelaney That wasn't the question asked. :) The OP was asking about users being able to directly inject strings into a DB and build math formulas on the fly. – Carewen Jul 21 '22 at 20:53
-
@Carewen - You may want to re-read the question. All we know is "personalized functions" and all I did was comment on the idea that "you should never combine user input with eval()". Whatever this system is may require scripts - perhaps downloading datasets. Maybe some complicated pandas functions. We don't know. I mentioned Jenkins, a well-known system that lets you save full python scripts as an example. – tdelaney Jul 21 '22 at 21:01
-
@tdelaney Maybe you should re-read my comment as well as the follow-up OP comments. My experience has shown me: users get social engineered and are generally less trustworthy. The more complexity you put in front of users the more UX takes a hit. The comment from the OP talking about "asking the user for the math formulas" combined with the OP left me with the sense that it is better to get super clear on function before determining form. When there's clarity on function, then a Django-centric solution would do well by using a form and views to lead to good function AND form. – Carewen Jul 21 '22 at 21:04
1 Answers
There is plenty of discussion around why eval()
can be bad (as you can see from the comments) and other questions like this: Why is using 'eval' a bad practice?
However, to try and answer your question, I would break your problem down into two components:
Parsing the user input into something understandable. You will likely end up with lots of
.splits()
anddict.get()
to validate the user input and extract the values to process, depending on how you structure the input. Plus checking left hand and right variables of operators. There might already be existing libraries that can do this. You will probably want to fundamentally replicate something like Excel's formula system.Processing that input into python functions, you can map dictionary keys to callable functions, so you could do something like this:
import math, operator function_dict = { 'SUM': sum, 'SQRT': math.sqrt, '+': operator.add, ... }
You can then pass your parsed function names into the dict and pass the values into the mapped python function. Using something like functools
compose
will let you chain these functions together.
However, as a simpler and more Django-centric solution, you might want to consider using forms, models, and restricting user input to something more rigid than a free text input.
Good luck! :)

- 2,547
- 1
- 10
- 25