RSS듀오랩스

애플리케이션 보안 핵심 개념 지도: 위협 모델에서 사고 대응까지

보안 사고는 대개 아무도 모르던 정교한 기법이 아니라, 다들 알고 있었지만 이 자리에는 없을 거라고 생각한 실수에서 시작합니다. 검증하지 않은 입력 하나, 권한 확인을 빠뜨린 엔드포인트 하나, 저장소에 그대로 남은 토큰 하나면 충분합니다. 그래서 보안은 마지막에 붙이는 점검이 아니라 설계할 때 함께 정해지는 성질에 가깝습니다.

이 문서는 애플리케이션 보안의 중요한 개념을 한곳에서 찾기 위한 지도입니다. 네트워크 장비나 침해 대응 전문 영역보다는, 애플리케이션을 만들고 운영하는 사람이 실제로 결정하게 되는 지점을 중심에 뒀습니다. 각 항목은 한두 문장으로 범위를 잡고, 자세한 설명이 필요한 주제는 별도의 심화 글로 연결합니다. 처음부터 끝까지 외울 필요는 없습니다. 어떤 기능을 만들 때 무엇을 확인해야 하는지 좁혀 가는 기준점으로 사용하는 편이 좋습니다.

자산과 위협 식별
-> 신뢰 경계
-> 인증
-> 인가
-> 입력과 출력
-> 데이터 보호
-> 의존성과 공급망
-> 운영과 탐지
-> 사고 대응

기본 개념

  • 자산: 지켜야 할 대상입니다. 데이터, 계정, 가용성, 평판이 모두 자산이며 무엇이 자산인지 적지 않으면 우선순위를 정할 수 없습니다.
  • 위협: 자산에 해를 끼칠 수 있는 사건입니다. 공격자만이 아니라 실수와 오작동도 포함해서 봐야 현실적인 목록이 나옵니다.
  • 취약점: 위협이 실제로 통하게 만드는 결함입니다. 취약점이 있어도 접근 경로가 없으면 위험은 낮습니다.
  • 위험: 발생 가능성과 영향의 조합입니다. 모든 취약점을 같은 급으로 다루면 정작 급한 것을 놓칩니다.
  • 공격 표면: 외부에서 닿을 수 있는 모든 지점의 합입니다. 기능을 늘리면 늘어나고, 쓰지 않는 것을 끄면 줄어듭니다.
  • 신뢰 경계: 신뢰 수준이 달라지는 선입니다. 이 선을 넘어오는 모든 데이터는 검증 대상이라는 단순한 규칙이 여기서 나옵니다.
  • 위협 모델링: 무엇을 누구로부터 지키는지 먼저 적는 작업입니다. 대상 없이 하는 강화는 비용만 늘리고 실제 위험은 그대로 둡니다.
  • 심층 방어: 하나가 뚫려도 다음 층이 막도록 겹쳐 두는 원칙입니다. 어떤 단일 방어도 완전하지 않다는 전제에서 출발합니다.
  • 최소 권한: 필요한 만큼만, 필요한 동안만 줍니다. 사고가 났을 때 피해 범위를 결정하는 가장 큰 변수입니다.
  • 안전한 기본값: 명시적으로 열지 않으면 닫혀 있어야 합니다. 기본이 열려 있으면 누군가는 반드시 닫는 것을 잊습니다.
  • 완전 중재: 모든 접근을 매번 검사합니다. 처음 한 번만 확인하고 이후를 신뢰하면 권한 변경이 반영되지 않습니다.
  • 모호함에 기대지 않기: 주소를 감추는 것은 보안이 아닙니다. 감춰진 것은 결국 발견되고, 발견되면 남는 방어가 없습니다.
  • 보안과 사용성: 지나치게 까다로운 절차는 우회를 부릅니다. 사람이 지킬 수 있는 수준으로 설계하는 것도 보안의 일부입니다.

