아니? 뽐뿌가 SQL 인젝션에 무너졌다고?

sql 인젝션
SQL 인젝션

미래창조과학부는 지난 9월 11일 발생한 ‘뽐뿌’ 웹사이트 침해사고 관련 민관합동조사단의 조사결과를 발표했다. 결과는, 정말 안타깝게도 SQL 인젝션을 통한 개인정보 탈취 사건이었다. 이건 무슨, 범죄 수법의 박물관도 아니고 어째서 이런 고색창연한 수법에 번번이 당하는가.

‘뽐뿌’는 주로 스마트폰을 판매하는 쇼핑몰 정보를 공유하는 인터넷 커뮤니티 사이트다. 2005년에 개장해 10년 동안 스마트폰 대중화에 힘입어 엄청나게 성장해 현재 200만 회원수를 자랑하는 대형 커뮤니티. 그러던 지난 2015년 9월 11일, 해킹범으로 추정되는 자가 자유게시판에 타 회원의 개인정보를 공개하며 해킹 사실을 알렸고, 파장은 일파만파 퍼져 나가 급기야 미래창조과학부가 나서 민관합동조사단이 출동해 2015년 10월 20일, “웹 취약점을 악용한 데이터베이스 공격으로 개인정보 유출이 발생한 사건”이라는 공식 발표가 나왔다. SQL 인젝션을 통해 총 196만 명 가량의 정보가 유출된 것이다.

대개 그러하듯 문제 원인은 다양하다. SQL 인젝션 외에도 ‘뽐뿌’의 보안은 너무나 취약했다. 오래전에 개발이 중단된 ‘제로보드’ 구버전을 기반으로 구축한 사이트인데도 취약성 코어 업데이트를 하지 않아 애초에 부실했고, 해시 충돌 문제로 사용 자제를 권장하는 MD5 알고리즘 사용, 악성 애플리케이션 다운로드 문제, XSS 공격 취약성 등 문제가 많았다. 정보보호관리체계 인증 대상이면서도 관장기관인 한국인터넷진흥원 KISA의 공문도 무시하며 문제를 방치했으니 이건 뭐라 말하든 변명의 여지가 없는 상태. 그런데도 왜 SQL 인젝션만 유독 강조될까? 그게 너무나 한심하기 때문,,

SQL 인젝션이란?

SQL 인젝션이란 말의 뜻 그대로 주사기에다 독약을 넣어 피해자를 찔러 중독케 만드는 수법이라고 보면 된다. 웹 애플리케이션의 허점을 악용해 애플리케이션의 개발자가 예상하지 못했던 SQL 문장이 실행되게 함으로써 데이터베이스를 비정상적으로 조작하는 공격이다. 어째 말이 좀 어려우니 최대한 말랑하게 풀어 보자.

어떤 웹사이트 사용자가 있다.
그의 아이디는 ‘홍길동’이고 패스워드는 ‘비밀이야’라고 하자.
웹사이트의 데이터베이스에는 해당 사용자의 정보가 저장되어 있다.

아이디 : 홍길동
패스워드 : 비밀이야

사용자가 웹사이트에 접속해 아이디 칸에 ‘홍길동’이라고 쓰고 패스워드 칸에 ‘비밀이야’라고 쓰면, 웹 서버는 이를 입력값으로 받아 서로 연결해,
“아이디는 ‘홍길동’인데 패스워드는 ‘비밀이야’ 맞나?”
..라는 SQL 문장을 만들고 데이터베이스에 질문하면 데이터베이스가 가지고 있는 정보와 비교해 보고 “맞다”고 대답하면 웹 서버는 해당 사용자를 통과시키고 로그인에 성공한다.

그런데 어떤 해커가 아이디 칸에는 ‘홍길동’이라고 제대로 쓰고 패스워드 칸에는 ‘비밀이야’가 아니라 ‘틀리지 않으면 맞는 거겠지?’ 라고 썼다고 치자. 그러면 웹 서버는,
“아이디는 ‘홍길동’인데 패스워드는 ‘틀리지 않으면 맞는 거겠지?’ 맞나?”
..라고 묻고 데이터베이스는 기계답게 기계적으로 판단해 ‘틀리지 않으면, 맞다’고 대답하면 해커는 해당 아이디로 로그인에 성공해 막 통과해 버린다. 그럼 해당 아이디의 진짜 사용자
개인정보는 먼지 털듯 탈탈 털린다.

다른 문장도 만들어 보자.
“나는 ‘모든 회원’이야. 내 정보를 줘.”
..라고 했다고 치자. 그럼 우리 순진한 데이터베이스는 곧이곧대로 ‘모든 회원’의 정보를 준다.
“나는 ‘모든 회원’이야. 내 정보를 지워 줘.”

아니 이건 너무 황당하지 않아,, 그렇다. 황당하다. 그러니 요즘은 당연히 막는 구멍이라서 수법으로 쳐 주지도 않는 구식 그리고 초보적 수법이다. 거기에 딱 걸린 거니, 한심한 거지.

SQL 인젝션 대응 방법

