AppSec 기본: 애플리케이션의 핵심을 보호하기
Source: Dev.to
소프트웨어 엔지니어로서 우리는 단순히 동작하는 기능을 구축하는 데 익숙합니다. 애플리케이션 보안(AppSec)에서는 접근 방식이 바뀝니다: 우리의 목표는 그 기능들이 악용될 수 없도록 보장하는 것입니다. 이 글은 매일 안전한 시스템을 설계하고 취약점을 우선순위화하기 위해 사용할 핵심 원칙에 집중하면서, 사고 방식을 전환하도록 돕기 위해 작성되었습니다.
CIA 삼위일체
정보 보안 정책을 안내하는 기본 모델이며, 귀하의 애플리케이션이 사용자에게 약속하는 세 가지 약속을 나타냅니다:
-
기밀성 (Confidentiality): 민감한 데이터가 허가된 당사자만 접근할 수 있도록 보장합니다.
약속: “당신의 비밀을 지키겠습니다”. -
무결성 (Integrity): 데이터가 정확하고 완전하며 변조되지 않도록 보장합니다. 단, 허가된 사용자가 수정할 경우는 예외입니다.
약속: “아무도 당신의 데이터를 조작하지 못하게 하겠습니다”. -
가용성 (Availability): 시스템과 데이터가 허가된 사용자가 필요할 때 접근 가능하도록 보장합니다.
약속: “당신이 필요할 때 언제든지 여기 있겠습니다”.
정신 모델: 은행 금고를 상상해 보세요. 두꺼운 벽과 매니저의 열쇠가 기밀성을 나타내고; $100을 입금하고 $100을 인출(다른 금액이 아니라)하는 보장이 무결성을 나타내며; 영업 시간에 은행이 열려 있는 것이 가용성을 나타냅니다.
이러한 기둥 중 하나라도 무시하면 심각한 결과를 초래합니다: API 키나 개인 데이터 노출(기밀성), 데이터베이스를 변조하는 SQL 인젝션 공격(무결성), 서비스가 중단되는 DDoS 공격(가용성).
위험 관리
앱 보안에서 모든 것을 해결할 수는 없습니다. 위험 관리는 위협을 식별, 평가 및 우선순위를 정해 비즈니스에 허용 가능한 수준으로 위험을 낮추는 과정입니다.
핵심 공식:
Riesgo = Probabilidad × Impacto
- 가능성: 취약점을 얼마나 쉽게 악용할 수 있나요? 공개된 익스플로잇 코드가 있나요?
- 영향: 악용될 경우 어떤 피해가 발생하나요? 사용자 하나에 영향을 미치나요, 아니면 전체 데이터베이스에 영향을 미치나요?
정신 모델: 트라이아지 간호사처럼 행동합니다. 종이 찢김(낮은 영향)과 심장마비(높은 영향) 환자가 온다면, 종이 찢김이 100 % 발생 가능하더라도 먼저 심장마비를 치료합니다.
위험을 관리하려면 개발자는 **위협 모델링 (Threat Modeling)**을 채택해야 합니다(코드를 작성하기 전에 “무엇이 잘못될 수 있나요?”를 스스로 묻는 것) 그리고 CVSS와 같은 시스템을 사용해 취약점을 객관적으로 점수화합니다.
인증 vs. 인가
비록 자주 혼동되지만, 그 구분은 보안에 필수적입니다.
- 인증 (AuthN) – 당신은 누구인가? 사용자 또는 시스템의 신원을 확인합니다 (예: 비밀번호, 토큰, 생체인식 등).
- 인가 (AuthZ) – 무엇을 할 수 있나요? 이미 인증된 신원이 접근할 수 있는 자원을 결정합니다.
정신 모델: 운전 면허증은 인증에 사용됩니다 (사진과 이름으로 당신이 누구인지 증명). 같은 면허증에 적힌 나이는 인가에 사용됩니다 (술을 구매하거나 차량을 대여할 수 있는지 결정).
인가 오류 중 IDOR (불안전한 직접 객체 참조)와 같이 사용자가 URL의 ID를 바꿔 다른 사람의 데이터를 보는 경우가 가장 흔하고 위험합니다. 황금 규칙은: **“기본적으로 거부”**이며, 로그인 시에만이 아니라 모든 요청에서 권한을 확인해야 합니다.
개발 보안 원칙 (Shift‑Left)
- Defensa en Profundidad: 하나의 제어에만 의존하지 마세요. 여러 계층(WAF, 암호화, 입력 검증, 모니터링)을 사용해 하나가 실패하더라도 다른 계층이 시스템을 보호하도록 합니다.
- Principio de Mínimo Privilegio: 사용자와 시스템은 작업을 수행하는 데 필요한 최소 권한만 가져야 합니다.
- Gestión de Secretos: 키나 비밀번호를 소스 코드나 Git에 절대 저장하지 마세요. AWS Secrets Manager나 HashiCorp Vault와 같은 비밀 저장소와 짧은 수명의 토큰을 사용합니다.
- Validación de Entradas: 모든 사용자 입력을 잠재적인 악의적인 것으로 간주하고 처리하세요. SQL 인젝션을 방지하기 위해 파라미터화된 쿼리를 사용합니다.
- Seguridad en el Pipeline CI/CD: 알려진 취약점이 있는 종속성을 스캔하고 배포 전에 코드에 대한 정적 분석(SAST)을 수행합니다.
결론
보안은 체크리스트가 아니라 방어를 구축하면서 공격자처럼 사고하는 사고방식이다. CIA 삼위일체를 숙달하고, 위험을 이해하며, 인증과 인가를 올바르게 구분함으로써 단순히 기능 개발자에서 벗어나 애플리케이션 무결성의 첫 번째 수호자가 된다.