A. Security & Data Safety · Prompt 6
File Upload Safety Test
Get the free PDFWhy it matters
An upload can store malware, fill storage, or overwrite a file if the server trusts the browser's file name and type.
Modeled on
The OWASP File Upload Cheat Sheet.
How to run this prompt
- Switch to a mode that does not edit files. In Cursor that is Ask or Plan. In Claude Code that is Plan mode.
- Paste the audit prompt. Wait for the report. It must stop and ask which IDs to fix.
- Read the report. Keep the IDs you agree with.
- Switch to a mode that can edit. Paste the fix prompt and the IDs you chose.
- Switch back to the read-only mode and paste the same audit prompt again. Confirm those IDs are gone.
- Cursor: audit in Ask mode or Plan mode. Fix in Agent mode.
- Claude Code: audit in Plan mode (Shift+Tab cycles to it). Fix in Normal mode, which can edit.
- Any other tool: audit in Chat, Discuss, or Plan mode, whichever answers without editing files. If the tool has no such mode, the prompt itself forbids edits. Fix in the mode that is allowed to edit files.
The audit prompt
MODE: AUDIT ONLY. Do not create, edit, or delete any file. Do not run commands
that change anything: no installs, migrations, git commits, deploys, or "--fix" flags.
If your tool has an Ask, Plan, Chat, or Discuss mode, use it for this prompt.
Before you start:
- Tell me the stack you detect (framework, language, database, auth, hosting,
payment provider) and which folders you will review.
- If a check below does not apply to this stack, write "Not applicable" and why.
- If you can run read-only commands, run the ones listed. If you cannot, list them
so I can run them and paste the output.
File Upload Safety Test: what to check
Review every upload path as if a hostile user will use it. Do not upload files to a production bucket in this pass.
1. List every upload endpoint or component, where bytes are stored (disk, object storage, database), and who can read them afterwards.
2. Say whether the server checks type from content or a signature, not only the extension or the browser-supplied MIME type, and whether the allowlist is explicit.
3. Say whether size, file count, and image dimensions are limited on the server, and whether the upload is streamed or buffered so one huge body can exhaust memory.
4. Say whether the stored name is a server-generated id. A client-supplied name can traverse paths or overwrite an existing object.
5. Say whether files are stored outside the web root or in a separate bucket, are never executed, and are served with a content type that does not sniff as HTML.
6. Say whether one user can fetch another's file by changing an id, and whether private files use a signed URL that expires.
7. Note SVG uploads (they can contain script), EXIF location data on photos, and image or PDF libraries pinned to an old version.
8. Say whether there is a per-user upload rate limit and a way to delete orphaned files. If you cannot see the limiter's store, mark it Needs manual check.
9. Write a test plan I can run on a staging bucket only: a renamed executable, an oversized file, an SVG with a script tag, and a name containing ../. Say what the code would do with each.
Evidence rules:
- Every finding cites a file path and line number, or the exact command output used.
- Mark each finding Confirmed (seen in the code) or Needs manual check (depends on
something outside the repo, such as a dashboard setting or production data).
- Never print a full secret. Show the first 4 characters and the location only.
- If you are not sure, say so. Do not invent files, settings, or results.
Severity: Critical = exploitable now, or leaks real data or money. High = serious
with little effort. Medium = weakens defenses or needs a second bug. Low = hygiene.
Report:
- Summary: count of findings by severity.
- Table: ID | Severity | Confirmed? | Finding | Evidence | Why it matters | Suggested fix | Effort
(IDs for this prompt use the prefix P06, for example P06-1, P06-2.)
- Checked and fine: what you verified is already OK.
- Could not check: what I need to look at myself, and where.
Then stop. Do not fix anything. Ask me which IDs I want fixed.