인증

  • 인증: 요청한 주체가 누구인지 확인하는 절차입니다. 무엇을 할 수 있는지와는 별개의 문제입니다.
  • 비밀번호 저장: 절대 원문이나 단순 해시로 저장하지 않고, 느리게 설계된 전용 알고리즘과 솔트를 씁니다. 유출은 언젠가 일어난다는 전제로 정해야 합니다.
  • 비밀번호 정책: 복잡도 규칙보다 길이와 유출 목록 대조가 효과적입니다. 잦은 강제 변경은 오히려 더 나쁜 비밀번호를 만듭니다.
  • 다중 인증: 아는 것, 가진 것, 그 자신인 것 중 둘 이상을 요구합니다. 계정 탈취를 막는 수단 중 비용 대비 효과가 가장 큽니다.
  • 세션: 로그인 이후 요청들이 같은 사용자임을 잇는 상태입니다. 만료, 갱신, 강제 종료 경로를 함께 설계해야 합니다.
  • 세션 쿠키 속성: 전송 구간 제한, 스크립트 접근 차단, 교차 사이트 전송 제한을 켭니다. 셋 중 하나만 빠져도 흔한 공격이 통합니다.
  • 토큰 기반 인증: 서명된 토큰으로 상태를 클라이언트에 둡니다. 서버가 즉시 무효화할 수 없다는 점이 가장 중요한 제약입니다.
  • 접근 토큰과 갱신 토큰: 짧게 사는 것과 길게 사는 것을 나눕니다. 갱신 토큰이 새면 짧은 수명의 이점이 사라지므로 보관 위치가 중요합니다.
  • 위임 인증: 다른 서비스의 계정으로 로그인하게 하는 방식입니다. 비밀번호를 다루지 않아도 되지만 계정 연결과 탈퇴 처리를 직접 설계해야 합니다.
  • 계정 복구: 대개 인증 체계에서 가장 약한 고리입니다. 복구 경로가 본인 확인보다 쉬우면 그 경로가 실제 인증 수단이 됩니다.
  • 무차별 대입 방어: 속도 제한, 지연 증가, 계정 잠금을 조합합니다. 잠금만 쓰면 그 자체가 서비스 거부 수단이 됩니다.
  • 자격 증명 스터핑: 다른 사이트에서 유출된 조합을 그대로 시도하는 공격입니다. 유출 목록 대조와 이상 로그인 탐지가 실질적인 대응입니다.
  • 로그아웃: 서버 쪽 세션과 클라이언트 저장소를 모두 정리합니다. 화면만 바뀌고 토큰이 남는 구현이 흔합니다.

인가

  • 인가: 인증된 주체가 무엇을 할 수 있는지 정하는 규칙입니다. 인증과 한곳에 섞으면 권한 규칙을 추적할 수 없게 됩니다.
  • 역할 기반 접근 제어: 권한을 역할에 묶고 사용자에게 역할을 줍니다. 단순하지만 예외가 늘면 역할이 폭증합니다.
  • 속성 기반 접근 제어: 사용자, 자원, 상황의 속성으로 판단합니다. 유연한 대신 규칙이 복잡해져 검증이 어려워집니다.
  • 객체 수준 인가: 이 사용자가 바로 이 자원에 접근할 수 있는지 확인합니다. 목록 API는 막았는데 상세 API는 식별자만 바꾸면 열리는 사고가 가장 흔합니다.
  • 식별자 추측: 순차 번호는 다른 사용자의 자원을 쉽게 지목하게 합니다. 추측 어려운 식별자는 보조 수단이지 인가의 대체가 아닙니다.
  • 권한 상승: 낮은 권한이 높은 권한 기능에 닿는 결함입니다. 관리자 화면을 숨기는 것만으로는 막히지 않습니다.
  • 서버 측 검증: 화면에서 버튼을 감추는 것은 인가가 아닙니다. 모든 판단은 요청을 받는 쪽에서 다시 해야 합니다.
  • 다중 테넌시 격리: 여러 고객 데이터가 한 시스템에 있을 때 서로 보이지 않게 합니다. 질의 조건 하나에 의존한 격리는 언젠가 새어 나갑니다.
  • 위임과 대리 접근: 지원 담당자가 사용자 계정을 대신 보는 기능은 강력하고 위험합니다. 범위 제한과 감사 기록이 반드시 함께 가야 합니다.
  • 기계 간 인증: 서비스끼리의 호출도 신원과 권한이 필요합니다. 내부망이라는 이유로 무조건 허용하는 설정이 흔한 구멍입니다.
  • 범위: 토큰이 허용하는 동작의 범위를 좁게 나눕니다. 하나의 만능 키가 있으면 그 키가 곧 전체 위험입니다.
  • 권한 회수: 해지와 퇴사 시 즉시 반영되는 경로가 있어야 합니다. 토큰 수명이 길면 회수와 수명 사이의 공백이 남습니다.
  • 정책의 한곳 관리: 인가 규칙이 코드 곳곳에 흩어지면 감사할 수 없습니다. 한 자리에 모으고 테스트로 고정합니다.

