Skip to content
Ask Otto AI
Help

What is this page?

File upload security

Role aware

This page proves the local upload-security hardening pass across student documents, admissions, forms, course media, assignments, staff downloads, compliance evidence, and public verification, including signed URL expiry, tenant-prefixed keys, malware quarantine gates, and content sanitization fixtures.

Audience
Staff
Current limits
The file upload security proof uses local deterministic fixtures only. It does not write a production storage policy, mint real signed URLs, mark malware scanning production-ready, release quarantined files, publish sanitized content, or run against live school data.

Support request boundary

Use Sev2 if a public URL or live signed URL appears enabled, cross-tenant replay is allowed, malware or quarantine gates appear bypassed, or active content is not sanitized; use Sev3 for route, fixture, control, expiry, object-key, or sanitizer issues; use Sev4 for labels or layout feedback. This panel does not submit a support case.

Sev1: Critical outage or data-risk emergency

Target: 1-hour response, 24/7 paging during pilot

Sev2: Major workflow blocked

Target: 4 business hours

Sev3: Standard product question or non-urgent issue

Target: 1 business day

Sev4: How-to, cosmetic, or future enhancement

Target: 2 business days

These preview controls are placeholders. Real AI answers, search, walkthroughs, and support submission come in later tickets.

Notifications31

Static proof preview

Real notification feeds, delivery, and preferences arrive in a later ticket.

Sam Director

Sam Director

sam.director@otto-fixture.test

Switch local proof role

This changes only the local shell proof. Production role changes remain server-validated future work.

Search is a keyboard-focusable skeleton. No real index or permissioned search results are implemented in this ticket.

Hardening - upload security

File upload security

Review local upload validation, signed URL expiry, content sanitization, quarantine gates, and the disabled production-storage boundary.

Otto Fixture BPPE Career School - upload hardening

School Administrator ยท Sam Director

File upload security

Signed URL expiry and content sanitization

Ticket 152 proves local upload hardening across student documents, admissions, forms, course media, assignments, compliance evidence, staff downloads, and public verification boundaries. It reuses the document upload validation plan while keeping production storage, real signed URLs, scanner promotion, and live school data disabled.

Reviewed 2026-10-13

Scenarios

Scenarios

16

Local fixtures covering accepted, rejected, blocked, quarantined, and sanitized upload outcomes.

Surfaces

Surfaces

8

Student, staff, course, forms, compliance, admissions, assignments, and public verification surfaces.

Signed URL tests

Signed URL tests

6

Scenarios that prove short-lived upload or read URLs stay scoped to tenant and object state.

Sanitization checks

Sanitization checks

7

Scenarios that prove active content, metadata, or file names are scrubbed before preview.

Blockers

Blockers

0

Blocking local proof issues found in this upload hardening pass.

Cross-surface upload hardening

Security surfaces

8 surfaces

Student documents

4 local scenarios

Covered
Blocked or quarantined
Blocked or quarantined
2
Signed URL
Signed URL
1
Sanitization
Sanitization
2

Admissions application

2 local scenarios

Covered
Blocked or quarantined
Blocked or quarantined
2
Signed URL
Signed URL
0
Sanitization
Sanitization
0

Forms and signing evidence

1 local scenarios

Covered
Blocked or quarantined
Blocked or quarantined
1
Signed URL
Signed URL
1
Sanitization
Sanitization
1

Course media

3 local scenarios

Covered
Blocked or quarantined
Blocked or quarantined
1
Signed URL
Signed URL
0
Sanitization
Sanitization
2

Assignment submissions

2 local scenarios

Covered
Blocked or quarantined
Blocked or quarantined
1
Signed URL
Signed URL
1
Sanitization
Sanitization
1

Staff review downloads

1 local scenarios

Covered
Blocked or quarantined
Blocked or quarantined
1
Signed URL
Signed URL
1
Sanitization
Sanitization
0

Compliance evidence

2 local scenarios

