설명
업로드된 파일을 검증하지 않거나 업로드된 바이트를 HTML로 제공하면 공격자가 스크립트가 포함된 파일을 업로드해 실행시킬 수 있습니다.
잠재적 영향
- 저장형 XSS, 악성 파일 배포, 콘텐츠 타입 혼동이 발생할 수 있습니다.
해결 방법
파일 크기, 확장자, MIME 타입, 저장 위치를 검증하고 업로드 파일은 안전한 콘텐츠 타입으로 제공합니다.
예시
변경 전
csharp
using Microsoft.AspNetCore.Mvc;
public sealed class UploadController : Controller
{
public IActionResult View(string id)
{
var fileBytes = System.IO.File.ReadAllBytes("/tmp/uploads/" + id);
return File(fileBytes, "text/html");
}
}
변경 후
csharp
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.IO;
using System.Threading.Tasks;
public sealed class UploadController : Controller
{
public async Task<IActionResult> Upload([FromForm] IFormFile file)
{
if (file.Length is <= 0 or > 1_048_576) return BadRequest();
if (!string.Equals(
Path.GetExtension(file.FileName), ".txt",
StringComparison.OrdinalIgnoreCase)) return BadRequest();
// 이 경로와 상위 디렉터리는 서비스만 쓸 수 있어야 합니다.
var uploadRoot = Path.GetFullPath("/var/lib/app/uploads");
Directory.CreateDirectory(uploadRoot);
var storedName = $"{Guid.NewGuid():N}.txt";
var destination = Path.Combine(uploadRoot, storedName);
await using var output = new FileStream(
destination, FileMode.CreateNew, FileAccess.Write, FileShare.None);
await file.CopyToAsync(output);
return Accepted(new { id = storedName });
}
}
설명:
- 변경 전: 업로드된 파일을 검증 없이 저장한 뒤 HTML로 제공하면 업로드된 스크립트가 브라우저에서 실행될 수 있습니다.
- 변경 후: 크기와 허용 확장자를 제한하고, 클라이언트 파일명 대신 서버가 생성한 이름으로 웹 루트 밖에 새 파일만 만듭니다. 실제 서비스에서는 파일 형식의 내용 기반 검증과 악성 코드 검사도 추가하고, 다운로드할 때 실행 가능한 HTML MIME 타입으로 제공하지 않아야 합니다.