업로드 보안과 외부 스캐너
사용자 업로드 기능을 운영에 노출할 때 확인해야 할 스토리지와 악성코드 검사 기준입니다.
기본 원 칙
| 항목 | 권장 |
|---|---|
| 저장소 | Cloudflare R2 같은 S3-compatible object storage |
| 로컬 디스크 | local/testing 용도만 |
| private 파일 | 직접 URL 금지, presigned URL 사용 |
| public 파일 | 썸네일, 샘플, SEO 이미지 등 공개 가능 자산만 |
| scanner | 기본은 off, 운영 업로드는 ClamAV 선택 설치 권장 |
업로드 자산을 서버 로컬 디스크에 묶지 않으면 배포, 백업, 확장, 프로젝트 이식이 단순해집니다.
R2 설정
CONTENT_ASSET_* 값은 프로젝트 루트 .env 에 설정합니다.
CONTENT_ASSET_PRIVATE_DISK=r2-private-rw
CONTENT_ASSET_PRIVATE_READ_DISK=r2-private
CONTENT_ASSET_PUBLIC_DISK=r2-public
CONTENT_ASSET_KEY_PREFIX=assets
CONTENT_ASSET_R2_ENDPOINT=https://<ACCOUNT_ID>.r2.cloudflarestorage.com
CONTENT_ASSET_R2_REGION=auto
CONTENT_ASSET_R2_PRIVATE_BUCKET=
CONTENT_ASSET_R2_PUBLIC_BUCKET=
CONTENT_ASSET_R2_PUBLIC_URL=
CONTENT_ASSET_R2_READ_ACCESS_KEY_ID=
CONTENT_ASSET_R2_READ_SECRET_ACCESS_KEY=
CONTENT_ASSET_R2_WRITE_ACCESS_KEY_ID=
CONTENT_ASSET_R2_WRITE_SECRET_ACCESS_KEY=
read token 과 write token 을 분리하는 것을 권장합니다. 학습자/공개 조회 경로는 read disk 만 사용하고, 관리자/AI 업로드 경로만 write disk 를 사용합니다.
AssetLibrary 기본 검사
AssetLibrary 는 외부 scanner 없이도 다음 검사를 수행합니다.
- 확장자 whitelist/blocklist
- MIME 타입 검증
- 파일 signature/magic byte 검증
- 파일 크기 제한
- 원본 파일명 미사용
- HTML/JS/SVG/실행 파일 기본 차단
SVG 는 기본 차단합니다. SVG를 허용해야 하는 경우 sanitizer 가 있는 별도 경로를 사용하세요.
ClamAV 선택 설치
ClamAV 는 리눅스/서버에서 널리 쓰이는 GPLv2 malware scanning engine 입니다. multi-saas-kit 기본 배포본에는 포함하지 않고, 필요한 프로젝트에서 별도 컨테이너 또는 서비스로 설치합니다.
ASSET_LIBRARY_SCANNER=none # none | auto | clamav
ASSET_LIBRARY_CLAMAV_HOST=clamav
ASSET_LIBRARY_CLAMAV_PORT=3310
ASSET_LIBRARY_CLAMAV_TIMEOUT=10
ASSET_LIBRARY_CLAMAV_FAIL_OPEN=false
| 모드 | 동작 |
|---|---|
none | ClamAV 를 사용하지 않음 |
auto | clamd 연결 가능 시 사용, 없으면 malware scan skip |
clamav | clamd 연결 실패 또는 감염 탐지 시 업로드 차단 |
설치 후 바로 연계
ClamAV 는 애플리케이션 코드 변경 없이 clamd 서비스와 env 설정만 맞추면 AssetLibrary adapter 로 연결됩니다.
기본 배포는 가볍게 유지하고, 업로드 보안이 필요한 프로젝트만 scanner 를 추가할 수 있습니다.
외부 모듈 라이선스 원칙
GPL/AGPL/상용/라이선스 불명확 모듈은 multi-saas-kit 기본 배포본에 포함하지 않습니다. 이런 모듈은 선택 설치형 adapter, 별도 컨테이너, 별도 서비스로 분리합니다.
설치 전에는 다음을 확인합니다.
- 라이선스와 상업 배포 가능성
- 전이 의존성 라이선스
- 외부 통신 여부
- 권한 상승 시도 여부
- 시크릿 수집 여부
배포 체크리스트
- production/staging 업로드 자산은 R2/S3-compatible object storage 사용
- private/public bucket 또는 prefix 분리
- read/write token 분리
-
.env에만 bucket/credential 설정 -
ASSET_LIBRARY_SCANNER정책 결정 - 사용자 업로드 운영 노출 시 ClamAV 선택 설치 검토
- GPL/AGPL/상용 모듈은 기본 배포에 포함하지 않음