Covered
Blocked or quarantined
Blocked or quarantined
1
Signed URL
Signed URL
1
Sanitization
Sanitization
1

Public verification

1 local scenarios

Covered
Blocked or quarantined
Blocked or quarantined
1
Signed URL
Signed URL
1
Sanitization
Sanitization
0

Short-lived access

Signed URL expiry tests

4 tests

Upload PUT URL

PUT - expires in 10 minutes

Passing locally
Scope
Scope
write-one-object
Required state
Required state
received draft
Replay policy
Replay policy
Reject after expiry or after object key changes.

Read GET URL

GET - expires in 5 minutes

Passing locally
Scope
Scope
read-one-accepted-object
Required state
Required state
accepted
Replay policy
Replay policy
Reject before accepted status and after expiry.

Cross-tenant replay

GET - expires in 5 minutes

Passing locally
Scope
Scope
tenant-member-and-object-key
Required state
Required state
same tenant membership
Replay policy
Replay policy
Reject if requester tenant differs from object prefix.

Token logging

GET - expires in 5 minutes

Passing locally
Scope
Scope
signature-redacted
Required state
Required state
audit metadata only
Replay policy
Replay policy
Never log raw signature, token, or signed query string.

Preview-safe payloads

Content sanitization tests

5 fixtures

HTML script payload

Unsafe fragments removed before preview rendering.

Sanitized
Removed
Removed
<script, onerror, javascript:
Kept
Kept
Safe lesson note, open
Sanitized output
Sanitized output
<p>Safe lesson note</p><img src=x><a href="alert(1)">open</a>

SVG active content

Unsafe fragments removed before preview rendering.

Sanitized
Removed
Removed
<script, foreignObject, onload
Kept
Kept
diagram
Sanitized output
Sanitized output
<svg><text>diagram</text></svg>

Office preview metadata

Unsafe fragments removed before preview rendering.

Sanitized
Removed
Removed
macroProject, 123-45-6789
Kept
Kept
Preview text
Sanitized output
Sanitized output
Author: Maya Rivera Student SSN [redacted-ssn] Preview text

Signed URL metadata

Unsafe fragments removed before preview rendering.

Sanitized
Removed
Removed
signature=abc123
Kept
Kept
signature=redacted, expires=2026-10-13
Sanitized output
Sanitized output
/api/storage/sign-read?bucket=student-documents&signature=redacted&expires=2026-10-13T20:00:00Z

Filename traversal

Unsafe fragments removed before preview rendering.

Sanitized
Removed
Removed
.., !!
Kept
Kept
maya-diploma-final.pdf
Sanitized output
Sanitized output
maya-diploma-final.pdf

Upload security matrix

Local scenario coverage

16 scenarios

student documents

Accepted student document proof

Student document intake

Accepted
Fixture
Fixture
Maya Rivera Diploma.pdf
Controls
Controls
extension_allowlist, mime_sniff, magic_number, size_limit, tenant_prefix, hash_integrity
Acceptance signal
Acceptance signal
PDF fixture passes extension, MIME, magic number, size, tenant prefix, and SHA-256 checks.

student documents

Reject executable upload

Binary upload attempt

Rejected
Fixture
Fixture
transcript-viewer.exe
Controls
Controls
extension_allowlist, mime_sniff, magic_number, content_sanitization
Acceptance signal
Acceptance signal
Executable extension, MIME type, and MZ magic number are rejected before storage planning.

admissions application

Reject MIME and extension mismatch

Admissions upload spoofing

Rejected
Fixture
Fixture
application-essay.pdf with image/jpeg
Controls
Controls
extension_allowlist, mime_sniff, magic_number
Acceptance signal
Acceptance signal
Declared PDF, browser MIME, and magic number must agree before an application document can be queued.

student documents

Path traversal filename scrub

Object-key path traversal

