Nie przekreślałbym tak szybko eval() bo można się pokusić o sprawdzenie danych pochodzących od użytkownika przed poddaniem ich ewaluacji (evaluation).
przykład (dozwolone znaki - all()) [ on-line ]
import os, re
def clearConsole():
os.system('cls' if os.name in ('nt', 'dos') else 'clear')
def comma2Dot(value):
return value.replace(",", ".")
def removeSpaces(value):
return re.sub(r"\s", "", value)
def insertValueFor(expression, variable, value):
return expression.replace(variable, value)
allowedCharacters = [
' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'+', '-', '*', '/', '(', ')', '.', 'p', 'i', 'x', 'r'
]
while True:
expression = input("Wprowadź wyrażenie: ")
expression = removeSpaces(expression.lower())
if expression == "": continue
expression = comma2Dot(expression)
if all(character in allowedCharacters for character in expression):
if "x" in expression:
x = float(comma2Dot(input("Podaj wartość dla x: ")))
expression = insertValueFor(expression, "x", str(x))
if "r" in expression:
r = float(comma2Dot(input("Podaj wartość dla r: ")))
expression = insertValueFor(expression, "r", str(r))
if "pi" in expression:
expression = insertValueFor(expression, "pi", "3.14")
try:
print("\n" + expression)
print(round(eval(expression), 2))
except ZeroDivisionError:
print("Bład dzielenia przez zero")
except:
print("Nieprawidłowe wyrażenie")
else:
if expression in ["s", "stop"]:
exit()
elif expression in ["c", "cls"]:
clearConsole()
continue
else:
print("Wprowadzone wyrażenie zawiera niedozwolone znaki")
print()
przykład (dozwolone znaki - regular expression) [ on-line ]
import os, re
def clearConsole():
os.system('cls' if os.name in ('nt', 'dos') else 'clear')
def comma2Dot(value):
return value.replace(",", ".")
def removeSpaces(value):
return re.sub(r"\s", "", value)
def insertValueFor(expression, variable, value):
return expression.replace(variable, value)
while True:
expression = input("Wprowadź wyrażenie: ")
expression = removeSpaces(expression.lower())
if expression == "": continue
expression = comma2Dot(expression)
if re.match("^[0-9pirx+-/*().]*$", expression):
if "x" in expression:
x = float(comma2Dot(input("Podaj wartość dla x: ")))
expression = insertValueFor(expression, "x", str(x))
if "r" in expression:
r = float(comma2Dot(input("Podaj wartość dla r: ")))
expression = insertValueFor(expression, "r", str(r))
if "pi" in expression:
expression = insertValueFor(expression, "pi", "3.14")
try:
print("\n" + expression)
print(round(eval(expression), 2))
except ZeroDivisionError:
print("Bład dzielenia przez zero")
except:
print("Nieprawidłowe wyrażenie")
else:
if expression in ["s", "stop"]:
exit()
elif expression in ["c", "cls"]:
clearConsole()
continue
else:
print("Wprowadzone wyrażenie zawiera niedozwolone znaki")
print()
można też:
Example of the solving exploitation with the eval()
We can solve this security problem by using safe dictionaries. We can create a safe dictionary containing holding only the x as its value corresponding to the key ‘x’. This dictionary is given as the second parameter of the eval() so that only x will be identified as a global variable while evaluating.
This will prevent the eval() function from accessing the get_pass() function as it does not have this as a global variable to call. And this makes the password or any other confidential data secure.
This example is shown in the below code.
def get_pass():
password='python@123'
return password
exp=input('Enter an expression: ')
x=int(input("Enter the value of x: "))
safe_dic={}
safe_dic['x']=x
eval(exp,safe_dic)