입력과 출력

  • 모든 입력을 의심한다: 사용자 입력뿐 아니라 헤더, 파일 이름, 외부 API 응답, 큐 메시지가 모두 입력입니다. 신뢰 경계를 넘어온 것이면 전부 해당합니다.
  • 허용 목록 방식: 허용할 형태를 정하는 편이 금지할 형태를 나열하는 것보다 안전합니다. 금지 목록은 언제나 빠진 것이 있습니다.
  • 검증 위치: 클라이언트 검증은 사용성이고 서버 검증이 보안입니다. 두 곳 모두 필요하지만 역할이 다릅니다.
  • 주입 공격: 데이터가 명령으로 해석되면서 생깁니다. 데이터베이스, 셸, 템플릿, 직렬화 어디서나 같은 형태로 나타납니다.
  • 매개변수 바인딩: 질의문과 값을 분리해 값이 문법으로 읽히지 않게 합니다. 문자열을 이어 붙이지 않는 것만으로 대부분이 막힙니다.
  • 출력 인코딩: 데이터를 쓰는 맥락에 맞게 이스케이프합니다. 같은 값이라도 HTML, 속성, 스크립트, URL에서 규칙이 다릅니다.
  • 교차 사이트 스크립팅: 남의 스크립트가 우리 페이지 권한으로 실행되는 문제입니다. 저장형과 반사형, 그리고 화면단에서 생기는 형태가 있습니다.
  • 콘텐츠 보안 정책: 어떤 출처의 스크립트와 자원을 허용할지 브라우저에 선언합니다. 실수로 남은 취약점의 실제 피해를 줄여 주는 마지막 그물입니다.
  • 교차 사이트 요청 위조: 로그인된 사용자의 브라우저가 의도치 않은 요청을 보내게 만듭니다. 토큰과 쿠키 전송 제한 속성으로 막습니다.
  • 서버 측 요청 위조: 서버가 공격자가 지정한 주소로 요청하게 만드는 결함입니다. 내부망과 메타데이터 서비스가 노출되는 경로가 됩니다.
  • 파일 업로드: 이름, 크기, 형식, 저장 위치, 제공 방식을 모두 통제해야 합니다. 업로드된 파일이 실행 가능한 경로에 놓이는 것이 최악입니다.
  • 역직렬화: 신뢰할 수 없는 데이터를 객체로 되돌리면 코드 실행으로 이어질 수 있습니다. 형식과 대상 타입을 제한해야 합니다.
  • 경로 조작: 사용자 입력이 파일 경로에 들어가면 상위 디렉터리로 빠져나갈 수 있습니다. 경로를 정규화한 뒤 허용 범위 안인지 확인합니다.

