출처
https://mysqlcode.com/mysql-bool-boolean/
https://marketsplash.com/tutorials/mysql/mysql-boolean/
https://cvk.posthaven.com/sql-injection-with-raw-md5-hashes
위 사이트들에서는 훨씬 더 자세하고 많은 양의 내용을 다루고 있다. 필자는 제목에 해당하는 내용만 다루겠다.
mysql의 boolean 데이터 유형은 tiny int이다.
비교시에 true는 1, false는 0으로 convert된다. 그럼 아래 4가지 상황을 가정해보자.
1. select * from user where true = 1;
2. select * from user where true = 11;
3. select * from user where true = '1';
4. select * from user where true = '11';
- 1번째 상황이다. true와 숫자 1의 비교다.
true는 1로 변환되기 때문에 true가 되어 값이 출력되는 것을 확인할 수 있다.
- 2번째 상황이다. true와 11의 비교다.
1과 11은 같은 값이 아니다. 따라서 false가 출력된다.
- 3번째 상황이다. true와 문자 '1'의 비교다
true는 1로 변환되고, 문자 '1' 역시 문자에서 숫자값으로 변환된다. 따라서 true가 되는 것이다
- 4번째 상황이다. true와 문자 '11'의 비교이다.
true와 문자 11이 각각 1과 11로 변환되어 false가 된 모습이다.
이를 통해 boolean값과 문자열이 숫자로 convert되어 comparison되는 것을 확인했다. 그러면 '11'과 같은 문자열이 아니라 'aa'와 같은 문자열은 어떻게 변환될까? 아래 4가지 상황을 더 살펴보자.
5. select * from user where false = 'aa';
6. select * from user where false = '1aa';
7. select * from user where false = '0aa';
8. select * from user where 'aa' = 0;
- 5번째 상황이다. false와 문자열 'aa'의 비교다.
false는 0으로, 'aa' 역시 0으로 변환되어 0 = 0 -> true가 된 모습이다.
- 6번째 상황이다. false와 문자열 '1aa'의 비교다.
false와 '1aa'의 비교다. 각각 0과 1로 변환되어 false가 됐다. 이로써 문자열이 숫자로 변환될 때는 맨 앞을 기준으로 바뀐다는 것을 알 수 있다. php의 느슨한 비교가 생각난다.
- 7번째 상황이다. false와 '0aa'
이 역시 각각 0과 0으로 변환되어 true가 된다.
- 8번째 상황이다. 그럼 명시적으로 false라고 나타낸 것이 아닌 0과 문자열 'aa'의 비교는 어떻게 될까?
'aa'가 0으로 변환되어 true가 된다.
false injection
그럼 false injection에 대해 간략히 알아보자.
select * from user where passwd = 'aaa' = 'bbb'
위의 sql문은 true가 되어 데이터를 출력해줄까? 혹은 false가 될까?
passwd = 'aaa'에서 'aaa'라는 값을 가진 레코드를 찾지 못했다. 따라서 false이다.
false = 'bbb'는 위에서 알아봤듯, 0과 0으로 convert되어 true가 될 것이다.
or를 사용한 경우
이번엔 `or`로 inj하는 상황을 가정해보자.
9. select * from user where passwd = 'aaa' or 'bbb'
10. select * from user where passwd = 'aaa' or '1bbb'
11. select * from user where passwd = 'aaa' or '2bbb'
- 9번째 상황이다. passwd = 'aaa' or 'bbb'
passwd= 'aaa'라는 레코드를 찾지 못하기 때문에 false
false or 'bbb'인데, string인 'bbb'는 0으로 cast된다.
따라서 결과는 false이다.
- 10번째 상황. passwd= 'aaa' or '1bbb'이다.
앞선 상황으로 생각해보면 `false or 1`인 것을 알 수 있다. 따라서 true이다.
- 11번재 상황이다. passwd='aaa' or '2bbb'이다.
`false or 2`인 상황일 것이다. 오늘 공부한 내용으로 인해 0을 제외한 모든 숫자값이 true가 된다는 것을 잊지말자.
'분류 전 > 개념 노트장' 카테고리의 다른 글
[SQL] information_schema가 필터링 됐을 때 Union SQL Injection (0) | 2024.03.29 |
---|---|
[Node.js] prepared statement 사용 시 주의 사항 (1) | 2024.03.28 |
[python] pickle 모듈 간단 사용법 및 취약점 (1) | 2024.02.12 |
[SQL] order by 0 과 order by if(1=1, 0, 0)의 차이 (0) | 2024.02.10 |
[개념] url 인코딩 / 디코딩 정리 (0) | 2023.06.27 |