Back to scan results
Check 34 of 45

File Upload Security

We perform a read-only review of public upload forms, likely endpoints, method metadata, and common storage directories. No file, multipart body, filename payload, or test artifact is ever submitted.

What this check probes

The scanner inspects the public landing page and a small set of common upload paths for HTML file inputs. It records the destination, transport, form method, multipart encoding, recognizable anti-CSRF field, client file-type hint, multiple-file flag, size metadata, and any editable filename, path, folder, or destination control.

For same-origin HTTPS actions, an empty OPTIONS request may inspect Allow, Accept-Post, and explicit upload-size headers. Common storage paths are fetched with GET only and checked for directory indexes or listed active-content extensions.

A visible upload form produces a warning because HTML cannot prove server-side authentication, authorization, extension and magic-byte validation, size enforcement, malware scanning, filename replacement, storage isolation, or execution prevention. Missing accept metadata is noted as a client-side hint only and is not treated as proof of missing server validation.

The check never sends POST or PUT, never uploads a text or executable file, never uses a traversal filename, never sends an oversized body, and never opens or executes a listed file. Authenticated, script-generated, mobile/API-only, and unlinked upload workflows remain outside this scan.

Why this matters for PCI DSS

An unrestricted upload can introduce web shells, malware, stored cross-site scripting, parser exploits, oversized-file denial of service, or files that overwrite trusted content. Publicly listed uploads can also expose customer documents and personal data.

PCI DSS secure-development and access-control requirements expect untrusted files to be authenticated, authorized, validated, isolated, scanned, and served safely. A pass here means no public upload surface was discovered by this read-only scan; it does not certify authenticated upload workflows.

How to fix it

Validate on the server and store outside the web root. This outline uses APIs available in .NET Framework 4.7.2 and 4.8:

HttpPostedFile file = upload.PostedFile;
const int MaxBytes = 5 * 1024 * 1024;

if (file == null || file.ContentLength <= 0 || file.ContentLength > MaxBytes)
    throw new HttpException(400, "Invalid file size.");

string extension = Path.GetExtension(file.FileName).ToLowerInvariant();
var allowed = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
    ".jpg", ".jpeg", ".png", ".pdf"
};
if (!allowed.Contains(extension))
    throw new HttpException(400, "File type is not allowed.");

// Read and verify the format's magic bytes before saving.
string storedName = Guid.NewGuid().ToString("N") + extension;
file.SaveAs(Path.Combine(storageRootOutsideWeb, storedName));

Do not trust Content-Type, the browser's accept attribute, or the original extension by itself. Verify the file signature, fully decode and re-encode images where practical, reject polyglots and archives unless required, and scan accepted content for malware before release.

Generate the stored name server-side and keep the original name only as encoded metadata. Enforce both ASP.NET httpRuntime maxRequestLength and IIS request-filtering maxAllowedContentLength, plus per-user quotas, request timeouts, rate limits, and limits inside archive or document processors.

Require authentication, object-level authorization, and anti-CSRF protection. Serve files through an authorization handler with Content-Disposition: attachment and X-Content-Type-Options: nosniff. If files must be web-accessible, place them on a separate non-executable origin and explicitly disable script handlers, directory browsing, and content sniffing.

Fixed it? Re-run the scan to confirm.

Run scan again