대상: ASP.NET Core로 앱이나 API를 운영하는 사람. 여기서는 공격 절차를 다루지 않고, 프로덕션을 굳히기 위한 실무 레퍼런스(우선순위 체크리스트·영역별 대책·자기 검증)를 제시합니다. 프레임워크 전체의 관점은 프레임워크별 보안의 입구도 참조하세요.
우선순위 하드닝 체크리스트
먼저 이 표를 위에서부터 실시합니다. P0은 전제, P1이 가장 빈번한 사고원, P2는 지속적인 유지 관리입니다.
P0 ── 전제(먼저 이것)
프로덕션에서 상세 오류 비표시 / 시크릿을 외부화 / NuGet 의존성 CVE 즉시 패치
P1 ── 가장 빈번한 사고원
인가([Authorize]·기본 거부·소유자) / over-posting 대책(DTO/[Bind])
P2 ── 지속적인 유지 관리
안전하지 않은 역직렬화 / HTTPS·헤더·antiforgery / SSRF
| 우선순위 | 대책 | 구체(ASP.NET Core) |
|---|---|---|
| P0 | 프로덕션 오류 | UseExceptionHandler. Developer Exception Page/상세를 프로덕션에서 내보내지 않기(환경 판정을 올바르게) |
| P0 | 시크릿 외부화 | appsettings.json에 직접 기재하지 않기. 개발=User Secrets, 프로덕션=환경/Key Vault |
| P0 | NuGet 의존성 CVE | dotnet list package --vulnerable/osv-scanner로 모니터링·실가동 버전으로 판정해 즉시 패치 |
| P1 | 인가를 명시 | [Authorize]+기본 거부(폴백 정책)+리소스 기반/소유자 확인 |
| P1 | over-posting 대책 | 엔티티 직접 바인딩을 피하고 DTO로. [Bind]로 받아들일 필드를 한정 |
| P2 | 역직렬화 | BinaryFormatter를 쓰지 않기. 신뢰할 수 없는 데이터를 안전하지 않은 형식으로 복원하지 않기 |
| P2 | HTTPS/헤더/CSRF | UseHttpsRedirection·UseHsts·antiforgery(CSRF)·Cookie 속성 |
| P2 | SSRF | 서버 측 취득은 허용 리스트로 한정+내부 IP/메타데이터 차단 |
1. 프로덕션 오류의 노출 방지 (P0)
- 프로덕션에서는
UseExceptionHandler등으로 범용 오류로 전환하고, Developer Exception Page/상세를 내보내지 않습니다(ASPNETCORE_ENVIRONMENT=Production등의 환경 판정을 올바르게). - 스택 트레이스나 내부 구조를 외부에 내보내지 않습니다.
2. 시크릿의 외부화 (P0)
- 연결 문자열이나 키를 appsettings.json에 직접 기재하지 않습니다. 개발은 User Secrets, 프로덕션은 환경 변수나 클라우드의 시크릿 관리(Key Vault)에서 읽어 들입니다.
- appsettings.json은 실수 커밋/공개로 누출되기 쉽습니다. 리포지토리에 커밋하지 않고, 공개 디렉터리에 두지 않습니다(→ 공개 디렉터리에 시크릿을 두지 않기). 만일 누출되면 신속히 로테이션합니다.
3. NuGet 의존성의 CVE (P0)
dotnet list package --vulnerable나 osv-scanner로 알려진 CVE를 기계 모니터링하고, 실가동 버전으로 판정해 즉시 패치합니다(→ 의존성 CVE 모니터링 · 취약점 대응 실무).- .NET을 지원 대상 버전으로 유지하고, EOL 버전을 방치하지 않습니다.
4. 인가 (P1 — 가장 빈번한 사고원)
자주 하는(위험한)
- 엔드포인트에
[Authorize]를 붙이는 것을 잊음 - 인증은 있지만 소유자 확인이 없음
- 기본값이 "허용" 쪽이어서 미인증 요청이 통과
- 역할/정책 설계 없이 산발적으로 판정
올바른
[Authorize]+폴백 정책으로 기본 거부- 역할/정책 기반+리소스 기반 인가로 소유자 확인
- 취득·갱신·삭제의 모든 경로에서 확인
- 인가는 명시적으로 구성하고, 기본값에 맡기지 않기
용어는 IDOR란. 인증과 인가는 별개이며, 인가는 데이터에 가까운 곳에서 확인합니다.
5. over-posting (P1)
- 엔티티를 직접 바인딩하지 않습니다. 입력 전용 DTO에 바인딩하고, 필요한 필드만 받아들입니다.
- 또는 **
[Bind]**로 받아들일 필드를 명시적으로 한정합니다. 권한 플래그 등을 외부 입력에서 덮어쓰게 하지 않습니다.
6. 안전하지 않은 역직렬화와 입력 (P2)
BinaryFormatter를 쓰지 않습니다(비권장/위험). 신뢰할 수 없는 데이터를 안전하지 않은 형식으로 복원하지 않습니다(조건에 따라 RCE로 이어질 수 있음)(→ RCE란).- 입력은 **모델 검증(데이터 주석 등)**으로 형·범위·허용값을 검증한 뒤에 사용합니다.
7. HTTPS·헤더·antiforgery (P2)
UseHttpsRedirection+UseHsts로 HTTPS를 강제하고, Cookie를 secure/httponly/samesite로 표시합니다.- 폼/상태 변경 요청에는 **antiforgery 토큰(CSRF 대책)**을 사용합니다(→ CSRF란).
- 보안 헤더를 부여합니다(본 사이트는 보안 헤더 진단으로 확인).
8. SSRF와 서버 측 취득 (P2)
- 서버(
HttpClient등)가 사용자 지정 URL을 취득하는 처리는 허용 리스트로 대상을 한정하고, 내부 IP/메타데이터로의 도달을 차단합니다(→ SSRF란). 업로드는 검증하고 공개면 밖에 저장합니다.
검증: 내 ASP.NET Core는 정말 굳혀졌는가
만들면 끝이 아니라, 점검해야 비로소 완료입니다. 다음은 자신의 환경에 대한 방어적 자기 점검입니다.
프로덕션에서 Developer Exception Page가 나오지 않는가
시크릿이 설정/리포지토리에 없는가
appsettings.json에 연결 문자열/키가 직접 기재되지 않았는지, 리포지토리에 시크릿이 포함되지 않았는지 확인.인가가 작동하는가
의존성과 HTTPS/헤더
dotnet list package --vulnerable/osv가 클린인지, 헤더 진단으로 HTTPS/HSTS 등이 붙는지 확인.본 사이트의 관점: 안정된 프레임워크라도 설정과 인가는 자신의 책임
ASP.NET Core는 인증·인가·데이터 보호의 구조가 갖추어져 있지만, 프로덕션의 설정과 인가의 부여만은, 환경별·엔드포인트별로 자신이 올바르게 결정해야 합니다. 본 사이트는 다른 스택이지만 원칙은 같습니다 — 프로덕션에서 내부 정보를 내보내지 않고, 시크릿을 설정의 외부에 두고, 공개 엔드포인트에는 반드시 인가를 작성하고, 의존성은 CVE 모니터링한다. 프레임워크의 보안 기능은 올바른 설정과 명시적인 인가가 있어야 비로소 효과를 냅니다.
다음으로 읽기
- 입구: 프레임워크별 보안(입구) · Spring Boot 보안(같은 기업 계열·의존성/인가의 문제가 비슷하다)
- 실무: 취약점 대응 실무 · 의존성 CVE 모니터링 · 공개 디렉터리에 시크릿을 두지 않기
- 용어: IDOR란 · RCE란 · CSRF · SSRF
- 도구: 보안 헤더 진단
출처와 확인 범위
아래 1차 자료는 위의 설정·영향 범위·대응을 뒷받침하며 링크는 2026년 10월 23일 확인했습니다. 자료의 버전·구성 조건을 확인하세요. 점검 우선순위와 교훈은 이 사이트의 정리이며 글 전체의 재검증이나 안전 보증이 아닙니다.