Skip to content

FileUpload max_file_size check trusts client-reported size field #3815

@strawgate

Description

@strawgate

Description

The store_files tool in FileUpload checks f.get("size", 0) > provider._max_file_size to enforce the file size limit, but the size field is entirely client-provided and never validated against the actual base64-encoded data payload.

A client can set size: 1 while sending an arbitrarily large data payload, completely bypassing the configured max_file_size limit.

Reproduction

import base64
from fastmcp import FastMCP
from fastmcp.apps.file_upload import FileUpload

server = FastMCP("test", providers=[FileUpload(max_file_size=100)])

big_data = base64.b64encode(b"x" * 10_000).decode()
spoofed = {
    "name": "huge.bin",
    "size": 1,  # lies about size
    "type": "application/octet-stream",
    "data": big_data,
}

# This succeeds despite max_file_size=100
result = await server.call_tool("Files___store_files", {"files": [spoofed]})

Expected behavior

The size limit should be enforced based on the actual base64 data length, not the client-reported size field.

Impact

The max_file_size setting gives a false sense of security — it can be trivially bypassed by any client that sets a small size value.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working. Reports of errors, unexpected behavior, or broken functionality.high-prioritysecuritySecurity fixes: input validation, SSRF/LFI prevention, auth hardening, injection defenses.serverRelated to FastMCP server implementation or server-side functionality.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions