Bài viết này nhằm mục đích giải thích và khám phá các lỗ hổng trong hàm input() ở phiên bản Python 2.x. Trong phiên bản Python 3, hàm raw_input() đã bị xóa và chức năng của nó đã được chuyển sang một hàm tích hợp mới được gọi là input().

1. Các cách nhập dữ liệu trong Python 2.x

Có hai phương thức phổ biến để nhận đầu vào trong Python 2.x:

  1. Sử dụng hàm input(): Hàm này lấy và giữ nguyên giá trị và kiểu đầu vào như bạn nhập mà không thay đổi bất kỳ kiểu nào.
  2. Sử dụng hàm raw_input(): Hàm này chuyển đổi một cách rõ ràng đầu vào được nhập thành kiểu string.

Chúng ta hãy sử dụng chương trình sau để xác định sự khác biệt giữa hai hàm trên:


# Python 2.x program to show differences between 
# input() and rawinput()function  
  
# 3 inputs using raw_input() function,  
# after which data type of the value 
# entered is displayed 
s1 = raw_input("Enter input to test raw_input() function: ") 
print type(s1) 
  
s2 = raw_input("Enter input to test raw_input() function: ") 
print type(s2) 
  
s3 = raw_input("Enter input to test raw_input() function: ") 
print type(s3) 
  
# 3 inputs using input() function,  
# after which data type of the value 
# entered is displayed 
s4 = input("Enter input to test input() function: ") 
print type(s4) 
  
s5 = input("Enter input to test input() function: ") 
print type(s5) 
  
s6 = input("Enter input to test input() function: ") 
print type(s6) 

Đầu vào:

Hello
456
[1,2,3]
45
"goodbye"
[1,2,3]

Kết quả:

Enter input to test raw_input() function: <type 'str'>
Enter input to test raw_input() function: <type 'str'>
Enter input to test raw_input() function: <type 'str'>

Enter input to test input() function: <type 'int'>
Enter input totest input() function: <type 'str'>
Enter input to test input() function: <type 'list'>

Lưu ý: Trong khi nhập chuỗi đầu vào trong hàm input(), chúng ta phải đính kèm theo giá trị trong dấu ngoặc kép. Điều này là không bắt buộc trong hàm raw_input()

2. Lỗ hổng trong phương thức input()

Lỗ hổng trong phương thức input() nằm ở thực tế là biến truy cập vào các giá trị của đầu vào có thể được truy cập bởi bất kỳ ai chỉ bằng cách sử dụng tên của biến hoặc phương thức. Hãy khám phá từng cái một:

  • Tên biến làm tham số đầu vào: Biến có giá trị của biến đầu vào có thể truy cập trực tiếp vào giá trị của biến đầu vào.

# Python 2.x program to show Vulnerabilities 
# in input() function using a variable  
  
import random 
secret_number = random.randint(1,500) 
print "Pick a number between 1 to 500"
while True: 
    res = input("Guess the number: ") 
    if res==secret_number: 
        print "You win"
        break
    else: 
        print "You lose"
        continue

Đầu vào:

15

Kết quả:

Pick a number between 1 to 500
Guess the number: You lose
Guess the number: 

Đầu vào:

secret_number

Kết quả

Pick a number between 1 to 500
Guess the number: You win

Như có thể thấy, trong trường hợp thứ hai, biến “secret_number” có thể được nhập trực tiếp làm đầu vào và kết quả luôn là “You won”. Nó đánh giá biến như thể một số được nhập trực tiếp, có nghĩa là nó luôn trả về giá trị kiểu True Boolean. Trong khi sử dụng raw_input, điều đó là không thể vì nó không cho phép đọc biến trực tiếp.

  • Tên hàm là tham số: Lỗ hổng nằm ở đây khi chúng ta thậm chí có thể cung cấp tên của hàm là các giá trị đầu vào và biến truy cập mà thực chất là không được cho phép truy cập.

# Python 2.x program to demonstrate input() function 
# vulnerability by passing function name as parameter 
secret_value = 500
  
# function that returns the secret value 
def secretfunction(): 
    return secret_value 
  
# using raw_input() to enter the number 
input1 = raw_input("Raw_input(): Guess secret number: ") 
  
# input1 will be explicitly converted to a string 
if input1 == secret_value: 
    print "You guessed correct"
else: 
    print "wrong answer"
      
# using input() to enter the number 
input2 = input("Input(): Guess the secret number: ") 
  
#input2 is evaluated as it is entered 
if input2 == secret_value: 
    print "You guessed correct"
else: 
    print "wrong answer"

Đầu vào:

400
secretfunction()

Kết quả:

Raw_input(): Guess secret number: wrong answer
Input(): Guess the secret number: You guessed correct

Trong bộ đầu vào/đầu ra này, chúng ta có thể thấy rằng khi chúng ta sử dụng hàm raw_input, chúng ta nhất thiết phải nhập đúng số. Tuy nhiên, trong khi sử dụng hàm input(), chúng ta thậm chí có thể cung cấp tên của một hàm hoặc một biến và trình thông dịch sẽ đánh giá điều đó.
Lấy ví dụ, ở đây, đầu vào cho hàm input() đã được đặt dưới dạng tên của hàm ‘secretfunction()’. Trình thông dịch đánh giá việc gọi hàm này và trả về số bí mật mà chúng ta muốn tìm và do đó điều kiện của chúng ta đánh giá là đúng, mặc dù chúng ta không nhập số bí mật đó.

Đầu vào:

secretfunction()
secret_value

Kết quả:

Raw_input(): Guess secret number: wrong answer
Input(): Guess the secret number: You guessed correct

Như đã giải thích ở điểm đầu tiên, trong ví dụ này, chúng ta cũng có thể chỉ cần nhập tên biến ‘secret_number’ ở đầu vào cho hàm ‘input()’ và chúng ta đã có thể có quyền truy cập vào giá trị mật.
Tuy nhiên, trong khi cố gắng gọi hàm secretfunction() trong đầu vào cho hàm raw_input(), nó sẽ cho chúng ta sai khi trình thông dịch chuyển đổi đối số của chúng ta thành chuỗi và không đánh giá nó như một lệnh gọi hàm.

Ngăn chặn lỗ hổng đầu vào

Điều luôn tốt hơn là sử dụng hàm raw_input() trong phiên bản python 2.x và sau đó chuyển đổi rõ ràng đầu vào thành bất kỳ kiểu nào chúng ta cần. Ví dụ: nếu chúng ta muốn lấy đầu vào là một số nguyên, chúng ta có thể làm như sau:

n = int(raw_input())

Điều này ngăn chặn các cuộc gọi hoặc đánh giá độc hại của các hàm.

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!