업무 현장에서 궁금해 할 만한 개인정보 관련 법,제도,정책,사례 등을 개인정보보호위원회 전문가들이 골라서 설명해드립니다. 개인정보 관련 모니터링과 사전검토가 필요한 기업에는 가이드가 되고, 개인정보에 관심이 많은 분들께는 현안, 이슈를 두루 살펴볼 수 있는 유용한 창구가 되기를 기대합니다. 소재에 관한 제언이나 그 이외의 의견은 언제든지 환영합니다. pipcpr@korea.kr 로 연락주시기 바랍니다.
[9.16.(월). 발행]
해킹사고로 바라본 개인정보 유출
3부 SQL 인젝션
C사는 온라인 커뮤니티 사이트(ppomppu.co.kr)를 운영하다 2015. 9. 11. 해킹으로 고객정보(아이디, MD5로 암호화된 비밀번호, 생년월일, 이메일 등) 195만 건을 탈취 당했습니다. 해킹의 유형은 SQL 인젝션(Structured Query Language Injection)이었습니다. 이는 데이터베이스 질의어를 악의적으로 조작하여 서버를 오동작시킴으로써 접근권한 없는 정보(예: 다른 회원의 개인정보)를 열람 또는 변조(예: 로그인 실패 상황에서 로그인 성공값을 리턴)하는 공격으로서, 매우 오래되었고 흔한 기법입니다.
참고 - SQL 인젝션 공격 원리
어느 로그인 웹페이지에 이용자의 ID 및 PW를 입력받는 란(form)이 있고, 이것이 유효한 ID,PW인지 여부를 DB의 user_auth_table과 대조하기 위한 SQL 쿼리가 아래와 같이 프로그램 되어 있다고 전제합니다. 여기서 [ID 입력값] 및 [PW 입력값] 부분이 웹페이지 입력값입니다. SELECT * FROM user_auth_table WHERE id='[ID 입력값]' AND pw='[PW 입력값]';
예를 들어 이용자가 ID [jeon], PW [Pswd#24]를 위 웹페이지에 입력하면 다음과 같은 SQL 쿼리가 생성되어 DB에 전달됩니다. SELECT * FROM user_auth_table WHERE id='jeon' AND pw='Pswd#24';
그런데 해커가 ID [' OR 1=1; /*], PW [*/--]를 위 웹페이지에 입력하면 SQL 쿼리는 다음과 같이 됩니다. SELECT * FROM user_auth_table WHERE id='' OR 1=1; /*' AND pw='*/--';
여기서 ‘/* */’으로 둘러쌓인 부분 및 ‘--’ 이하 부분은 주석(comment)으로 처리되므로, 실제 DB 서버에 전달되는 SQL 쿼리는 다음과 같이 됩니다. SELECT * FROM user_auth_table WHERE id='' OR 1=1;
이때 WHERE 이하 “id='' OR 1=1” 부분의 논리값은 항상 TRUE 입니다. “1=1”(TRUE)와 무엇을 OR 하든 결과값은 항상 TRUE이기 때문입니다. 따라서 위 쿼리의 의미는 사실상 다음과 같아집니다. SELECT * FROM user_auth_table;
당초 개발자가 프로그램을 작성한 의도는 user_auth_table 입력된 ID?PW가 존재하는지 여부를 확인하는 것이었습니다(존재하면 쿼리가 성공하므로 로그인 처리, 존재하지 않으면 쿼리가 실패하므로 로그인 실패). 그런데 SQL 인젝션 공격으로 인해 user_auth_table의 내용을 모두 조회하는 것으로 프로그램이 오동작하게 되며, 위 SQL 쿼리 결과가 성공(조회할 레코드가 존재함)이므로 해커도 로그인에 성공하게 됩니다.
|
SQL 인젝션을 방어하는 방법은 크게 두 가지입니다.
첫째, 웹페이지 개발 단계에서 예방하는 방법입니다. 일례로 웹프로그래밍 언어에서 통상 지원하는 시큐어 함수인 Prepared Statement를 사용하는 등의 방법으로 악의적인 데이터베이스 질의어 조작을 방어할 수 있습니다. 일반적인 데이터베이스 질의 함수의 경우, SQL 쿼리 중 프로그램 실행 시 입력되는 등 동적으로 처리되는 부분(위 예시의 ‘ID 입력값’ 및 ‘PW 입력값’) 및 미리 프로그램된 부분(나머지 부분)을 모두 합친 후에 비로소 그 문법을 분석하기 때문에, 동적 처리 부분에 주석 특수문자 등이 들어오면 자칫 쿼리의 문법적 구조 자체가 바뀌어 해커에 의해 악용될 위험이 있습니다.
반면에 Prepared Statement 함수의 경우, SQL 쿼리 중 미리 프로그램 된 부분의 문법을 미리 분석하여 그 구조를 캐시한 후에 프로그램 실행 시 동적으로 처리되는 부분을 대입하는 원리이기 때문에, 동적 처리 부분에 의해 쿼리의 문법적 구조가 바뀌지 않으므로 SQL 인젝션 공격을 예방할 수 있습니다. 이외에도 SQL 인젝션을 예방하기 위해 사회통념상 합리적으로 기대 가능한 보호조치가 여러 가지 있을 수 있는데, 아무런 조치도 하지 않으면 고시 제6조 제3항 위반이 됩니다. 본건 C사의 경우 웹서버에서 구동되는 애플리케이션에 대하여 SQL 인젝션을 비롯한 취약점이 가시화되어 있었음에도 불구하고 이를 방어하기 위한 필요한 조치를 취하지 않았던 부분이 위반으로 판단되었습니다.
둘째, 웹서비스 운영 단계에서 트래픽을 관제·차단하는 방법입니다. 이용자 입력값을 가지고 SQL 쿼리를 동적으로 구성하는 퓁페이지의 경우, SQL 인젝션 공격에 사용되는 특수한 패턴, 예컨대 따옴표('), 주석(/*, */, --) 등 주석 특수문자가 입력값으로 들어온다면 이를 기반으로 침입탐지시스템 또는 웹방화벽에서 필터링·차단 조치를 할 수 있는 사례가 있습니다. 그러한 필터링 기술이 보편화되어 사회통념상 필수적이라 여겨지는 상황에서 이를 불이행하는 경우 고시 제6조 제1항 위반이 됩니다. 본건 C사의 경우 웹방화벽 ModSecurity의 기능 중 GET 방식(이용자 입력값을 인터넷 주소에 포함·노출된 파라미터에 넣어 전송하는 방식) 접속에 대한 차단 정책만 적용하고, POST 방식(이용자 입력값이 인터넷 주소가 아닌 메시지 본문 안에 들어가 전송되는 방식) 접속에 대한 차단정책을 적용하지 않아 POST 방식 접속에 관하여 비정상적 SQL 질의에 대한 차단을 누락한 부분이 위반으로 판단되었습니다.
C사에게 부과된 행정처분은 법원에서 확정되었습니다(서울고등법원 2018. 9. 20. 선고 2018누45055 판결(확정)). C사 사건을 계기로 SQL 인젝션 공격으로 인한 개인정보 유출사고에 관하여는 기본적으로 고시 제6조 제3항이 적용되며, 나아가 웹방화벽 또는 침입탐지시스템을 활용하여 공격을 탐지·차단할 수 있는 상황이었음에도 불구하고 그러한 조치가 미흡했다는 사실까지 밝혀지는 경우 고시 제6조 제1항을 적용하는 것이 행정관행화 되었습니다.
시사점
고시 제6조 제1항은 해킹공격이 들어오는 시점의 ‘관제’ 단계에서 사회통념상 주의를 다하여 이상행위를 탐지·차단할 것을, 동조항 제3항은 공격이 들어오기 전 프로그램을 개발하고 시스템을 구축하는 단계에서 해킹 원인이 된 취약점 등을 사회통념상 주의를 다하여 걸러낼 것을 각각 요구하는 규정입니다.
두 조항의 공통점은, 첫째, 다른 고시 조항들의 경우 특정한 행위의무를 부과하는 성격인 반면, 이들 조항은 불확정개념이 들어있다는 점입니다. 불확정개념이 쓰인 이유는, 해킹이라는 창과 보안이라는 방패의 싸움을 통해 끊임없이 진화하는 정보보호 기술을 법제도로써 포섭하기 위해 불가피하기 때문입니다. 둘째, 그러한 불확정개념이 지나치게 확장되지 않도록 이를 해석함에 있어 ‘사회통념상 합리적으로 기대 가능한’이라는 요건을 붙인다는 점입니다. 어디까지가 사회통념상 요구되는 조치인지는 워낙 사례가 다양하여 획일화된 잣대를 들이대기 어렵습니다.
분야별 현장에 안착된 필수조치(de facto standard)가 어디까지인지 파악하고 유형별 처분선례·판례에서 쓰였던 고려요소를 참고하여 해석·판단하는 개별적 접근이 필요하며, 이 글에서는 크리덴셜 스터핑, 파라미터 변조, SQL 인젝션, 세 가지 유형을 예시로 들어 대해 살펴보았습니다. 결론적으로 수범자는 자신이 비즈니스를 하는 분야에서, 법집행기관은 조사·처분하고자 하는 분야에서 각각 보편적으로 요구되는 보호조치 규범이 어느 수준인지를 파악하고 발맞춰 따라가는 노력을 지속해야 할 것입니다.
개인정보보호위원회 조사 3팀장 전승재