Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

ช่องโหว่ของฟังก์ชัน input() ใน Python


ในบทความนี้ เราจะเรียนรู้เกี่ยวกับวิธีที่ฟังก์ชัน input ทำงานอย่างไม่พึงประสงค์ในเวอร์ชัน 2.x หรือเวอร์ชันก่อนหน้า ในเวอร์ชัน 2.x ฟังก์ชัน raw_input() ทำงานแทนฟังก์ชัน input() ในเวอร์ชันใหม่ 3.x หรือใหม่กว่า ฟีเจอร์และฟังก์ชันที่พึงประสงค์ของทั้งสองฟังก์ชันถูกรวมเข้าด้วยกันในฟังก์ชัน input()

ก่อนอื่น มาดูประเภทอินพุตของฟังก์ชัน built-in สำหรับรับอินพุตใน Python 2.x

ตัวอย่าง

# Input Given : String
str1 = raw_input("Output of raw_input() function: ")
print type(str1)
str2 = input("Output of input() function: ")
print type(str2)

# Input Given : Float
str3 = raw_input("Output of raw_input() function: ")
print type(str3)
str4 = input("Output of input() function: ")
print type(str4)

# Input Given : Integer
str5 = raw_input("Output of raw_input() function: ")
print type(str5)
str6 = input("Output of input() function: ")
print type(str6)

ผลลัพธ์

Output of raw_input() function: Output of input() function: Output of raw_input() function: Output of input() function: Output of raw_input() function: Output of input() function:

คำอธิบาย − จากผลลัพธ์ มันชัดเจนว่า raw_input function แปลงอินพุตเป็น string type อย่างชัดเจน ไม่ว่าจะเป็นประเภทอินพุตที่ให้มา ส่วน input function จะเก็บชนิดข้อมูลเดียวกับที่ให้มาในขณะอินพุต

ตอนนี้หลังจากเห็นตัวอย่างข้างต้น คุณอาจสงสัยว่า ถ้า input function เก็บชนิดข้อมูลไว้ ทำไมมันถึงเป็นช่องโหว่? มาทำความชัดเจนด้วยภาพประกอบ −

ILLUSTRATION 1: ตอนนี้มาสร้างเกมทอยลูกเต๋าโดยใช้โมดูล random

ตัวอย่าง

import random as rd
number = random.randint(1, 6)
print("Pick a number between 1 to 6")
while True:
    user_input = input("Guess the number: ")
    if user_input == number:
        print("You guessed it right.")
        break
    else:
        print("OOPS! try it next time.")
        continue

คำอธิบาย − ในกรณีที่ผู้ใช้ให้อินพุตเป็น integer ผลลัพธ์ที่พึงประสงค์ตามนิพจน์เงื่อนไขจะถูกคำนวณตามลำดับ

ในกรณีที่ผู้ใช้ให้อินพุตเป็น string ที่เหมือนกับชื่อตัวแปรที่เราเก็บจำนวนสุ่มที่ได้จากลูกเต๋าโดยใช้ random module ผลลัพธ์ก็จะถูกคำนวณเช่นกัน แต่สิ่งนี้ไม่ควรเป็นผลลัพธ์ที่พึงประสงค์ที่เราต้องการคำนวณ จริงๆ แล้วมันควรยกข้อยกเว้นเกี่ยวกับประเภทอินพุตผิดเมื่อให้ string input มันพิจารณาว่าชื่อตัวแปรเทียบเท่ากับตัวเลขที่ผู้ใช้ป้อนโดยตรง นิพจน์ให้ค่า Boolean True และเกมจบสิ้นสุด ในทางตรงข้าม ถ้าเราใช้ raw_input() แทน ปัญหาแบบนี้จะไม่เกิดขึ้น

ช่องโหว่นี้อาจเป็นอันตรายถึงชีวิตในกรณีที่เราเก็บข้อมูลล็อกอิน (login credentials), รายละเอียดผู้ใช้ และรหัสผ่านบัญชี

ILLUSTRATION 2: ตอนนี้มาสร้างระบบที่ขอ PIN และเปรียบเทียบกับค่าที่เก็บไว้

ตัวอย่าง

stored_value = 7863
def return_function():
    return stored_value
inp = input()
if inp == stored_value:
    print "You Entered Correctly"
else:
    print "Oops! It's Incorrect"

คำอธิบาย

เช่นที่เราอภิปรายใน ILLUSTRATION ก่อนหน้า ว่าในกรณีที่อินพุตเป็น integer function จะทำงานปกติ แต่ในกรณีใดก็ตามที่ผู้ใช้ให้อินพุตเหมือนกับค่าที่คืนจากฟังก์ชัน เงื่อนไขจะกลายเป็น True และผลลัพธ์จะถูกสร้างขึ้น

สิ่งนี้เป็นอันตรายมากถ้าใช้ในกรณีจัดการข้อมูลสำคัญและเป็นความลับ เช่น PIN และรหัสผ่าน สามารถแก้ไขได้โดยใช้ raw_input() ที่มีใน Python 2.x

จาก ILLUSTRATION ทั้งสองข้างต้น ชัดเจนว่า input function ทำให้โปรแกรมพร้อมสำหรับการโจมตีตัวแปรโดยตรง (Variable attack)

สรุป

ในบทความนี้ เราได้เรียนรู้ว่ามีปัญหาและช่องโหว่อะไรบ้างที่พบขณะใช้ฟังก์ชัน input() ใน Python 2.x ที่จำเป็น