애플리케이션 보안
Application Security
개념
남의 계정으로 들어가거나 남의 데이터를 꺼내 가는 길이 코드에 남지 않게 만드는 개발 영역입니다.
등장 배경
보안을 오래 맡아 온 쪽은 네트워크였습니다. 회사 서버 앞에 방화벽을 세우고, 바깥에서 들어오는 통로를 몇 개만 열어 두고, 그 통로를 감시하는 일이 보안의 전부로 여겨졌습니다. 담을 높게 치면 안쪽은 안전하다는 그림이었습니다.
서비스가 웹으로 옮겨 가면서 그 담이 의미를 잃었습니다. 누구나 브라우저로 정문을 통과해 들어오는 것이 정상인 서비스에서는 바깥과 안쪽을 가르는 선이 방어선 노릇을 하지 못합니다. 공격은 담을 넘지 않고 정문으로 들어옵니다. 로그인 화면에 이상한 값을 넣어 보고, 주소창의 숫자를 하나 바꿔 보고, 남이 만들어 둔 링크를 누르게 만드는 식입니다.
페이지덱에서도 같은 일이 있었습니다. 문서 공유 링크가 /doc/1042 같은 모양이었고, 태오가 만든 화면은 링크를 연 사람이 그 문서의 참여자인지를 확인하지 않았습니다. 숫자를 1041 로 바꾸면 남의 팀 회의록이 그대로 열렸습니다. 방화벽은 멀쩡했고 서버도 뚫리지 않았습니다. 뚫린 것은 코드 한 줄, 정확히는 없는 코드 한 줄이었습니다.
이런 구멍은 기능을 다 만든 뒤에 찾아내기가 유독 어렵습니다. 기능이 잘 도는지는 의도한 사용법 하나만 따라가 보면 확인되지만, 안전한지는 의도하지 않은 사용법을 전부 상상해야 확인됩니다. 그 목록은 만든 사람의 머릿속에서 잘 나오지 않습니다. 자기가 짠 화면을 자기가 공격해 보는 일이 원래 잘 안 됩니다. 그래서 다 만든 뒤에 검사하는 대신 만드는 동안 규칙으로 걸어 두는 쪽으로 방향이 옮겨 갔고, 그 일에 붙은 이름이 애플리케이션 보안입니다.
서두르는 이유는 사고의 값이 다른 버그와 다르기 때문입니다. 결제 버튼이 하루 안 눌리면 하루치 매출을 잃고 끝나지만, 고객 문서가 한 번 새 나가면 그 고객은 돌아오지 않고 남은 고객까지 계약서를 다시 꺼내 봅니다. 규원이 기능 일정을 미루면서까지 권한 검사를 먼저 넣으라고 하는 것은 이 비대칭 때문입니다.
분야 구성
이 아래 묶인 용어들은 요청 하나가 들어와 데이터에 닿기까지의 길을 따라 놓여 있습니다. 누가 왔고 무엇을 해도 되는지 가리는 접근 제어, 그 관문이 뚫려도 내용을 읽지 못하게 두는 보호, 관문을 우회하는 알려진 수법인 취약점, 무엇부터 막을지 순서를 정해 주는 기준, 막혔다고 믿는 것이 정말 막혔는지 확인하는 점검, 그리고 모든 결정의 기본값이 되는 원칙입니다. 여섯 갈래입니다.
접근 제어는 문 앞에서 묻는 갈래입니다. 용어 일곱 개가 묶여 있고 앞의 둘이 질문, 나머지 다섯이 그 질문에 답하는 방법입니다.
- 인증 — 접속한 사람이 누구인지 확인하는 절차입니다. 아이디와 비밀번호를 맞춰 보는 로그인이 가장 익숙한 형태입니다.
- 인가 — 확인된 그 사람이 지금 요청한 일을 해도 되는지 판단하는 절차입니다. 앞의 공유 링크 사고는 인증은 통과했고 인가를 건너뛴 경우입니다.
- OAuth — 비밀번호를 넘기지 않고 권한만 빌려주는 표준입니다. 구글 계정으로 로그인을 누를 때 페이지덱이 받는 것은 구글 비밀번호가 아니라 이름과 메일 주소까지만 읽어도 된다는 허가증입니다.
- JWT — 그 허가증을 서명된 문자열 하나에 담아 주고받는 규격입니다. 서버가 요청마다 계정 정보를 다시 조회하지 않고 문자열의 서명만 보고 위조 여부를 가립니다.
- 다중 인증 — 비밀번호 하나로는 부족하다고 보고 휴대폰 인증번호나 지문 같은 두 번째 수단을 더 요구하는 방식입니다. 비밀번호가 새 나가도 계정은 남습니다.
- 싱글 사인온 — 회사 계정으로 한 번 로그인하면 여러 서비스를 다시 로그인하지 않고 쓰게 하는 방식입니다. 직원이 퇴사하면 계정 하나만 막아도 딸린 서비스가 함께 닫힙니다.
- 역할 기반 접근 제어 — 사람마다 권한을 일일이 주는 대신 관리자·편집자·열람자 같은 역할에 권한을 묶어 두고 사람에게는 역할만 붙이는 방식입니다. 구성원이 마흔다섯 명이고 권한이 스무 종류면 손으로 관리할 수 있는 양을 넘어섭니다.
보호는 뚫린 뒤를 대비하는 갈래입니다. 앞의 관문이 언젠가 한 번은 열린다고 가정하고, 그때 상대가 들고 가는 것이 읽을 수 없는 덩어리가 되도록 미리 만들어 둡니다. 세 용어가 각각 다른 자리를 맡습니다. 암호화는 내용을 열쇠 없이 못 읽는 형태로 바꿔 두는 일이라 열쇠가 있으면 원래대로 돌릴 수 있고, 고객 문서 본문처럼 나중에 다시 읽어야 하는 것에 씁니다. 해싱은 되돌릴 수 없게 뭉개는 일이라 비밀번호처럼 원래 값을 알 필요가 아예 없는 것에 씁니다. 계정 정보가 통째로 새 나가도 거기 적힌 것은 비밀번호가 아니라 비밀번호를 뭉갠 값이라 그대로는 로그인에 쓸 수 없습니다. TLS 는 이 둘을 저장이 아니라 오가는 구간에 적용한 표준으로, 주소창의 자물쇠 표시가 그것입니다. 카페 와이파이로 로그인해도 같은 망에 앉은 사람이 그 내용을 읽지 못하는 이유입니다.
취약점은 공격이 실제로 들어오는 길에 이름을 붙여 둔 갈래입니다. 셋이 대표적입니다. SQL 인젝션은 입력창에 넣은 값이 데이터를 꺼내는 질의문의 일부로 섞여 들어가는 경우입니다. 검색창에 이름 대신 질의문 조각을 적어 넣어 회원 목록을 통째로 꺼내 가는 식입니다. XSS는 남이 심어 둔 스크립트가 다른 사람의 브라우저에서 우리 서비스의 권한으로 실행되는 경우입니다. 댓글 칸에 스크립트를 적어 두면 그 댓글을 읽은 사람의 로그인 정보가 공격자에게 넘어갑니다. CSRF 는 이미 로그인해 둔 상태를 빌려 쓰는 경우입니다. 다른 사이트에 심어 둔 버튼을 누르는 순간 브라우저가 페이지덱에 저장해 둔 로그인 정보를 함께 실어 보내서, 사용자가 의도하지 않은 요청이 성사됩니다. 셋의 공통점은 서버가 아니라 들어온 값을 믿은 데서 생긴다는 점입니다.
기준은 무엇부터 막을지 순서를 정해 주는 갈래입니다. OWASP Top 10은 웹에서 실제로 가장 많이 터지는 취약점 열 가지를 몇 년에 한 번씩 추려 공개하는 목록입니다. 목록이 필요한 이유는 막을 수 있는 구멍이 사실상 무한하고 팀의 시간은 유한해서입니다. 열 항목을 점검표로 삼으면 보안 담당이 따로 없는 팀도 어디서부터 볼지 정할 수 있고, 고객사가 도입 전에 보내는 확인 문서에 답할 때도 같은 이름을 쓰게 됩니다.
점검은 막혔다고 믿는 것을 실제로 시험해 보는 갈래입니다. 모의 침투 테스트는 허락된 범위 안에서 외부 전문가가 진짜 공격자처럼 서비스를 두드려 보고 그 결과를 보고서로 남기는 점검입니다. 자동 검사 도구가 잡아 주는 것은 알려진 패턴까지이고, 권한 검사 한 줄이 빠진 화면 같은 구멍은 사람이 시나리오를 짜야 나옵니다.
원칙은 개별 결정의 기본값을 미리 정해 두는 갈래입니다. 최소 권한 원칙은 사람에게도 프로그램에게도 지금 하는 일에 필요한 만큼만 권한을 주라는 규칙입니다. 편하다는 이유로 모든 구성원에게 관리자 권한을 주면 계정 하나만 털려도 전부 털립니다.
여섯 갈래는 나란한 목록이 아니라 앞뒤로 물려 있습니다. 최소 권한 원칙을 실제로 지키려면 역할에 권한을 묶는 수단이 먼저 있어야 하고, 인가를 어디서 검사할지 정해 두지 않으면 공개된 취약점 목록의 상위 항목이 그대로 우리 서비스의 구멍이 되며, 그 구멍이 진짜로 열려 있는지는 사람이 두드려 봐야 답이 나옵니다. 그리고 어느 갈래도 완전하지 않다고 보기 때문에 보호 갈래가 마지막 방어선으로 남습니다.
실무 용례
"이 화면 인가 검사 들어갔나요? 로그인만 확인하면 남의 문서가 열립니다."
누구인지 확인하는 것과 그 사람이 이 문서를 열어도 되는지 확인하는 것은 별개라는 지적입니다.
"권한 모델은 지금 정합시다. 나중에 바꾸면 만들어 둔 화면을 전부 다시 봐야 해요."
누가 무엇을 할 수 있는지가 화면마다 흩어져 박히기 때문에 뒤에 고치는 값이 커진다는 뜻입니다.
"이번 분기에 모의 침투 테스트 예산을 잡아야 합니다. 대형 고객 계약 조건에 들어 있어요."
보안 점검이 개발팀의 자발적 과제가 아니라 매출이 걸린 계약 요건이 됐다는 말입니다.
페이지덱에서 이 일을 따로 맡은 사람은 없습니다. 구성원 마흔다섯 명에 보안 엔지니어 자리가 없어서, 태오를 비롯한 백엔드 개발자들이 코드 리뷰 때 나눠 봅니다. 공유 링크 사고 뒤로 태오가 가장 먼저 한 일은 그 화면을 고치는 것이 아니라, 문서를 꺼내는 자리를 한 곳으로 모으고 거기서 요청한 사람이 참여자인지 반드시 확인하게 만든 것이었습니다. 화면마다 검사를 넣으면 다음에 만드는 화면에서 또 빠집니다.
수아는 다른 쪽에서 같은 말을 꺼냅니다. 대형 고객은 계약 전에 보안 확인 문서를 보내오고, 거기에는 저장할 때와 주고받을 때 암호화를 하는지, 직원 권한을 얼마나 자주 점검하는지, 외부 점검을 받은 적이 있는지가 줄줄이 적혀 있습니다. 답을 못 채우면 계약이 멈춥니다. 규원이 분기 회의에서 확인하는 것도 같은 두 가지입니다. 지난 분기에 막지 못한 구멍이 있었는지, 그리고 지금 협상 중인 계약이 보안 항목에서 막혀 있지는 않은지입니다.
흔한 오해
보안을 서버와 인프라 담당이 알아서 하는 일로 여기는 오해가 가장 흔합니다. 방화벽·백신·서버 접속 통제처럼 눈에 보이는 장비가 전부 그쪽에 있으니 그렇게 보일 만합니다. 그런데 실제로 사고가 나는 자리는 대부분 그 장비가 닿지 않는 곳입니다. 권한 검사를 빼먹은 화면 하나, 입력값을 그대로 질의문에 붙인 코드 한 줄처럼 기능을 만든 사람만 알 수 있는 자리입니다. 이 오해를 그대로 두면 팀은 서버 설정만 단단히 조여 놓고 안심한 채로 구멍이 뚫린 화면을 계속 내보냅니다. 사고가 난 뒤에야 인프라가 아니라 기능 쪽에 원인이 있었다는 것을 알게 되고, 그때는 이미 나간 화면 수십 개를 거슬러 올라가며 점검해야 합니다.
우리 규모는 표적이 되지 않는다고 보는 것도 자주 나옵니다. 공격을 사람이 대상을 골라 벌이는 일로 상상하면 무명 서비스는 안전해 보입니다. 실제로 대부분의 공격은 자동으로 돌아가는 프로그램이 주소를 무작위로 훑으며 알려진 구멍을 하나씩 찔러 보는 방식이라, 회사 이름을 알든 모르든 순서가 돌아옵니다. 이름이 안 알려진 것은 방어가 아니라 통계일 뿐입니다. 이 기대를 붙들고 있으면 팀은 사용자가 늘어난 뒤에야 보안을 시작하게 되는데, 그 시점에는 지켜야 할 고객 데이터도 이미 쌓여 있고 고쳐야 할 화면도 이미 많습니다. 가장 싸게 막을 수 있던 시기는 만들면서 규칙을 걸어 두던 때였습니다.
같이 보면 좋은 페이지
하위 용어
연관 용어
마지막 업데이트 2026-09-16