본문 바로가기
Hack/Web

SQL에서 "문자열"="문자열 "이 True인 현상

by Becoming a Hacker 2022. 9. 27.
반응형

예전에 들어서 알고 있던 내용인데, 업무를 하다가 오랜만에 보게된 "test"="test " is True 현상... padding 과 관련된 내용이라는 것은 알았지만 정확한 개념이 기억나지 않아 정리를 한 번 해야될 필요성을 느꼈습니다.

 

먼저 아래와 같은 결과가 참이 나오는 이유는 두 문자열의 길이가 다른 경우 문자열의 길이를 같게 만든 뒤 공백을 추가하는 표준이 존재하기 때문입니다.

CREATE TABLE minseok123(title varchar(10));
INSERT INTO minseok123(title) VALUES('test');
SELECT * FROM minseok123 WHERE title='test ';
# Result -> title : test

 

이와 같은 내용은 SQL 표준을 명시하는 SQL-92의 208페이지와 234 페이지에서 확인할 수 있습니다.

208 Page
3) The comparison of two character strings is determined as follows:

            a) If the length in characters of X is not equal to the length
              in characters of Y, then the shorter string is effectively
              replaced, for the purposes of comparison, with a copy of
              itself that has been extended to the length of the longer
              string by concatenation on the right of one or more pad char
              acters, where the pad character is chosen based on CS. If
              CS has the NO PAD attribute, then the pad character is an
              implementation-dependent character different from any char
              acter in the character set of X and Y that collates less
              than any string under CS. Otherwise, the pad character is a space.
              
3) 두 문자열의 비교는 다음과 같이 결정된다.
a) 만약 X의 문자 길이가 Y의 문자 길이와 같지 않다면,
각기 다른 길이의 데이터를 보다 효율적으로 비교하기 위해 짧은 문자열은 교체될 수 있다.
짧은 문자열을 복사하고 PAD 문자(스페이스)를 이어붙여 긴 문자열과 같은 길이를 가진 문자열을 만든다.
   
234 Page
c) If the data type of T is fixed-length character string with
  length in characters L and the length in characters M of V
  is less than L, then the first M characters of T are set to V
  and the last L-M characters of T are set to spaces.  
  
c) 만약 고정된 길이 L의 크기를 가진 데이터 T가 있고
L보다 작은 길이인 V의 크기를 가진 데이터 M이 있을때
두 개를 비교한다면,
M의 문자열 중 V개 만큼은 그대로 저장하고
남은 길이(T-V)만큼은 공백으로 채운다.

 

이러한 이유로 인해 시큐어 코딩을 완벽히 적용했더라도 예상치 못한 취약점이 발생할 수 있습니다.

 

예를 하나 들어보자면, 계정 명이 "admin"인 경우에만 관리자 권한을 부여하도록 코드가 작성되어 있을 때 "admin "로 가입하는 것으로도 관리자 권한을 획득할 수도 있습니다.

INSERT INTO user(id,password) VALUES("admin ", "1234");
SELECT * FROM user WHERE id="admin"; # True

 

물론 모든 Database에서 이러한 표준을 지원하는 것은 아닙니다. Oracle, MySQL, MSSQL에서는 이러한 표준을 지원하지만, SQLite, PostgreSQL, MariaDB에서는 이러한 표준을 지원하고 있지 않습니다.

 

Reference

 

MySQL에서 ‘a’ = ‘a ‘가 true로 평가된다? | 우아한형제들 기술블로그

{{item.name}} DB 알못의 어떤 리서치 개요 안녕하세요 기계인간 이종립입니다. FC플랫폼개발팀에서 배민찬 백엔드를 개발하고 있습니다. DB알못인 저는 업무 중에 우연히 MySQL에서 'a' = 'a '의 결과가

techblog.woowahan.com

 

댓글