Security
uploadkit-security provides size, extension, MIME, filename, and checksum validators (sync + async). Pair it with Core or any framework adapter.
Install
Shell
pip install uploadkit-security
Shell
uv add uploadkit-security
Shell
poetry add uploadkit-security
System requirements — libmagic
For comprehensive MIME detection, install OS libmagic and
uploadkit-security[magic] (uses python-magic).
Without it, a built-in signature checker covers common types.
See
uploadkit-security.
libmagic1
file-libs
libmagic
libmagic
Shell
sudo apt install libmagic1
pip install 'uploadkit-security[magic]'
Shell
sudo dnf install file-libs
pip install 'uploadkit-security[magic]'
Shell
sudo apk add libmagic
pip install 'uploadkit-security[magic]'
Shell
brew install libmagic
pip install 'uploadkit-security[magic]'
Optional: prefer uv add 'uploadkit-security[magic]' or poetry add uploadkit-security -E magic.
Examples
Attach validators on UploadPolicy. Sync pipelines use validators; async pipelines use async_validators.
Default stack
Size → extension → MIME → filename → checksum. Policy allow-lists are read by the validators.
policy_sync.py
from uploadkit import UploadPolicy
from uploadkit_security import default_validators
policy = UploadPolicy(
max_size=5 * 1024 * 1024,
allowed_extensions=frozenset({"png", "jpg"}),
allowed_mime_types=frozenset({"image/png", "image/jpeg"}),
validators=default_validators(),
)
policy_async.py
from uploadkit import UploadPolicy
from uploadkit_security import default_async_validators
policy = UploadPolicy(
max_size=5 * 1024 * 1024,
allowed_extensions=frozenset({"png", "jpg"}),
allowed_mime_types=frozenset({"image/png", "image/jpeg"}),
async_validators=default_async_validators(),
)
Customize the stack
Use include, exclude, and extra on default_validators() / default_async_validators().
customize_sync.py
from uploadkit import UploadPolicy
from uploadkit_security import (
ChecksumValidator,
FileNameValidator,
FileSizeValidator,
default_validators,
)
# Drop checksum from the full stack
validators = default_validators(exclude=ChecksumValidator)
# Keep only size + filename
validators = default_validators(
include=(FileSizeValidator, FileNameValidator),
)
policy = UploadPolicy(
max_size=5 * 1024 * 1024,
validators=validators,
)
customize_async.py
from uploadkit import UploadPolicy
from uploadkit_security import (
AsyncChecksumValidator,
AsyncFileNameValidator,
AsyncFileSizeValidator,
default_async_validators,
)
# Drop checksum from the full stack
async_validators = default_async_validators(exclude=AsyncChecksumValidator)
# Keep only size + filename
async_validators = default_async_validators(
include=(AsyncFileSizeValidator, AsyncFileNameValidator),
)
policy = UploadPolicy(
max_size=5 * 1024 * 1024,
async_validators=async_validators,
)
MIME detection
MimeTypeValidator / AsyncMimeTypeValidator call detect_mime_type. With uploadkit-security[magic] and OS libmagic installed, sniffing uses python-magic; otherwise a built-in signature table covers common types.
mime_sync.py
from uploadkit import UploadPolicy
from uploadkit_security import detect_mime_type, default_validators
# Requires: pip install 'uploadkit-security[magic]' + OS libmagic
head = open("photo.png", "rb").read(2048)
print(detect_mime_type(head, "photo.png")) # e.g. "image/png"
policy = UploadPolicy(
max_size=5 * 1024 * 1024,
allowed_extensions=frozenset({"png", "pdf"}),
allowed_mime_types=frozenset({"image/png", "application/pdf"}),
validators=default_validators(), # MimeTypeValidator uses detect_mime_type
)
mime_async.py
from uploadkit import UploadPolicy
from uploadkit_security import detect_mime_type, default_async_validators
# Requires: pip install 'uploadkit-security[magic]' + OS libmagic
head = open("photo.png", "rb").read(2048)
print(detect_mime_type(head, "photo.png")) # e.g. "image/png"
policy = UploadPolicy(
max_size=5 * 1024 * 1024,
allowed_extensions=frozenset({"png", "pdf"}),
allowed_mime_types=frozenset({"image/png", "application/pdf"}),
async_validators=default_async_validators(), # AsyncMimeTypeValidator
)
Filename and checksum
Harden names with FileNameValidator / sanitize_filename. Compute SHA-256 with ChecksumValidator so result.sha256 is set after upload.
filename_checksum_sync.py
from uploadkit import UploadPolicy
from uploadkit_security import (
ChecksumValidator,
FileNameValidator,
default_validators,
sanitize_filename,
)
print(sanitize_filename("../../evil name!!.txt")) # "evil name__.txt"
# Filename hardening only
validators = default_validators(include=(FileNameValidator,))
# Checksum only — result.sha256 after upload
validators = default_validators(include=(ChecksumValidator,))
policy = UploadPolicy(validators=validators)
filename_checksum_async.py
from uploadkit import UploadPolicy
from uploadkit_security import (
AsyncChecksumValidator,
AsyncFileNameValidator,
default_async_validators,
sanitize_filename,
)
print(sanitize_filename("../../evil name!!.txt")) # "evil name__.txt"
# Filename hardening only
async_validators = default_async_validators(include=(AsyncFileNameValidator,))
# Checksum only — result.sha256 after upload
async_validators = default_async_validators(include=(AsyncChecksumValidator,))
policy = UploadPolicy(async_validators=async_validators)
Shared policy and error conventions: Common patterns. Full reference: uploadkit-security README.