Python3 to Python2 dangerous cross compatibility

I recently learned that there are some dangers of accepting user input via the input() function between Python2 and Python3.

In Python2 I was always taught to use the function, raw_input() to accept user input. In Python3, the raw_input() function was taken away and the input() function is used instead.

Each of these functions will automatically cast the entered data as a string, regardless of the input you pass it:

However, in Python2 there is also an input() function. In the Python2 input() function, the entered input is evaluated by Python, which allows for user input to be executed. This is not a good thing when you are dealing with untrusted input. Consider the following script that was intended to be run using Python3:

# evil_input.py
print('Welcome {}!'.format(name))

In Python3 this is safe, but if the same script is ran with Python2 a user can enter input that can execute on the operating system:

To make program safe and backwards compatible to Python2, a try/except block can be used to set the value of input to raw_input:

# evil_input.py
try:
input = raw_input
except:
pass
name = input('Enter your name: ')
print('Welcome {}!'.format(name))

This will make the script safe and functional for both Python2 and Python3:

As mentioned, I didn’t previously know about the input() function in Python2 until recently. I learned about this in the SANS training class, SEC 573: Automating Information Security with Python, and although I had pretty strong grasp on Python prior to the course, I definitely learned a lot and would recommend it.

Leave a Reply

Your email address will not be published. Required fields are marked *