Sanitized
Fixture
Fixture
../../Maya Diploma Final!!.PDF
Controls
Controls
tenant_prefix, metadata_scrub
Acceptance signal
Acceptance signal
Filename is normalized before object-key planning and cannot escape the tenant prefix.

admissions application

Reject oversized application upload

Large file denial-of-service

Rejected
Fixture
Fixture
full-portfolio-scan.pdf
Controls
Controls
size_limit
Acceptance signal
Acceptance signal
Application uploads over 10 MB are rejected before storage, scan, or preview work starts.

forms signing evidence

Malware scan quarantine gate

Signer evidence release

Quarantined
Fixture
Fixture
guardian-id-scan.pdf
Controls
Controls
malware_scan_gate, signed_url_expiry, content_sanitization
Acceptance signal
Acceptance signal
Pending or failed scan state blocks read URLs and signer evidence release.

student documents

Upload URL expires after 10 minutes

Expired upload token replay

Blocked
Fixture
Fixture
write-one-object signed URL
Controls
Controls
signed_url_expiry, tenant_prefix
Acceptance signal
Acceptance signal
PUT URL is write-one-object scoped and expires 10 minutes after issue.

staff review download

Read URL expires after acceptance

Unreviewed document download

Blocked
Fixture
Fixture
read-one-accepted-object signed URL
Controls
Controls
signed_url_expiry, tenant_prefix
Acceptance signal
Acceptance signal
GET URL is read-one-accepted-object scoped, expires in 5 minutes, and is unavailable before accepted status.

compliance evidence

Cross-tenant signed URL replay

Tenant isolation bypass

Blocked
Fixture
Fixture
bppe-career URL replayed by credit-college user
Controls
Controls
signed_url_expiry, tenant_prefix, public_url_block
Acceptance signal
Acceptance signal
Tenant-prefixed object key and membership context block replay outside the issuing tenant.

public verify

Public URL block

Public student-file exposure

Blocked
Fixture
Fixture
student-file-public-read
Controls
Controls
public_url_block, signed_url_expiry
Acceptance signal
Acceptance signal
Student documents never use public object URLs; verification routes use signed proof APIs only.

course media

Remote URL import SSRF block

Server-side request forgery

Blocked
Fixture
Fixture
https://169.254.169.254/latest/meta-data/
Controls
Controls
ssrf_block
Acceptance signal
Acceptance signal
Upload workflows do not fetch arbitrary remote URLs or private-network addresses.

course media

HTML script sanitization

Stored cross-site scripting

Sanitized
Fixture
Fixture
lesson-snippet.html
Controls
Controls
content_sanitization
Acceptance signal
Acceptance signal
Script tags, event handlers, javascript URLs, and HTML data URLs are removed from preview payloads.

course media

SVG active content sanitization

Active SVG content

Sanitized
Fixture
Fixture
diagram.svg
Controls
Controls
content_sanitization
Acceptance signal
Acceptance signal
SVG script, foreignObject, inline handlers, and javascript links are stripped before preview.

assignment submission

Office macro quarantine

Macro-enabled document

Quarantined
Fixture
Fixture
case-study-response.docm
Controls
Controls
malware_scan_gate, content_sanitization
Acceptance signal
Acceptance signal
Macro-enabled Office documents stay quarantined and cannot generate student or instructor previews.

compliance evidence

OCR text and metadata scrub

Restricted metadata in previews

Sanitized
Fixture
Fixture
withdrawal-evidence-ocr.txt
Controls
Controls
metadata_scrub, content_sanitization
Acceptance signal
Acceptance signal
Preview payload redacts restricted identifiers, signatures, and signed URL query values.

assignment submission

Assignment upload hash integrity

Assignment evidence tampering

Accepted
Fixture
Fixture
discharge-note-case-study.pdf
Controls
Controls
hash_integrity, tenant_prefix, signed_url_expiry
Acceptance signal
Acceptance signal
Assignment object key, SHA-256 hash, and short-lived read URL are bound to the submission record.

Production upload actions are disabled

Proof boundary

6 disabled