보안 감사 체크리스트
프로덕션에 배포하기 전 또는 주요 변경 후 시스템에서 이러한 검사를 실행하세요.
시작하기 전에
체크리스트 자체는 일반 텍스트이며 별도 도구가 필요하지 않습니다. scripts/ 디렉토리 아래 세 개의 스캐너는 Python으로 작성되어 있으므로, 실행하려면 머신에 Python 3가 필요합니다(python3 --version). Python 3이 없어도 체크리스트를 수동으로 작업할 수 있습니다. 자동화된 비밀 스캔, 헤더 확인, IaC 읽기 기능만 사용할 수 없을 뿐입니다.
1. 개인정보 보호 및 데이터 거버넌스
- 개인정보 처리방침 존재: 앱이 사용자 데이터를 수집, 저장 또는 처리하는 경우. 푸터와 가입 흐름에 링크.
- 사용자 데이터 저장 위치 파악: 기본 데이터베이스, 캐시, 로그, 백업, 타사 서비스 문서화. 데이터 거주 요구 사항(GDPR, CCPA) 확인.
- 데이터 최소화: 필요한 데이터만 수집. 사용하지 않는 데이터는 삭제하거나 익명화.
2. 비밀 및 키 위생
- .env 값이 유출되지 않음: 전체 저장소에서 하드코딩된 비밀 검색.
- 프론트엔드 코드에 API 키 노출 금지: JS 번들에 키 없음, 공개 env 접두사(
REACT_APP_,NEXT_PUBLIC_,VITE_)에 민감 값 없음. - 키를 서버 측 또는 프록시 뒤로 이동: 비밀을 필요로 하는 모든 타사 API 호출은 백엔드 엔드포인트를 통해야 함.
- 로그에서 비밀 제거: 로그와 오류 보고자에서 키, 토큰, 비밀번호 그렙. 출력 전 마스킹 또는 삭제.
- 유출된 자격 증명 즉시 교체: 발견 시.
빠른 스캔 명령어:
# 번들된 비밀 스캐너 실행
python3 scripts/scan_secrets.py .
# 수동 ripgrep 패턴
grep -rE '(api[_-]?key|secret|token|password)\s*[:=]\s*["\047][a-zA-Z0-9_\-]{16,}' --include='*.{js,ts,py,go,rb,php,java,json,yaml,yml,env,sh,tf,hcl}' .
grep -rE 'AKIA[0-9A-Z]{16}' . # AWS 키
grep -rE 'ghp_[a-zA-Z0-9]{36}' . # GitHub 토큰
grep -rE 'sk-[a-zA-Z0-9]{48}' . # OpenAI 키
3. 보안 헤더
-
Content-Security-Policy가 스크립트 소스를 제한하고 가능한 경우 인라인 실행 차단. -
X-Frame-Options또는frame-ancestors가 클릭재킹 방지. -
Strict-Transport-Security가 HTTPS 강제. -
X-Content-Type-Options: nosniff가 존재. -
Referrer-Policy가 리퍼러 누출 제한.
라이브 URL에서 헤더 확인:
python3 scripts/check_headers.py https://your-app.com
4. OWASP Top 10 기본 사항
| # | 위험 | 확인 사항 |
|---|---|---|
| A01 | 취약한 접근 통제 | 모든 엔드포인트가 인증 및 권한 부여 확인. IDOR 버그 없음. |
| A02 | 암호화 실패 | 비밀번호는 bcrypt/Argon2로 해싱. TLS 1.2+ 강제. URL에 민감 데이터 없음. |
| A03 | 인젝션 | SQL은 매개변수화된 명령문 사용. 쿼리에 원시 문자열 연결 없음. |
| A04 | 안전하지 않은 설계 | 인증 및 민감 작업에 속도 제한. 비즈니스 로직에 남용 확인. |
| A05 | 보안 설정 오류 | 기본 자격 증명 제거. 프로덕션에서 디버그 모드 끔. 오류 메시지에 스택 트레이스 누출 없음. |
| A06 | 취약한 구성 요소 | 종속성 감사: npm audit, pip-audit, cargo audit, snyk test. |
| A07 | 인증 실패 | 세션 토큰은 무작위이며 권한 변경 시 교체. 민감 계정에 MFA. |
| A08 | 데이터 무결성 | 잠금 파일 존재, 가능한 경우 서명된 커밋. |
| A09 | 로깅 실패 | 보안 이벤트가 비밀 없이 기록. |
| A10 | SSRF | 서버 측 요청이 허용 목록 사용. 사용자 제어 URL이 내부 서비스에 도달하지 않음. |
5. 입력 검증 및 인젝션
- SQL 인젝션: 모든 쿼리가 ORM 매개변수 또는 준비된 명령문 사용.
- XSS: 사용자 출력이 HTML 이스케이프 처리.
dangerouslySetInnerHTML및 유사 우회 코드 감사. - 명령 인젝션: 사용자 입력으로
exec(),system()또는eval()없음. - 경로 탐색: 파일 경로가 정리되고 허용 목록 디렉토리로 제한.
- NoSQL 인젝션: MongoDB 쿼리가 매개변수화된 객체 사용.
6. API 보안
- API 응답에 민감 데이터 확인: 내부 ID, 비밀번호 해시, 토큰 또는 불필요한 PII 없음.
- 모든 비공개 엔드포인트에 인증: 열린 관리자 또는 디버그 경로 없음.
- 누군가 API 비용을 태우기 전에 속도 제한: 비용이 많이 드는 엔드포인트나 인증 엔드포인트에 IP 및 사용자별 속도 제한.
429와Retry-After반환. - CORS는 엄격히:
Access-Control-Allow-Origin이*아님. 상태 변경 메서드에 사전 요청 필요.
7. 인증 및 세션
- 비밀번호 정책: 최소 8자, 암호를 방해하는 최대 길이 없음.
- 무차별 대입 공격 방지: 실패한 로그인 후 지수 백오프 또는 CAPTCHA.
- 세션 관리: 안전한 httpOnly, SameSite 쿠키. JWT는 짧은 만료와 갱신 교체.
- 비밀번호 재설정: 토큰은 일회용, 무작위이며 빠르게 만료.
8. 클라우드 제공업체 보안
AWS, GCP, Azure 및 기타 모든 클라우드 플랫폼에 적용됩니다.
8.1 아이덴티티 및 접근 관리 (IAM)
- 루트 계정 액세스 키 없음 존재. 루트 MFA 활성화.
- 최소 권한 원칙: 모든 역할, 사용자, 서비스 계정이 필요한 최소 권한만 보유. 절대적으로 필요하지 않은 경우 와일드카드(
*) 작업 또는 리소스 없음. - 장기 액세스 키 없음 사용자용. 임시 자격 증명(STS, 인스턴스 프로필, 워크로드 아이덴티티)이 있는 IAM 역할 선호.
- MFA 강제 모든 인간 사용자, 특히 관리자 및 결제 접근.
- 비활성 아이덴티티 제거: 90일 이상 사용되지 않은 사용자, 역할, 서비스 계정 삭제 또는 비활성화.
- 교차 계정 접근은 가능한 경우 외부 ID가 있는 명시적 역할 가정 사용.
Principal: *인 신뢰 정책 없음.
8.2 스토리지 (S3 / GCS / Azure Blob)
- 공개 버킷/컨테이너 없음 의도적으로 공개 정적 자산을 호스팅하지 않는 한. 계정 수준에서 공개 접근 차단.
- 미사용 데이터 암호화 활성화 (AES-256 또는 KMS). 암호화되지 않은 스토리지 볼륨 또는 스냅샷 없음.
- 전송 중 암호화 강제 (HTTPS/TLS만).
http허용 안 함. - 수명 주기 정책이 오래된 데이터를 삭제 또는 전환. 중요 버킷에 버전 관리 활성화.
- 버킷 정책이
Principal: *또는AllUsers를 부여하지 않음. 하드코딩된 키가 아닌 IAM 역할을 통한 접근. - 로깅 활성화 접근 로그 및 객체 수준 이벤트 (S3 서버 접근 로그, CloudTrail 데이터 이벤트).
8.3 컴퓨팅 (EC2 / GCE / Azure VM / Lambda / Cloud Run)
- 민감 포트(22, 3389, 3306, 5432, 6379, 27017)에 0.0.0.0/0을 허용하는 기본 보안 그룹 없음.
- SSM / Session Manager 사용 가능한 경우 직접 SSH 대신 사용. 포트 22가 인터넷에 열려 있지 않음.
- AWS EC2에서 IMDSv2 필수 (IMDSv1 비활성화).
- 인스턴스 메타데이터가 컨테이너 또는 신뢰할 수 없는 코드에 노출되지 않음.
- 함수 런타임이 최소 권한 사용. Lambda/GCP Cloud Functions가 관리자 역할로 실행되지 않음.
- 함수 환경 변수에 일반 텍스트 비밀 미포함. 비밀 관리자(AWS Secrets Manager, GCP Secret Manager, Azure Key Vault) 사용.
8.4 데이터베이스 및 캐시
- 공개 접근 없음: 데이터베이스가 프라이빗 서브넷 또는 VPC에 있음. 보안 그룹에
0.0.0.0/0없음. - 미사용 및 전송 중 암호화 활성화.
- 자동 백업 시점 복구 가능.
- 강력한 인증: 기본 비밀번호 없음. 지원되는 경우 IAM 데이터베이스 인증 또는 TLS 클라이언트 인증서 사용.
- 감사 로깅 활성화 연결 및 스키마 변경.
8.5 네트워킹
- VPC / 네트워크 세분화: 프로덕션, 스테이징, 개발이 별도 네트워크 또는 최소한 별도 서브넷에 있음.
- 보안 그룹 / 방화벽이 기본 거부. 필요한 포트만 열림.
- 지나치게 허용적인 CIDR 없음:
0.0.0.0/0은 공용 로드 밸런서의 HTTPS(443)를 제외하고 피함. - 프라이빗 서브넷 데이터베이스, 캐시, 내부 서비스용. 아웃바운드 인터넷용 NAT 게이트웨이 또는 VPC 엔드포인트.
- DDoS 보호 적용 가능한 곳에 활성화 (AWS Shield, Cloud Armor, Azure DDoS Protection).
- DNS / 도메인: 레지스트라가 지원하는 경우 DNSSEC 활성화. 만료된 IP 또는 삭제된 리소스를 가리키는 매달린 DNS 레코드 없음 (서브도메인 탈취 위험).
8.6 로깅, 모니터링 및 알림
- CloudTrail / Audit Logs / Activity Logs 모든 리전 및 서비스에서 활성화.
- 로그 무결성: 로그는 불변이거나 일회성 쓰기 권한이 있는 별도 계정에 저장.
- 민감 데이터가 로깅되지 않음: 클라우드 로그에 비밀번호, 토큰 또는 PII 미포함.
- 알림 구성 루트 로그인, IAM 정책 변경, 공개 버킷 생성, 보안 그룹 변경, 실패한 인증 급증.
- 로그 보존 규정 준수 요구 사항 충족 (일반적으로 1년).
9. 컨테이너 및 오케스트레이션 보안
9.1 Docker / 컨테이너 이미지
- 이미지에 비밀 없음: Dockerfile 및 레이어에서
.env,config.json또는 하드코딩된 자격 증명 검색. - 최소 기본 이미지: 가능한 경우 전체 Ubuntu/Debian 대신 distroless, Alpine 또는 scratch 사용.
- 루트로 실행되지 않음: Dockerfile이
USER를 비루트 UID/GID로 설정. - 이미지 스캔: 레지스트리(ECR, GCR, ACR, Docker Hub)에서 취약점 스캔 활성화 및 CI에서 중요 CVE 차단.
- 불변 태그: 프로덕션에서
latest사용 금지. 다이제스트 또는 특정 semver로 고정. - 멀티 스테이지 빌드: 빌드 아티팩트 및 개발 종속성이 최종 이미지에 포함되지 않음.
9.2 Kubernetes
- RBAC: 최소 권한 역할 및 역할 바인딩. 서비스 계정에 cluster-admin 없음.
- 기본 서비스 계정 토큰이 필요하지 않은 파드에 마운트되지 않음 (
automountServiceAccountToken: false). - 네트워크 정책: 기본 거부 인그레스/이그레스, 그런 다음 필요한 트래픽만 명시적 허용.
- 파드 보안 표준:
restricted또는baseline프로필 적용. 권한 있는 컨테이너, hostPath, hostNetwork 없음. - 시크릿 암호화: etcd 미사용 데이터 암호화 활성화. Git에 일반 텍스트 시크릿 없음.
- 컨테이너 런타임 보안: seccomp, AppArmor 또는 SELinux 프로필 적용.
- 승인 컨트롤러: OPA/Gatekeeper 또는 Kyverno를 사용하여 정책 시행 (최신 태그 금지, 필수 레이블, 리소스 제한).
- 리소스 제한: 모든 파드에 CPU 및 메모리 제한이 있어 리소스 소진을 통한 DoS 방지.
10. Infrastructure as Code (IaC)
- Terraform / CloudFormation / Pulumi / CDK에 비밀 없음: 상태 파일에 일반 텍스트 비밀번호 또는 키 미포함. 원격 상태는 암호화되고 접근 제어됨.
- Terraform 상태 백엔드가 안전함: SSE-KMS가 있는 S3, DynamoDB 잠금, 공개 읽기 접근 없음.
- IaC 스캔: 병합 전에 Terraform/CloudFormation에서
checkov,tfsec또는terrascan실행. - 드리프트 감지: 예약된 스캔이 IaC에서 벗어난 수동 콘솔 변경 감지.
- 모듈이 버전 고정됨: 브랜치 또는 버전이 없는 소스에서 모듈을 가져오지 않음.
빠른 IaC 스캔:
python3 scripts/scan_iac.py .
# 또는 설치된 전용 도구 사용:
checkov -d . --framework terraform,cloudformation,dockerfile
# tfsec .
11. CI/CD 파이프라인 보안
- 파이프라인 구성에 비밀 없음:
.github/workflows,.gitlab-ci.yml, Azure Pipelines 또는 Jenkinsfiles에 하드코딩된 토큰 없음. - 비밀은 주입 CI 플랫폼의 네이티브 비밀 관리자(GitHub Secrets, GitLab CI Variables, Azure DevOps Library)에서.
- 파이프라인 권한이 최소: CI 서비스 계정에는 배포에 필요한 권한만 있음.
- 브랜치 보호: main/master로의 직접 푸시 차단. 모든 변경 사항에 PR/MR + 리뷰 필요.
- 서명된 커밋 또는 병합 요구 사항: 민감 저장소에 대해 서명된 커밋 또는 적어도 확인된 병합 커밋 필요.
- 종속성 스캔: 모든 PR에서 SCA 도구(Snyk, Dependabot, Renovate) 실행.
- SAST: 모든 PR에서 정적 분석(Semgrep, CodeQL, SonarQube) 실행.
- 컨테이너 스캔: 배포 전에 이미지에서 CVE 스캔.
- 셀프 호스팅 러너가 VPN 또는 IP 허용 목록 없이 공개 인터넷에 노출되지 않음.
- 파이프라인이 수동 승인 없이 포크의 신뢰할 수 없는 코드를 실행하지 않음 (pwn 요청 방지).
12. 도메인 및 DNS 보안
- DNSSEC 레지스트라가 지원하는 경우 활성화.
- 만료된 서비스를 가리키는 매달린 CNAME / A / NS 레코드 없음 (서브도메인 탈취 위험).
- 와일드카드 인증서 또는 신뢰할 수 있는 CA의 주제별 인증서. 프로덕션에서 자체 서명 인증서 없음.
- 인증서 만료 모니터링: 만료 30일 및 7일 전 알림.
- CDN / WAF 적절한 규칙(SQLi, XSS, LFI 차단)으로 구성. 에지에서 속도 제한 활성화.
감사 출력
체크리스트를 실행한 후 다음을 포함하는 간결한 마크다운 보고서를 생성합니다:
- 요약 — 카테고리별 통과 / 실패 / 검토 필요.
- 중요 발견 사항 — 프로덕션 전에 반드시 수정해야 할 사항.
- 권장 수정 사항 — 특정 코드 변경, 구성 업데이트 또는 라이브러리 업그레이드.
- 위험 매트릭스 — 각 발견 사항에 대한 가능성 × 영향.
- 수정 일정 — 우선 순위 및 기한 제안.