안녕하세요! 👋 OWASP Top 10 정복 시리즈, 오늘은 2021년에 새롭게 등장하여 모두의 주목을 받은 A04:2021-안전하지 않은 설계(Insecure Design)에 대해 이야기 나눠보겠습니다.
이 항목은 코드 한 줄의 버그가 아니라, 애초에 설계도 자체가 잘못된 근본적인 문제를 다룹니다. 아무리 좋은 자재로 튼튼하게 집을 지어도, 설계도에 현관문 잠금장치가 빠져있다면 소용없겠죠? 📜✍️ 이처럼 '안전하지 않은 설계'는 나중에 수정하기가 매우 어렵고 비용도 많이 드는, 아주 중요하고 심각한 문제입니다.

🤔 안전하지 않은 설계? 그게 뭔가요?
'안전하지 않은 설계'는 소프트웨어를 기획하고 설계하는 단계에서 보안 위협을 충분히 고려하지 않아 발생하는 모든 종류의 취약점을 의미합니다.
다른 OWASP 항목들이 주로 '안전하지 않은 구현(Insecure Implementation)'에 초점을 맞추는 것과 대조됩니다.
- 안전하지 않은 구현: 설계는 좋았지만, 개발자가 코딩 실수를 한 경우. (예: 설계도에는 '강철 잠금장치'라고 쓰여있는데, 실제로는 '플라스틱 장난감 자물쇠'로 만든 상황)
- 안전하지 않은 설계: 애초에 설계도 자체가 잘못된 경우. (예: 설계도에 '현관문 잠금장치'를 아예 빼먹은 상황)
즉, "이 기능은 어떻게 악용될 수 있을까?"라는 질문을 던지지 않고 만든 모든 기능이 '안전하지 않은 설계'의 결과물이 될 수 있습니다. 보안을 개발 초기 단계부터 함께 고려하는 'Shift-Left' 개념의 중요성을 보여주는 항목이죠.
🕵️♂️ 안전하지 않은 설계의 대표적인 사례들
어떤 경우에 '설계가 안전하지 않다'고 말할 수 있을까요?
1. 위협 모델링의 부재 (Lack of Threat Modeling)
가장 근본적인 문제입니다. 집을 짓기 전에 '도둑이 어떻게 들어올까?', '불이 나면 어떻게 대피할까?'를 고민하는 것처럼, 시스템을 설계하기 전에 발생할 수 있는 보안 위협을 미리 식별하고 대비책을 세우는 과정을 위협 모델링이라고 합니다.
- 문제점: 위협 모델링 없이 개발을 시작하면, "우리 서비스의 중요 자산은 무엇인가?", "누가, 어떻게 공격할 수 있는가?"를 모른 채로 기능을 만들게 됩니다. 😥❓
- 결과: 예측 가능한 공격(예: 비밀번호 찾기 기능 무한 시도)에 대한 방어 로직이 설계에서 누락됩니다.
2. 결함이 있는 비즈니스 로직 (Flawed Business Logic)
코드 자체에는 버그가 없지만, 서비스의 동작 흐름(Workflow)을 악용할 수 있는 경우입니다.
- 사례 🛒💸:
- 온라인 쇼핑몰에서 10만 원짜리 상품 A와 1천 원짜리 상품 B를 장바구니에 담습니다.
- 1천 원짜리 상품 B에만 적용되는 50% 할인 쿠폰을 적용합니다. (총 결제금액: 100,500원)
- 결제하기 직전, 장바구니에서 1천 원짜리 상품 B를 삭제합니다.
- 만약 시스템 설계가 잘못되었다면, 10만 원짜리 상품 A에 50% 할인이 그대로 적용되어 5만 원에 결제되는 문제가 발생할 수 있습니다.
3. 속도 제한(Rate Limiting)의 부재
시스템이 특정 기능의 시간당 요청 횟수를 제한하지 않는 설계 문제입니다.
- 문제점: 로그인 페이지에서 비밀번호 입력을 무한정 시도할 수 있다면 어떻게 될까요? 공격자는 자동화된 도구로 수억 개의 비밀번호를 순식간에 시도하여 계정을 탈취할 수 있습니다. (무차별 대입 공격) 💣
- 필요성: "로그인 시도 5회 실패 시 10분간 계정 잠금", "1분당 API 요청 100회로 제한"과 같은 속도 제한은 반드시 설계 단계에서 고려되어야 합니다.
4. 신뢰할 수 없는 클라이언트 제어
보안 검증을 서버가 아닌 사용자의 브라우저(클라이언트)에서만 수행하는 위험한 설계입니다.
- 문제점: 자바스크립트를 이용해 "가격 필드는 수정할 수 없도록" 비활성화 처리를 해두었다고 가정해 봅시다. 일반 사용자는 수정할 수 없지만, 공격자는 브라우저 개발자 도구나 프록시 툴을 이용해 이 제한을 간단히 우회하고 가격을 0원으로 바꿔서 서버에 전송할 수 있습니다. 😲
- 원칙: "절대 클라이언트를 믿지 마라(Never trust the client)." 모든 중요한 데이터 검증과 권한 확인은 반드시 서버에서 다시 수행하도록 설계해야 합니다.
🛡️ 어떻게 안전하게 설계할 수 있을까요?
- 보안 개발 생명주기(Secure SDLC) 도입 🔄: 요구사항 분석, 설계, 개발, 테스트, 배포 등 개발의 모든 단계에 보안 활동을 자연스럽게 통합해야 합니다. 보안은 개발이 끝난 후 추가하는 기능이 아닙니다.
- 위협 모델링 생활화 🧠💡: 새로운 기능을 설계할 때마다 "이 기능의 최악의 시나리오는 무엇일까?"를 팀원들과 함께 고민하고 토론하는 문화를 만드세요. STRIDE, DREAD 같은 검증된 방법론을 활용하면 좋습니다.
- 안전한 설계 패턴 사용:
- 최소 권한의 원칙: 모든 컴포넌트와 사용자에게 꼭 필요한 최소한의 권한만 부여합니다.
- 심층 방어: 하나의 방어선이 뚫리더라도, 다음 단계의 방어선이 공격을 막을 수 있도록 여러 겹의 보안 장치를 설계합니다.
- 공격 표면 최소화: 외부에 노출되는 기능이나 API를 최소화하여 공격받을 수 있는 지점을 줄입니다.
- 반복적인 검토와 개선: 설계는 한 번으로 끝나지 않습니다. 만들어진 설계도를 동료들과 함께 검토하고, 새로운 위협 정보가 나오면 설계를 지속적으로 개선해야 합니다.
✨ 마치며
안전하지 않은 설계는 애플리케이션의 "선천적인 심장병"과 같습니다. 나중에 발견하면 수술이 매우 복잡하고 위험하죠. 반면, 개발 초기에 위협을 고민하고 안전하게 설계하는 것은 작은 노력으로 미래의 큰 재앙을 막는 가장 효과적인 방법입니다.
"잘 만든 코드는 안전한 설계에서 나온다."는 말을 기억하며, 우리 모두가 '보안 아키텍트'라는 마음가짐으로 개발에 임하면 좋겠습니다!
'일반IT > IT보안' 카테고리의 다른 글
| OWASP Top 10: A04:2021 안전하지 않은 설계(Insecure Design)와 STRIDE 위협 모델링 샅샅이 파헤치기 🧐 (0) | 2025.09.29 |
|---|---|
| 🛡️ 공격자의 눈으로 우리 서비스를 보자! OWASP 위협 모델링 프로세스 완벽 가이드 (0) | 2025.09.29 |
| 💉 당신의 애플리케이션을 감염시키는 치명적인 공격, 인젝션(Injection) 파헤치기 (0) | 2025.09.29 |
| 🔐 내 비밀번호는 안전할까? OWASP 2위, 암호화 실패 파헤치기 (0) | 2025.09.29 |
| 👑 OWASP 1위! 깨진 접근 통제 (Broken Access Control) 파헤치기 (0) | 2025.09.29 |