데이터 보호

  • 분류: 어떤 데이터가 민감한지 등급을 나눕니다. 등급이 없으면 모든 데이터를 같은 강도로 다루게 되어 결국 아무것도 못 지킵니다.
  • 최소 수집: 필요 없는 데이터는 받지 않습니다. 없는 데이터는 새지 않으므로 가장 확실한 대책입니다.
  • 전송 암호화: 오가는 모든 구간을 암호화합니다. 내부 서비스 사이 구간이 빠져 있는 경우가 흔합니다.
  • 저장 암호화: 디스크와 백업에 쌓인 상태를 보호합니다. 키를 같은 곳에 두면 암호화의 의미가 크게 줄어듭니다.
  • 키 관리: 생성, 보관, 교체, 폐기의 수명 주기가 있습니다. 교체 절차가 없는 키는 사실상 영구 키입니다.
  • 비밀 관리: 자격 증명을 코드와 이미지 밖에 두고 주입합니다. 저장소 이력에 한 번 들어간 비밀은 지워도 남아 있다고 봐야 합니다.
  • 해싱과 암호화의 구분: 비밀번호는 복원할 필요가 없으므로 해싱하고, 나중에 읽어야 하는 값은 암호화합니다. 이 둘을 바꿔 쓰면 둘 다 잘못됩니다.
  • 가명화와 익명화: 식별자를 대체하는 것과 되돌릴 수 없게 만드는 것입니다. 가명화된 데이터는 여전히 개인정보로 다뤄야 합니다.
  • 마스킹: 화면과 로그에 일부만 보여 줍니다. 무엇을 지울지가 아니라 무엇만 남길지로 규칙을 짜야 누락이 없습니다.
  • 로그에 남기지 않을 것: 토큰, 비밀번호, 카드번호, 주민등록번호는 로그에 들어가면 안 됩니다. 오류 상황에서 요청 전체를 덤프하는 코드가 대표적인 유출 경로입니다.
  • 보존 기간: 얼마나 오래 둘지 정하고 실제로 지웁니다. 지우지 않으면 비용과 법적 위험이 함께 자랍니다.
  • 백업 보호: 백업은 원본과 같은 등급의 자산입니다. 접근 권한과 암호화가 본 시스템보다 느슨한 경우가 많습니다.
  • 삭제 요청: 계정 삭제 시 어디까지 지울지 정합니다. 캐시, 로그, 백업, 분석 시스템에 남는 사본이 흔히 누락됩니다.

의존성과 공급망

  • 의존성 목록: 무엇을 쓰고 있는지 알아야 대응할 수 있습니다. 목록이 없으면 새 취약점 공지가 나와도 영향 여부를 판단할 수 없습니다.
  • 알려진 취약점 점검: 라이브러리 취약점을 자동으로 확인합니다. 빌드 과정에 넣어야 실제로 계속 돌아갑니다.
  • 버전 고정: 잠금 파일로 정확한 버전을 재현 가능하게 만듭니다. 범위 지정만 있으면 빌드마다 다른 코드가 들어옵니다.
  • 전이 의존성: 직접 넣지 않은 패키지가 대부분입니다. 깊이 들어간 의존성이 실제 위험의 상당 부분을 차지합니다.
  • 패키지 신뢰: 이름이 비슷한 가짜 패키지와 탈취된 계정이 실제로 존재합니다. 새 의존성을 추가하는 것은 그 관리자를 신뢰하겠다는 결정입니다.
  • 빌드 무결성: 빌드 환경 자체가 공격 대상입니다. 빌드 스크립트가 임의 코드를 실행할 수 있다는 점을 전제로 격리합니다.
  • 이미지 기반: 컨테이너 기본 이미지에도 취약점이 쌓입니다. 작은 기반 이미지를 쓰고 주기적으로 다시 빌드해야 합니다.
  • 비밀 유출 검사: 저장소에 자격 증명이 들어가는 것을 커밋 시점에 막습니다. 사후 삭제보다 사전 차단이 훨씬 쌉니다.
  • 저장소 권한: 누가 병합할 수 있고 누가 배포를 트리거할 수 있는지가 곧 운영 권한입니다. 코드 권한과 운영 권한은 같은 등급으로 다뤄야 합니다.
  • 서명과 출처 증명: 배포물이 우리가 만든 것인지 확인할 수 있게 합니다. 공급망 공격에 대한 실질적인 방어입니다.
  • 갱신 정책: 언제 올릴지 규칙을 정합니다. 미루면 한 번에 큰 폭으로 올려야 해서 더 위험해집니다.
  • 폐기된 패키지: 유지되지 않는 라이브러리는 취약점이 나와도 고쳐지지 않습니다. 대체 계획 없이 계속 쓰는 것이 결정입니다.
  • 외부 스크립트: 광고와 분석 스크립트는 우리 페이지 권한으로 실행됩니다. 무결성 검증과 정책으로 범위를 제한해야 합니다.

웹 플랫폼 보안

  • 동일 출처 정책: 다른 출처의 문서가 서로의 데이터를 읽지 못하게 하는 기본 규칙입니다. 브라우저 보안의 토대입니다.
  • 교차 출처 허용: 필요한 출처만 골라 여는 설정입니다. 모든 출처를 허용하면 앞의 규칙을 스스로 없애는 것입니다.
  • 쿠키 범위: 도메인과 경로에 따라 어디까지 전송될지 정해집니다. 하위 도메인이 많으면 의도치 않게 공유됩니다.
  • 전송 보안 강제: 항상 암호화된 연결만 쓰도록 브라우저에 알립니다. 첫 접속의 취약 구간까지 줄이려면 사전 등록이 필요합니다.
  • 혼합 콘텐츠: 암호화된 페이지가 평문 자원을 불러오면 보호가 깨집니다. 차단되기 때문에 기능 오류로 먼저 드러나기도 합니다.
  • 클릭재킹: 우리 화면을 투명하게 덮어 사용자가 다른 것을 누르게 만듭니다. 프레임 삽입 허용 범위를 제한해 막습니다.
  • 참조 정보 노출: 이동할 때 이전 주소가 함께 전달됩니다. 주소에 민감한 값이 있으면 그대로 새어 나갑니다.
  • 주소에 비밀을 두지 않기: 주소는 로그, 이력, 공유 링크에 남습니다. 토큰과 개인정보를 질의 문자열에 넣으면 안 되는 이유입니다.
  • 캐시 제어: 개인화된 응답이 공유 캐시에 담기면 다른 사용자에게 보입니다. 캐시 가능 여부를 응답마다 명시해야 합니다.
  • 오픈 리다이렉트: 우리 도메인을 거쳐 외부로 보내는 경로는 피싱에 쓰입니다. 이동 대상을 허용 목록으로 제한합니다.
  • 속도 제한: 무차별 시도와 자원 남용을 억제합니다. 사용자 단위와 주소 단위를 함께 봐야 우회가 어려워집니다.
  • 봇 대응: 자동화 트래픽을 구분해 다르게 다룹니다. 검색과 AI 크롤러 같은 정상 접근까지 막지 않도록 예외를 관리해야 합니다.
  • 오류 메시지: 내부 구조와 스택을 그대로 내보이면 공격자에게 지도를 주는 셈입니다. 사용자에게는 짧게, 기록에는 자세히 남깁니다.

안전한 개발 과정

  • 설계 단계의 보안: 위협 모델을 기능 설계와 함께 만듭니다. 나중에 붙이면 구조를 되돌려야 하는 경우가 많습니다.
  • 보안 요구사항: 기능 명세에 인증, 인가, 로깅 요구를 함께 적습니다. 적히지 않은 것은 구현되지 않습니다.
  • 코드 리뷰: 인가 확인, 입력 검증, 비밀 처리에 초점을 둔 항목을 정해 둡니다. 자유 리뷰만으로는 매번 다른 것을 봅니다.
  • 정적 분석: 코드에서 위험한 패턴을 자동으로 찾습니다. 오탐이 많으므로 규칙을 다듬어야 계속 쓰입니다.
  • 동적 분석: 실행 중인 애플리케이션을 밖에서 두드려 봅니다. 정적 분석이 못 보는 설정과 조합 문제를 잡습니다.
  • 의존성 검사: 빌드마다 알려진 취약점을 확인합니다. 통과 기준을 정해 두지 않으면 경고만 쌓입니다.
  • 비밀 스캔: 커밋과 이미지에 자격 증명이 들어갔는지 검사합니다. 실수는 반드시 일어나므로 자동 검사가 필요합니다.
  • 테스트에 보안 넣기: 인가 실패 케이스를 정상 케이스만큼 테스트합니다. 권한 없는 사용자가 접근했을 때를 검증하는 테스트가 대개 없습니다.
  • 침투 테스트: 전문가가 실제 공격 관점으로 확인합니다. 시점 검사이므로 지속적인 절차를 대체하지는 못합니다.
  • 취약점 공개 절차: 외부 제보를 받을 창구를 둡니다. 창구가 없으면 제보가 공개적으로 올라갑니다.
  • 보안 교육: 흔한 결함 유형을 팀이 공유합니다. 도구가 잡지 못하는 논리 결함은 사람만 발견합니다.
  • 기본 골격 제공: 안전한 방식을 기본 라이브러리와 템플릿에 넣습니다. 매번 옳게 하도록 요구하는 것보다 확실합니다.
  • 예외 관리: 지금 못 고치는 위험은 기록하고 기한과 담당을 정합니다. 조용히 넘긴 항목은 사고 때 처음 발견됩니다.

운영과 탐지

  • 자산 파악: 무엇이 돌고 있고 어디에 노출돼 있는지 목록을 유지합니다. 잊힌 서버와 옛 도메인이 실제 침입 경로가 됩니다.
  • 설정 관리: 기본 계정, 열린 포트, 디버그 모드가 남아 있는지 확인합니다. 코드보다 설정에서 나는 사고가 더 많습니다.
  • 네트워크 분리: 데이터베이스와 내부 서비스는 공개 인터넷에서 닿지 않게 둡니다. 접근 경로를 줄이는 것이 가장 값싼 방어입니다.
  • 감사 로그: 누가 언제 무엇을 했는지 남기고 변조되지 않게 보관합니다. 애플리케이션이 지울 수 있는 곳에 두면 증거가 되지 않습니다.
  • 보안 이벤트: 로그인 실패, 권한 거부, 이상 접근 패턴을 별도로 수집합니다. 일반 로그에 섞이면 발견되지 않습니다.
  • 경보 설계: 무엇을 언제 사람에게 알릴지 정합니다. 경보가 많으면 곧 무시되고, 무시되면 없는 것과 같습니다.
  • 기저율: 정상 상태를 알아야 이상을 판단할 수 있습니다. 평소 수치를 모른 채 만든 임계값은 대부분 오경보가 됩니다.
  • 탐지와 예방: 모든 것을 막을 수 없으므로 빨리 알아채는 능력에 함께 투자합니다. 침해가 몇 달간 발견되지 않는 것이 가장 큰 피해를 만듭니다.
  • 패치 주기: 얼마나 빨리 고칠지 등급별로 정합니다. 공개된 취약점은 며칠 안에 대량 스캔의 대상이 됩니다.
  • 권한 점검: 누가 무엇에 접근 가능한지 주기적으로 다시 봅니다. 권한은 늘기만 하고 줄지 않는 경향이 있습니다.
  • 백업 검증: 실제로 복구해 보지 않은 백업은 백업이 아닙니다. 랜섬웨어 대응의 실질적인 마지막 방어선입니다.
  • 사고 대응 계획: 누가 무엇을 판단하고 어떻게 알릴지 미리 정합니다. 사고 중에 절차를 만들면 시간을 다 씁니다.
  • 사후 분석: 사람이 아니라 구조를 대상으로 원인을 찾습니다. 같은 유형이 반복되면 아직 원인을 못 본 것입니다.

개념들은 기능 하나를 여는 동안 만납니다

파일 첨부 기능 하나를 추가하는 과정에도 이 지도의 거의 모든 영역이 들어옵니다.

  1. 자산과 위협을 적습니다. 첨부 파일에 어떤 정보가 담길 수 있는지에 따라 필요한 강도가 달라집니다.
  2. 인증을 확인합니다. 업로드 주소가 로그인 없이 열려 있지 않은지, 세션이 어떻게 만료되는지 봅니다.
  3. 인가를 확인합니다. 이 사용자가 바로 이 게시물에 첨부할 수 있는지, 남의 파일을 식별자만 바꿔 내려받을 수 없는지 확인합니다.
  4. 입력을 검증합니다. 파일 이름, 크기, 형식을 허용 목록으로 제한하고 경로 조작을 막습니다.
  5. 저장 위치를 정합니다. 실행 가능한 경로에 두지 않고, 원본 이름을 그대로 쓰지 않습니다.
  6. 제공 방식을 정합니다. 내려받기 응답의 콘텐츠 타입과 캐시 설정에 따라 브라우저에서 실행될 수도 있습니다.
  7. 데이터를 보호합니다. 저장 암호화와 보존 기간, 계정 삭제 시 처리까지 함께 정합니다.
  8. 남용을 억제합니다. 속도 제한과 용량 제한이 없으면 저장소와 비용이 공격 대상이 됩니다.
  9. 기록을 남깁니다. 누가 언제 무엇을 올리고 내려받았는지 남겨야 사고가 났을 때 범위를 좁힐 수 있습니다.

각 개념을 따로 배우는 이유는 기능 하나를 아홉 단계로 나눠 만들기 위해서가 아닙니다. 사고가 났을 때 원인이 인증인지, 인가인지, 입력 처리인지, 설정인지 좁혀 가기 위해서입니다. 공격이 정교했다고 적는 순간 고칠 수 있는 것이 하나도 남지 않습니다.

처음 배운다면 이 순서가 좋습니다

  • 신뢰 경계를 그려 봅니다. 지금 만드는 기능에서 데이터가 어디서 들어오는지 표시하는 것만으로 검증할 지점이 드러납니다.
  • 인가를 점검합니다. 식별자만 바꿔서 남의 자원에 접근되는지 직접 시도해 봅니다. 가장 흔하고 가장 크게 터지는 결함입니다.
  • 입력과 출력을 나눠 봅니다. 값이 어디서 데이터로 다뤄지고 어디서 명령으로 해석되는지 구분합니다.
  • 비밀이 어디 있는지 찾습니다. 저장소, 이미지, 로그, 설정 파일을 실제로 검색해 봅니다.
  • 의존성 목록을 만듭니다. 무엇을 쓰고 있는지 모르면 아무 대응도 시작할 수 없습니다.
  • 로그를 확인합니다. 사고가 났다고 가정하고 지금 로그로 무엇을 알 수 있는지 세어 봅니다.
  • 복구를 해 봅니다. 백업에서 실제로 되살려 보는 것이 마지막이자 가장 중요한 점검입니다.

이 순서가 절대적인 것은 아닙니다. 맡고 있는 서비스 하나를 붙들고 필요한 개념을 앞뒤로 오가는 편이 훨씬 오래 남습니다.

이 문서는 시리즈의 허브입니다

이후의 심화 글은 각 문서만 읽어도 이해되도록 쓰고 appsec-core-concepts 태그로 연결합니다. 새 글이 발행되면 이 허브의 관련 항목에도 직접 링크를 추가합니다. 번호대로 읽어야 하는 연재물이 아니라, 관심 있는 지점에서 들어와 전체 지도로 돌아올 수 있는 구조입니다.

먼저 확장하기 좋은 주제는 다음과 같습니다.

  • 객체 수준 인가: 식별자만 바꿔도 열리는 API
  • 세션과 토큰: 무효화할 수 없다는 제약을 다루는 법
  • 주입 공격이 한 가지 형태인 이유
  • 파일 업로드를 안전하게 받는 순서
  • 비밀 관리: 저장소 이력에 들어간 값은 되돌릴 수 없다
  • 의존성 취약점 대응을 빌드에 넣기
  • 로그에 무엇을 남기고 무엇을 남기지 않을 것인가
  • 백업 복구 훈련: 실제로 되살려 본 적 있는가

공격 기법과 도구는 계속 바뀌지만 물어야 할 질문은 크게 달라지지 않습니다. 무엇을 지키는가, 이 데이터는 어디서 왔는가, 이 요청을 보낸 사람은 이 자원에 권한이 있는가, 뚫렸을 때 어디까지 번지는가, 그리고 지금 그것을 알아챌 수 있는가. 이 다섯 질문을 기준으로 두면 처음 보는 취약점 유형도 이미 아는 개념 위에 놓고 이해할 수 있습니다.

마지막 수정:

공유하실 때는 출처(Duolabs)와 원문 주소를 표시해 주세요.