[python] Peewee에서의 SQL 주입 방어

SQL 주입은 악의적인 사용자가 애플리케이션에 악성 SQL 쿼리를 주입하여 데이터베이스를 조작하는 공격입니다. Peewee는 간단하고 사용하기 쉬운 Python ORM(Object Relational Mapping) 라이브러리로 데이터베이스 쿼리 작성을 쉽게 해줍니다. 이러한 ORM 라이브러리를 사용하는 경우 SQL 주입을 방어하기 위해 몇 가지 주의해야 할 사항이 있습니다.

1. Placeholder 사용하기

SQL 주입을 방어하기 위해 Peewee에서는 쿼리 문자열 대신 Placeholder를 사용할 수 있습니다. Placeholder는 쿼리에 동적으로 값을 전달하기 위해 사용되며, Peewee에서는 ?를 사용하여 Placeholder를 작성할 수 있습니다. Placeholder를 사용하면 입력값이 자동으로 이스케이프되어 SQL 주입을 방지할 수 있습니다.

다음은 Placeholder를 사용한 예제입니다.

query = "SELECT * FROM users WHERE username = ? AND password = ?"
params = (username, password)
result = User.raw(query, params).execute()

2. Raw 쿼리 사용 시 주의

Peewee에서는 Raw 쿼리를 사용하여 직접 SQL 문을 작성할 수도 있습니다. 그러나 Raw 쿼리를 사용할 때는 사용자 입력값을 쿼리에 직접 넣는 것을 피해야 합니다. 대신 Placeholder를 사용하여 동적인 값 전달을 처리해야 합니다.

예를 들어, 다음과 같이 Raw 쿼리를 사용하는 경우, 입력값을 이스케이프하지 않고 직접 쿼리에 넣는 것은 SQL 주입에 취약할 수 있습니다.

query = f"SELECT * FROM users WHERE username = '{username}'"
result = User.raw(query).execute()

위와 같은 코드는 사용자 입력값을 바로 쿼리에 넣기 때문에 사용자가 악의적인 SQL을 주입할 수 있습니다. 이를 방지하기 위해 Placeholder를 사용하여 쿼리를 작성해야 합니다.

3. Peewee의 내장 기능 활용

Peewee는 SQL 주입과 같은 보안 이슈를 해결하기 위해 다양한 내장 기능을 제공합니다. 예를 들어, 사용자 인증과 관련된 기능을 사용할 때는 Peewee의 내장 check_password_hash 함수를 사용하여 비밀번호를 안전하게 확인할 수 있습니다.

from peewee import check_password_hash

user = User.get(User.username == username)
if check_password_hash(user.password, input_password):
    # 비밀번호가 일치하는 경우
else:
    # 비밀번호가 일치하지 않는 경우

위의 예제에서는 입력된 비밀번호를 check_password_hash 함수를 사용하여 해싱된 비밀번호와 비교하였습니다. 이를 통해 데이터베이스에 저장된 비밀번호를 보안적으로 처리할 수 있습니다.

결론

Peewee는 SQL 주입과 같은 보안 이슈에 대비하여 다양한 방어 메커니즘을 제공합니다. Placeholder를 사용하고, Raw 쿼리를 사용할 때 입력값을 적절히 처리하며, Peewee의 내장 기능을 활용하여 보안을 강화하는 것이 중요합니다. 이러한 사항을 유념하여 개발하면 안전한 애플리케이션을 개발할 수 있습니다.

참고 자료: