File Upload Risk Calculator
Weight the ten controls that stop a malicious upload becoming a web shell and get a coverage score plus the residual risk.
Inputs
Weight 16
Weight 14
Weight 16
Weight 12
Weight 12
Weight 8
Weight 8
Weight 6
Weight 5
Weight 3
Control Coverage
72%
Control Grade
C — Fair
Residual Risk Score
2.52/ 9
Residual Risk Level
Low
Web Shell Path
Closed — no upload lands on an executable path
Next Control to Add
Add anti-malware scanning before files are released
Step by step
Values used
Extension and MIME allow-list (not a deny-list) = Yes; Content sniffed and matched against the declared type = Yes; Stored outside the web root or in object storage = Yes; Execution disabled on the storage path = Yes; Anti-malware or sandbox scan before release = No; Server-generated random filename = Yes; Images re-encoded and metadata stripped = No; Size and decompression limits enforced = Yes; Content-Disposition attachment with a fixed Content-Type on download = No; Downloads served through short-lived signed URLs = No; Who can upload = Anonymous visitors — 9
File Upload Risk
coverage = Σ(weight of each implemented control), weights 16 allow-list, 16 off-webroot, 14 content sniffing, 12 no-execute, 12 malware scan, 8 rename, 8 re-encode, 6 size limits, 5 Content-Disposition, 3 signed URLs = 100.
Residual risk
residual risk = (100 − coverage) × uploader trust ÷ 100, on the OWASP 0–9 scale.
Control Coverage
= 72
Control Grade
= C — Fair
Residual Risk Score
= 2.52 / 9
Residual Risk Level
= Low
Web Shell Path
= Closed — no upload lands on an executable path
Next Control to Add
= Add anti-malware scanning before files are released
How it works
The four controls that decide whether an upload can ever execute — allow-list, content sniffing, storage outside the web root and no-execute permissions — carry 58 of the 100 points between them. Residual risk scales what is missing by who is allowed to upload, so an anonymous form with weak controls lands in the high band. An upload endpoint is the shortest path from anonymous request to code execution on your server, and the controls are cheap — the usual failure is a deny-list of extensions and nothing else.
Formulas
File Upload Risk
coverage = Σ(weight of each implemented control), weights 16 allow-list, 16 off-webroot, 14 content sniffing, 12 no-execute, 12 malware scan, 8 rename, 8 re-encode, 6 size limits, 5 Content-Disposition, 3 signed URLs = 100.
- coverage
- Weighted percentage of controls implemented
- residual
- 100 − coverage
Residual risk
residual risk = (100 − coverage) × uploader trust ÷ 100, on the OWASP 0–9 scale.
- uploader trust
- 2 administrators … 9 anonymous visitors
Frequently Asked Questions
How is File Upload Risk calculated?
coverage = Σ(weight of each implemented control), weights 16 allow-list, 16 off-webroot, 14 content sniffing, 12 no-execute, 12 malware scan, 8 rename, 8 re-encode, 6 size limits, 5 Content-Disposition, 3 signed URLs = 100. The four controls that decide whether an upload can ever execute — allow-list, content sniffing, storage outside the web root and no-execute permissions — carry 58 of the 100 points between them. Residual risk scales what is missing by who is allowed to upload, so an anonymous form with weak controls lands in the high band.
Why does File Upload Risk matter?
An upload endpoint is the shortest path from anonymous request to code execution on your server, and the controls are cheap — the usual failure is a deny-list of extensions and nothing else.
What values do I need to enter?
This calculator takes 11 inputs: Extension and MIME allow-list (not a deny-list), Content sniffed and matched against the declared type, Stored outside the web root or in object storage, Execution disabled on the storage path, Anti-malware or sandbox scan before release, Server-generated random filename, Images re-encoded and metadata stripped, Size and decompression limits enforced, Content-Disposition attachment with a fixed Content-Type on download, Downloads served through short-lived signed URLs, Who can upload. The pre-filled defaults are a realistic starting point — replace them with figures from your own environment for a result you can act on.
Is checking the extension and Content-Type enough?
No. Both are attacker-controlled, and a deny-list will miss .phtml, .php5, .cshtml, .jsp variants and double extensions. Combine a positive allow-list with a content-type check on the actual bytes, then make sure the storage location cannot execute anything at all.
You might also need
- Remote Code Execution Risk CalculatorCommonly used together
- Path Traversal Risk CalculatorCommonly used together
- Input Validation Coverage CalculatorCommonly used together
- OWASP Risk CalculatorAlso in Web & API Security
- Command Injection Risk CalculatorAlso in Web & API Security
- JWT Security CalculatorAlso in Web & API Security