[Django] TextField의 max_length의 중요성 대하여

Humpback Whale·2024년 2월 3일
0
post-thumbnail

파이썬 웹 프레임워크인 Django를 통해 웹을 개발하다 보면, Model 객체를 작성하는 과정에서 models.TextField()에 익숙할 것이다.

대부분의 Django 기초 혹은 입문 책과 강의를 접하여 학습 하는 과정에서, 대개 TextFieldmax_length 옵션을 제한하지 않고 비워 둔 채로 사용하는 것을 심심찮게 경험하였다.
나 또한 아무 생각없이, TextField가 필요하다면, 그저 some_field = models.TextField()로 정의하여 사용하였다.

그러다, 김성렬님의 '백엔드 개발을 위한 핸즈온 장고' 책을 학습하던 중,

"TextField는 기본적으로 DB에 따라 다르나 최대 1GB 까지 저장 될 수 있다."

라는 내용을 보고, TextField를 사용함에 있어 엄격하게 max_length 옵션을 사용해야 한다는 생각이 들었다.

만일 Model 객체가 TextField를 포함하며, max_length 옵션이 지정되지 않았다면?

악의적인 사용자 가 존재할 경우, 해당 텍스트 필드가 허용하는 최대한 길의의 무의미한 텍스트를 전송하여, 의도적으로 Server 리소스를 낭비시킬 수 있을 것이다.

이에 대해 간단히 테스트를 해보았다.

title(CharField)description(TextField) 를 가지는 Post 객체를 만들어,
sqlite3 DB에 대용량의 텍스트 데이터를 저장하는 테스트를 하였다.

파이썬 쉘을 통하여, 다음과 같은 텍스트를 DB에 저장해 보았다.

>> text = 'a' * (10**8)
>> post = Post(title='Test Title', description=text)
>> post.save()

생성 된 Data를 확인 해 보니, 실제 DB에서는 약 200KB 의 데이터가 저장되었음을 확인하였다.
String을 Byte로 변환하여 저장하므로, 예상한 String의 크기보다 적은 용량이 저장되었다.

그렇다면, byte type text data를 전송 및 저장한다면?
저장할 텍스트를 바이트 데이터로 변경하여 저장 해보았으며. 1byte 크기 byte문자를 약 800MB 사이즈로 저장해 보았다.

>> text = b'a' * (8*10**8)   # byte 문자열 800MB
>> post = Post(title='Test Title', description=text)
>> post.save()

실제 DB에서도 약 800MB 사이즈의 크기를 가진 row 데이터가 생성되었으며,
프로젝트 폴더의 크기가 단 한개의 row를 가짐에도 불구하고, 800MB의 크기를 가지는 것을 확인하였다. (sqlite 사용시 프로젝트 폴더 내, db 파일을 통해 데이터를 저장하므로)

만일 프로젝트가 max_length를 엄격하게 적용하지 않은 TextField 를 사용하는 경우, 악의적인 의도로 byte data를 1GB까지 꽉 채워서 서버에 저장하도록 할 수 있다는 것이다.
1000개만 보내더라도, 1TB의 저장공간을 간단하게 소모시킬 수 있을 것이다.

'강건한' 서버를 염두한다면, TextField 의 사용 또한 엄격하게 적용해야 할 것으로 생각된다.
나 또한 이 점을 기억하고 프로젝트를 함에 있어 엄격히 적용해야 함을 느끼게 되었다.

Client 측에서 입력 데이터의 크기를 제한할 수도 있을 것이나, 만약 변경에 의해 그러한 중요한 사항이 누락 된다면?
Server의 책임을 단지 Client에게 책임을 전가할 수 없을 것이다.

1개의 댓글

comment-user-thumbnail
2024년 10월 15일

질문이 있습니다. 그러면 max_length 제한을 둔 Textfield와 Charfield는 어떤 차이가 있나요?

답글 달기