File uploads are a common requirement in modern web applications. Users upload profile pictures, invoices, contracts, medical reports, spreadsheets, videos, and many other types of documents every day. While implementing file uploads appears straightforward, it is also one of the most common sources of security vulnerabilities.
Attackers frequently exploit insecure upload endpoints by submitting malicious files, oversized payloads, executable content, or files with spoofed extensions. Without proper validation and storage practices, a file upload endpoint can become an entry point for malware distribution, denial-of-service attacks, or even remote code execution.
In this article, you'll learn how to build secure, production-ready file upload APIs in ASP.NET Core 10 by validating uploaded files, enforcing limits, safely storing content, and following security best practices.
Understanding File Upload Risks
Why File Uploads Require Special Attention
A file upload endpoint accepts data directly from external users, making it a high-risk area of any application.
Common threats include:
Malware uploads
Executable files disguised as images
Oversized files causing resource exhaustion
Directory traversal attacks
Content type spoofing
Duplicate file names
Unauthorized file access
A secure implementation validates every uploaded file before it reaches permanent storage.
Accepting File Uploads
ASP.NET Core represents uploaded files using the IFormFile interface.
app.MapPost("/upload", async (IFormFile file) =>
{
if (file.Length == 0)
{
return Results.BadRequest("No file uploaded.");
}
return Results.Ok();
});
Why Use IFormFile?
IFormFile provides access to the uploaded file's metadata and content stream without requiring the entire file to be loaded into memory immediately.
This makes it suitable for handling uploads efficiently while allowing validation before processing.
Validate File Size
Never allow unlimited uploads.
const long MaxFileSize = 10 * 1024 * 1024;
if (file.Length > MaxFileSize)
{
return Results.BadRequest(
"File exceeds the maximum allowed size.");
}
Why Validate Size?
Large uploads consume:
Memory
CPU
Disk space
Network bandwidth
Restricting upload size helps prevent resource exhaustion and improves application stability.
Validate File Extensions
Only allow expected file types.
var allowedExtensions = new[]
{
".jpg",
".jpeg",
".png",
".pdf"
};
var extension =
Path.GetExtension(file.FileName)
.ToLowerInvariant();
if (!allowedExtensions.Contains(extension))
{
return Results.BadRequest(
"Unsupported file type.");
}
Why Validate Extensions?
Extension validation blocks many accidental or malicious uploads.
However, file extensions alone should never be trusted because attackers can easily rename executable files.
Extension validation should always be combined with additional verification.
Validate Content Type
Inspect the uploaded MIME type.
var allowedTypes = new[]
{
"image/jpeg",
"image/png",
"application/pdf"
};
if (!allowedTypes.Contains(file.ContentType))
{
return Results.BadRequest(
"Invalid content type.");
}
Why Check MIME Types?
Checking the content type provides another layer of validation.
Although MIME types can also be spoofed, combining multiple validation techniques significantly reduces risk.
Generate Safe File Names
Never store files using the original file name.
var fileName =
$"{Guid.NewGuid()}{extension}";
Why Generate New Names?
Original file names may contain:
Duplicate names
Unsupported characters
Sensitive information
Path traversal sequences
Generating unique names avoids collisions while preventing users from influencing server-side file paths.
Save Files Securely
Store uploads outside the web root whenever possible.
var uploads =
Path.Combine(
builder.Environment.ContentRootPath,
"Uploads");
Directory.CreateDirectory(uploads);
var path =
Path.Combine(uploads, fileName);
await using var stream =
File.Create(path);
await file.CopyToAsync(stream);
Why Store Outside the Web Root?
Files stored outside wwwroot cannot be downloaded directly through a browser.
Instead, applications should authorize every download request before returning the file.
This prevents unauthorized access to sensitive documents.
End-to-End Implementation
Consider a document management application.
Architecture:
Employee
│
▼
Upload API
│
File Validation
│
Virus Scanning
│
Secure Storage
│
Metadata Database
Workflow:

Join the conversation! Your thoughts help the community grow.