정부 관련 기관이 제안하는 SQL 인젝션 대응방법은 아래와 같다.
1) 동적 SQL을 사용하지 않는다. 동적 SQL은 위 풀이처럼 입력값을 연결함으로써 SQL 문장을 완성하는 방식이기 때문에 악의적 주입이 쉽게 일어난다.
2) 안전한 웹사이트를 설계하고 구현한다. 입력값마다 적절한 검증 절차를 적용하고 위험한 입력값은 위험하지 않은 값으로 치환하고 입력값이 허용범위 내에 있는지 검사하는 등의 사전 조치다.
3) 데이터베이스의 에러 메시지를 노출하지 않는다. 에러 메시지를 통해 중요한 데이터가 노출되는 경우가 많다. 이를 악용하려는 시도도 많다.
4) 웹 방화벽 WAF를 사용한다. WAF는 평상시 외에도 문제가 발생해 애플리케이션을 수정하는 동안에도 웹사이트를 지켜 준다.
5) 웹 보안 취약점을 주기적으로 점검하라. 아무리 안전하게 설계하고 구현한 웹사이트에도 보안 문제는 남아 있을 수 있으니 일상적으로 점검하고 진단하는 과정이 필요하다.

근데 말이 어째 좀 이상하다? 웹사이트를 안전하게 설계하고 구현하는데, 안전하게 설계하고 구현해도 보안 문제는 남아 있을 수 있다? 이거 참 애매하다. 군대서 종종 듣던 부조리한 말, 딱 그런 느낌이다.
“어떻게 합니까?”
“잘 해야지!”
“그럼 잘 하기만 하면 되는 겁니까?”
“안 돼!”
다시 말해, 깡패 만나 죽도록 맞고 나서,
“돈.. 드.. 드리겠습니다!”
“필요 없어!”

뭐 이런 느낌적 느낌? 상당히 허무하다. 그러니 난 ‘시큐어 코딩’이란 말을 들을 때마다 참 애매한 기분이 든다. 그래, 잘해야지, 근데 잘해도 안 돼,,

다시 보는 ‘완벽한 웹 보안’

늘 주장하는 바, 본격 웹-시대다. 가장 중요한 정보보안 또한 웹 보안이다. 지난 ‘웹-시대, 웹은 과연 안전한가?’에서 지겨울 정도로 반복해 떠들었던 바. 웹 보안의 필수요소들을 정리한 ‘완벽한 웹 보안, 어떤 것들이 필요한가?’도 중요하지만 다소 원론적인 해법이라 볼 수도 있으니 실제 가동 중인 웹 서비스 현장에서 취할 만한 조치를 따로 ‘실제 현장에서 벌어지는, 실전 웹 보안’을 통해 살펴보기도 했다.

그럼 다시 위 ‘SQL 인젝션 대응방법’을 살펴보자. 그래, 저렇게 해야 한다. 하나도 빠짐없이 옳다. 하지만 보안이란 리스크 매니지먼트, 그럼에도 남아 있는 위험성에 집중해 볼 필요가 있다. 특히 시큐어 코딩. 당연히 엄격히 적용해야 한다. 그렇지만 그게 쉬운 일이 아니다.

웹사이트는 수많은 페이지로 구성된다. 모든 페이지가 동일한 보안성을 가지지 못하는 건 당연한 일이다. 그러니 해커들이 처음 하는 짓이 취약한 페이지를 찾는 일이다. 웹사이트를 딱 구축했다고 끝이 아니다. 서비스가 진행됨에 따라 페이지는 점점 늘어난다. 사용자들이 직접 생성하는 페이지도 있다. 사용자 컨텐츠는 시대적 필연 같은 거라 위험하다고 해서 막을 수도 없다. 자 그럼, 그 많은 페이지를 모두 어떻게 막을 것인가? 불가능한 일이다.

그런 점에서 WAF는 4) 순위가 부당하다고 느껴진다. 현실적으로 생각해 볼 때 위상이 보다 높아질 필요가 있다. WAF는 웹사이트 전면에 서서 오가는 컨텐츠를 감시한다. 해당 웹사이트가 얼마나 복잡해지든 상관 없이 출입문을 지키며 위험요소를 걸러내는 일종의 필터다. 옳지만 그냥 옳은 소리인 시큐어 코딩, 물론 중요하지. 하지만 현실적으로 가능하냐는 반문이다.

“그럼 WAF는 SQL 인젝션도 막을 수 있는가?”
당연히 막지. SQL 인젝션 따위를 못 막으면서 감히 웹 보안 운운하겠는가. 그래서 이번 ‘뽐뿌’ 사태가 한심하다는 거다.
“그래도 WAF는 돈이 들잖아?”
톡 까놓고 말하자면 완벽한 수준으로 시큐어하게 코딩을 하려면 개발자 수준까지 고려해야 하니 수준은 곧 몸값이라 인건비가 더 든다,, 그런데도 그 결과는 여전히 불안한 거라. 그리고, 196만 명의 개인정보를 개당 1천원씩만 받고 판다고 쳐 보자. 아 뭐,

그저 안타까운 이야기다. -_-