What to Decide Before Adding File Uploads to a Website or Customer Portal
The short answer
Before you add file uploads, decide four things in writing. First, why a customer must send a file at all. Second, which file types and how many you will accept for that purpose. Third, who may see each file and what happens to it after it arrives. Fourth, what the customer sees when something goes wrong. If you cannot name a clear purpose, a text description in a form may meet the task without collecting a file, and you avoid having to store, review and remove files.
This article is about commissioning: what you, the owner, should specify so a developer builds the right thing. It is not a security tutorial, and nothing here is a guarantee. Where I cite a source, I say so. The rest is practical judgment you should adapt to your own business.
1. Decide whether you need uploads
Ask what the file does for the business. A signed form, a photo of a damaged item, an artwork file for approval and a CV are different purposes with different risks. Write one sentence per purpose, such as: "Customers send a photo of the fault so we can quote without a site visit."
If a purpose is vague, such as "in case they have something to send", leave it out. Every upload field means stored files you must look after, review and eventually remove. Sometimes a written description of the problem is enough, and then no file needs to be collected at all.
2. Permitted formats, tied to a business purpose
List the formats per purpose, not one global list. The OWASP cheat sheet advises to use business critical extensions only, without allowing types the business does not require. In plain terms: if you only review PDFs, do not accept everything and hope.
For each format, state what your team will open it with. A format nobody on your team can open is a format you should not accept.
A picker hint is not a rule
Developers often add an accept setting to the upload field. MDN explains that the accept attribute does not validate the types of the selected files; it provides hints for browsers. Users can usually override it, and MDN's advice is that the requirement should be validated server side.
For your brief, this means the picker filtering the list is a courtesy to the customer, not protection for you. Ask your developer to confirm that the server enforces the rules, not only the page.
Extension and MIME checks are not enough alone
OWASP states that the declared content type is provided by the user, and as such cannot be trusted. It also warns that blocking specific extensions is a weak protection method on its own, and that checking a file's signature should not be used on its own because bypassing it is common and easy. Its overall position is that there is no silver bullet and that no one technique is enough.
What this means for you: ask for layered safeguards and an honest description of them. Be wary of anyone who says uploads are simply secure. Scanning is one layer. OWASP suggests running files through an antivirus or sandbox where available, but a scan is not a guarantee, and even rewriting an image does not guarantee that all malicious content is removed.
3. Size and count limits
Limits protect your storage and keep review manageable. OWASP says the application should set size limits in order to protect file storage capacity. Do not copy a number from a blog post, because there is no universal limit. Choose limits from your real files and your hosting.
A way to reason: look at the largest realistic file your customers would send for a given purpose, set the limit comfortably above it, then test with a deliberately oversized file. Specify both a size per file and a count per submission, and decide what message appears when either is exceeded.
4. Access roles
Decide who can upload, view, download, approve, reject and delete. OWASP says only authorized users should upload files. A useful starting point for your own brief: a customer sees only their own files, staff see files for jobs assigned to them, and one named person holds deletion rights. Adjust to your team.
5. Private versus public downloads
Most customer files should be private. Public retrievability adds risks, and OWASP names examples such as public disclosure of other files. Ask your developer how a download link is protected, whether guessing a link could expose someone else's file, and whether links expire.
OWASP also recommends that the application generate the stored filename instead of trusting the customer's. The practical consequence is that the original filename may be shown to staff but should not be what identifies the file internally.
6. Transfer, received, scanned, accepted
The most common misunderstanding in a brief is treating a finished upload as a finished job. A progress bar reaching 100 percent is browser side feedback. It does not prove the server got the file or stored it. Ask for an explicit confirmation from the server before the customer is told anything succeeded.
Specify separate states:
- Uploading: the browser is sending. No promise yet.
- Received: shown only after the server explicitly confirms it persisted the file. This does not mean the file has been checked, and I am not claiming it guarantees backups or long term durability.
- Scanned or checked: your automated safeguards have run, with a result recorded separately.
- Pending review: nobody has judged it yet.
- Accepted: a named role approved it for its purpose.
- Rejected: a role declined it, with a reason the customer can read.
Decide who is notified at each change and what the customer sees while waiting. If the connection drops before server confirmation, the status is unconfirmed, because the server may or may not have stored the file. Before a retry, the system should check for an existing upload or server record, so the customer does not create a duplicate. Where the design includes a stable submission identifier, use it to reconcile the two, and do not assume any automatic retry is guaranteed. Staff should never have to ask whether a file went through.
7. Retention and deletion
Decide how long each type of file stays and who removes it. Write the decision down as a business rule, for example "rejected files are removed after the customer has been told". I am not giving legal advice. Retention periods and customer deletion rights depend on your location and sector, so check with a qualified adviser before publishing promises on your privacy page.
Also decide how deletion treats copies held elsewhere, and whether deleted means hidden or truly gone. Do not promise more than your system does.
8. Replacing mistakes
Customers upload the wrong file. Decide whether they can replace a file before review, after rejection, or never. Decide whether the old version is kept for staff, and whether replacing resets the status to pending. Without these rules, you end up with five files named final and no idea which one was approved.
9. Mobile camera and file picker testing
Many customers will use a phone. MDN notes that with an image accept value many mobile devices also let the user take a picture with the camera. Its description of the capture attribute, which can request the front or rear camera, says that if the attribute is missing the browser is free to decide what to do, and if the requested facing mode is not available, the browser may fall back to its preferred default mode.
So do not promise that every phone will behave the same way. Put real devices on your test plan and test both paths on the devices and browsers you decide to support: taking a new photo and choosing an existing file. Also check a large photo, a cancelled picker and a dropped connection.
10. Accessibility
The upload control must be usable with a keyboard and a screen reader. MDN's example notes that hiding the file input with certain styles can make assistive technology treat it as not interactive. Ask that the button have a clear label, that file names, errors and status changes appear as text and not by colour alone, and that you test with keyboard only.
11. Failure handling
List the failures and the message for each: wrong type, too large, too many, connection lost, file unreadable, check failed, and server error. Each message should say what happened and what to do next. Also decide what staff see when a file is stuck, and who is told.
Hypothetical example: a print proof approval portal
Imagine a small print shop wants customers to upload artwork and approve proofs. A sample brief might say:
- Purpose: customers send one artwork file per order line; staff return a proof for approval.
- Formats: PDF only for artwork, with a plain explanation on the page of what to do if the customer has another format.
- Limits: a stated number of files per order and a stated size per file, chosen from the shop's real jobs and tested with an oversized file.
- Roles: customers see their own orders; designers see assigned orders; the owner can delete and approve exceptions.
- Access: all files private; no public links.
- Status: uploading, received after explicit server confirmation, checked, pending review, accepted, rejected with reason; the customer is emailed on change.
- Replacement: allowed until the proof is approved; each replacement returns the status to pending and keeps the previous version for staff.
- Retention: files removed after a period the owner sets, subject to adviser review.
- Mobile: tested on named phones, both camera and existing file paths.
- Accessibility: keyboard and screen reader test of upload, errors and status.
Acceptance checklist
Use this to write testable criteria. For more on phrasing, see how to write acceptance criteria for a small web app.
- Each upload field has a written business purpose, or a text description was chosen instead.
- Allowed formats are listed per purpose and enforced by the server.
- Size and count limits are stated and tested at and above the limit, with clear messages.
- Roles are tested using separate synthetic test accounts, never real customer accounts.
- Files are private unless a decision says otherwise.
- Received appears only after explicit server confirmation, and is separate from checking and acceptance.
- Customers can see status and rejection reasons.
- Replacement behaviour is defined and tested.
- Retention and deletion rules are written and checked with an adviser.
- Mobile tests are done on real supported devices, both camera and existing file paths, and results recorded.
- Keyboard and screen reader tests pass.
- Every failure has a readable message and a staff follow up.
- The developer has described which safeguards exist and which risks remain.
If you want help turning your answers into a brief, the work with me page explains how projects start. Nothing here is a promise of secure upload infrastructure, and a checklist cannot make a system safe by itself.
FAQ
Can I just rely on the file type setting in the upload field?
No. It guides the picker but does not validate files, and users can usually override it. The server must enforce your rules, and even then no single check is enough, so ask for several layers.
If a file passes a virus scan, is it safe to open?
Not necessarily. A scan is one layer and it can miss things. Treat accepted files carefully, open them with up to date software, and keep your review step separate from the scan result.
Do I need to let customers upload from a phone camera?
Only if your customers need it. Browsers and devices may behave differently, so do not promise camera capture. Decide which devices you support, and test both taking a photo and choosing an existing file on each.