사이드 프로젝트 보안 감사를 진행했습니다 — 발견한 내용들
최근에 제 모든 사이드 프로젝트를 보안 감사했습니다. FastAPI 백엔드, Telegram 봇, 그리고 웹 앱들을 점검했습니다. 저는 제가 꼼꼼하다고 생각했습니다.
제 착각이었습니다.
실제로 프로덕션 환경에 배포했던 진짜 버그들을 발견했습니다. 이것들은 이론적인 문제가 아닙니다. 빠르게 개발하려다 저지른 실수들입니다.
발견한 주요 문제점들과 해결 방법은 다음과 같습니다:
- 조건부 인증 (Conditional Authentication) 비밀 키(secret)가 존재할 때만 API 키를 확인하도록 코드를 작성했습니다. 만약 환경 변수에 비밀 키를 설정하는 것을 잊었다면, 확인 절차 자체가 통째로 건너뛰어집니다. 이로 인해 제 API가 모든 사람에게 노출되었습니다.
- 해결책: 인증을 조건부로 만들지 마세요. 비밀 키가 없다면 앱은 에러를 발생시키고 중단되어야 합니다.
- Git 히스토리에 키 유출 (Leaking Keys in Git History)
Git 히스토리에서 오래된 API 키들을 발견했습니다. 나중에
.env파일로 옮기긴 했지만, Git은 코드의 모든 이전 버전을 영구적으로 보관합니다.
- 해결책: Git에 한 번이라도 커밋된 키는 모두 유출된 것으로 간주하세요. 즉시 폐기(Revoke)해야 합니다.
git-filter-repo와 같은 도구를 사용하여 히스토리를 정리하세요.
- 남겨진 디버그 엔드포인트 (Leftover Debug Endpoints) 프로덕션 환경에 데이터베이스 설정과 시스템 설정을 보여주는 엔드포인트를 남겨두었습니다. 개발 중에는 유용하지만, 실제 환경에서는 매우 위험합니다.
- 해결책: 배포 체크리스트에 디버그 엔드포인트 제거 항목을 추가하세요.
- 상세한 에러 메시지 (Verbose Error Messages) 사용자에게 가공되지 않은 시스템 에러를 그대로 반환하고 있었습니다. 이러한 에러는 파일 경로, 데이터베이스 유형, 라이브러리 버전 등을 드러냅니다. 공격자는 이 데이터를 이용해 시스템을 타겟팅할 수 있습니다.
- 해결책: 전체 에러는 내부 로그에 기록하여 관리하세요. 클라이언트에게는 일반적인 "Internal Server Error" 메시지만 반환하세요.
- innerHTML을 통한 XSS (XSS via innerHTML)
프론트엔드에서 사용자 데이터를 렌더링할 때
innerHTML을 사용했습니다. 이는 공격자가 사이트에 스크립트를 주입할 수 있게 합니다.
- 해결책: 항상 데이터를 정제(sanitize)하거나
innerHTML대신textContent를 사용하세요.
- 속도 제한(Rate Limiting) 부족 비용이 많이 드는 AI 모델을 호출하는 엔드포인트에 제한이 없었습니다. 한 명의 사용자가 몇 분 만에 엄청난 비용을 발생시킬 수 있는 상태였습니다.
- 해결책: 인증(Authentication)은 권한이 없는 사용자를 막아줍니다. 속도 제한(Rate Limiting)은 권한이 있는 사용자가 시스템을 남용하는 것을 막아줍니다. 두 가지 모두 필요합니다.
- 허용 범위가 넓은 CORS 설정 (Permissive CORS Settings)
미들웨어에서
allow_origins=["*"]를 사용했습니다. 이는 어떤 웹사이트든 제 API에 요청을 보낼 수 있게 합니다.
- 해결책: 프로덕션 환경에서는 특정 도메인만 허용하세요.
- 파일 유출 임시 파일을 생성하는 코드를 작성했지만, 프로세스가 충돌할 경우 이를 삭제하지 못했습니다. 이 파일들은 서버에 영원히 남게 됩니다.
- 해결책:
try-finally블록을 사용하여 오류가 발생하더라도 파일이 반드시 삭제되도록 하세요.
보안 문제는 의도적인 경우가 거의 없습니다. "나중에 고치면 돼"라고 말하는 습관의 결과일 뿐입니다. 하지만 그 '나중'은 결코 오지 않습니다.
첫날부터 워크플로우에 보안을 내재화하세요. 커밋하기 전과 배포하기 전에 코드를 점검하세요.
출처: https://dev.to/justjinoit/i-audited-my-own-side-projects-for-security-issues-heres-what-i-found-1ahb