Image safety
ALTO Image applies source limits before decoding and strips metadata by default. Keep the defaults for untrusted uploads unless the application has a specific reason to change them.
Metadata policies
| Policy | ICC profile | EXIF, IPTC, and XMP |
|---|---|---|
MetadataPolicy::Strip |
remove | remove |
MetadataPolicy::ColourProfile |
keep | remove |
MetadataPolicy::Copyright |
remove | keep copyright and author fields when supported |
MetadataPolicy::Keep |
keep | keep what the driver supports |
Strip is the default and removes EXIF and GPS data.
<?php
use Alto\Image\Image;
$private = Image::open('upload.jpg')->webp();
$colourManaged = $private->keepColourProfile();
$archival = $private->keepMetadata();Use withMetadata() for an explicit policy. GD cannot preserve source metadata
or ICC profiles. Imagick support depends on its compiled delegates. The selected
driver reports any approximation in Result::$degradations.
keepColourProfile() preserves a profile. convertColourProfile() transforms
pixels to a named profile; it is a separate operation and requires LCMS support
in Imagick.
Input and output limits
The default Limits policy is:
| Limit | Default |
|---|---|
| Source pixels | 50,000,000 |
| Width or height | 32,768 |
| Animation frames | 512 |
| Encoded source bytes | 256 MiB |
| Truncated input | reject |
| Projected output checks | enabled |
Apply stricter limits to a request when needed:
<?php
use Alto\Image\Image;
use Alto\Image\Limits;
$image = Image::open($upload)
->within(new Limits(
maxPixels: 20_000_000,
maxDimension: 8_192,
maxBytes: 32 * 1024 * 1024,
));Use Limits::none() only for sources produced and trusted by the application.
Untrusted input
- Resolve user-controlled source paths against an allowed directory.
- Parse user-controlled transform strings with an explicit operation list:
<?php
use Alto\Image\Transform;
$transform = Transform::parse(
$value,
only: ['cover', 'crop', 'sharpen'],
);- Exclude
overlayunless referenced files are independently constrained. - Keep finite limits in place before any terminal operation.
- Treat
escape()closures as trusted application code.
Report suspected vulnerabilities through the organization security policy.
Sources
Image::open() accepts a path or Source. Create a source explicitly with
Source::file(), Source::bytes(), or Source::stream(). Source::of() accepts
an existing source or path. Use identifiedBy() only when application storage
already provides a stable version identifier for cache signatures.
Header reads such as metadata(), head(), tail(), and length() do not
request a full pixel decode. contents() reads the complete source. Resolve
paths and enforce finite Limits before allowing a terminal image operation.