2

First, to provide some context, I am designing a console based version of Blackjack for entertainment and learning purposes. The code below was my solution to evaluate different conditions given user input.

The function below handles sleep times and user inputs and its file is imported to main.

import consoleControl as cs

def console_control( string, n_sec, return_flag, break_check, condition, wrapper=str)

return_flag is set to True if a return is expected, and if a condition is passed the following code will be executed.

if condition:
    while True:
        try:
            # This is only meant to be used on numeric types 
            userIo = wrapper(input(string))
                if eval(str(userIo) + condition):
                    return userIo
                else:
                    return None

         except ValueError:
            return None

My first successfull run of this, included the following function call.

# Gets a positive numeric value
def get_bankRoll():
    while True:
        # condition being passed to console_control()
        condition = '> 0'
        try:
            while True:
                string = 'How much money will you be gamblin\'... player? \nEuros: '
                cash = hud_control(0, None, None, None, None, [string, None, True, None, condition, float])
            # more code follows

Calling to ->

# Printing routine with set ascii charaters and other printed statements
def hud_control(hud, cash, game_phase, hand_display_args,  new_line, control_args):

    # Code between '#' removed for clarity
    if hud == 0:
        pass
    else:
        pass
    if new_line:
        for x in range(new_line): print('\n')
    # 

    if control_args:
        if control_args[-1]:
            return cs.console_control(*control_args)
        else:
            cs.console_control(*control_args)

I've read that eval is extremely unsafe, and indeed when I tested removing the wrapper and evaluated "sys.exit(0) #) I successfully exited. But with the wrapper I cannot, so assuming that I wish to only evaluate numeric expressions.

Any of the following would be good answers for me:

  • how would one exploit the current code?
  • what would be an alternative for dynamic (input, condition) assessment?

Note: I would prefer a classless implementation, if possible.

blackraven
  • 5,284
  • 7
  • 19
  • 45
  • 1
    If you just want the user to be able to input numbers, then *why would it even cross your mind* to use `eval()`? `int()` (or possibly `float()`) is all you need. – jasonharper Aug 25 '22 at 02:09
  • 2
    As an aside, **don't use list comprehensions for side effects**: `[print('\n') for x in range(new_line)]` list comprehensions are for *creating lists*. If you aren't trying to create a list, then *don't use a list comprehension* – juanpa.arrivillaga Aug 25 '22 at 02:13
  • In this case I want positive values only, but I will need to assess different conditions later. – Paulo Martins Aug 25 '22 at 02:14
  • 2
    I love this question! Thinking about security in this kind of training projects makes good coders! – ex4 Aug 25 '22 at 02:37

1 Answers1

1

‘eval()’ is not safe. It does not stop user from malicious code input to be executed

An alternative is to use

import ast
s2 = ast.literal_eval(s1)
blackraven
  • 5,284
  • 7
  • 19
  • 45
  • Is this the right idea? userIo = wrapper(input(string)); if eval(str(ast.literal_eval(str(userIo))) + condition):. It most certainly doesn't look nice, but it does do the job. But my question is, if I already have a while, try except, that is catching non numerics, then am I not guaranteed that any attempts to abuse eval() will be caught, or am I missing something? – Paulo Martins Aug 25 '22 at 11:56
  • 1
    yes in your case it could be caught by try-except. However it's a good practice to err on the side of caution as hackers always look for loopholes. You might be doing complex codes in future, and might miss something and result in opening up an entry for hackers – blackraven Aug 25 '22 at 12:19
  • sometimes I code like this to concat: `str(str1) + str(str2)` when I know the data is from a column of string type, but just in case... something might change upstream then my code will break – blackraven Aug 25 '22 at 12:21