Highlights
This release adds a new HTML to Image tool (tool #53), full WCAG 2.2 AA accessibility compliance, and a comprehensive security hardening pass based on external penetration testing. The Docker image also received 5 critical fixes that resolve container startup failures, broken HEIC decoding on ARM, and missing AI tool dependencies.
New Features
- HTML to Image: Capture screenshots of URLs or raw HTML as PNG/JPEG/WebP. Supports full-page captures, custom viewports, and dark mode. Built on Playwright Chromium with SSRF protection.
- Docker _FILE secret convention: Mount sensitive environment variables (passwords, API keys, OIDC secrets) as files instead of plain-text env vars. Supported for
DEFAULT_PASSWORD_FILE,S3_ACCESS_KEY_ID_FILE,S3_SECRET_ACCESS_KEY_FILE,OIDC_CLIENT_SECRET_FILE,COOKIE_SECRET_FILE, andSNAPOTTER_LICENSE_KEY_FILE. (#205) - Enterprise licensing and S3 storage: Optional commercial license key and S3-compatible object storage backend for enterprise deployments.
- Shape editor improvements: Fill/stroke transparency, RGBA color picker, and dash line styles in the image editor.
- Pre-built release archives: Download
snapotter-vX.Y.Z-linux-amd64.tar.gzandsnapotter-vX.Y.Z-linux-arm64.tar.gzfrom GitHub Releases for non-Docker installs (Proxmox, bare metal, LXC). (#202) - Community roadmap: Feature requests and prioritization now tracked via GitHub Discussions with
now/next/laterlabels.
Improvements
- WCAG 2.2 AA accessibility: Skip navigation, route announcer, focus trapping on all modals,
aria-liveregions for processing status,prefers-reduced-motionsupport, correct contrast ratios, and 44px minimum touch targets. All 49 hardcodedaria-labelstrings replaced with i18n keys across 25 components. (#209) - Mobile responsiveness: Responsive settings dialog, homepage, navigation, and toast notifications. SSE connections now automatically reconnect when returning from a backgrounded mobile tab. (#203, #204)
- Background removal quality: Edge smoothing, color decontamination, and output format selection added to the remove-background tool.
- Italian translation: ~145 newly translated strings contributed by @albanobattistella. (#206)
- Per-tool API documentation: 53 individual VitePress doc pages with accurate parameters, example requests, and response formats. Root
llms.txtadded for LLM-friendly repo browsing. - AI model downloads: Retry logic with exponential backoff for HuggingFace model downloads, preventing transient failures from blocking bundle installation. (#201)
Bug Fixes
- Docker: fresh containers were completely unusable:
RATE_LIMIT_PER_MIN=0in the Dockerfile caused@fastify/rate-limitto block all API requests (including health checks) with HTTP 429. Fixed by treating 0 as unlimited (50,000/min). - Docker: face detection AI tools failed on all platforms: blur-faces, red-eye-removal, enhance-faces, and passport-photo failed with "libGLESv2.so.2 not found". Fixed by adding
libgles2to the Docker image. - Docker: HEIC files broken on ARM:
heif-convertcrashed with "undefined symbol: heif_get_plugin_directories" on arm64 due to library version mismatch. Fixed withLD_LIBRARY_PATH=/usr/local/libto prioritize the custom libheif 1.21.2 build. - Docker: upscale and restore-photo AI bundles failed on ARM:
basicsrcould not build from source on arm64 becausewheelandsetuptoolswere missing from the Python venv. Fixed by pre-installing both packages. - Docker: OCR used wrong CUDA version on GPU: PaddlePaddle resolved from PyPI (CUDA 11) instead of the CUDA 12.6 index, causing symbol errors on GPU containers. Fixed by changing
--extra-index-urlto--index-urlfor the cu126 package source. - SSRF guard bypass via hex IPv4-mapped IPv6: The URL-fetch SSRF guard only handled the dotted form of
::ffff:addresses. Hex-compressed forms like[::ffff:7f00:1](127.0.0.1) bypassed the private IP check, allowing access to internal services and cloud metadata endpoints. (Reported by @tonghuaroot via coordinated disclosure) - iPhone HEIC support: Built libheif 1.21.2 from source to fix decoding of iPhone HEIC files with auxiliary images (depth maps, HDR gain maps). (#183, #199)
- Real-ESRGAN CUDA OOM on 8GB GPUs: Enabled tiling to prevent out-of-memory crashes when upscaling on GPUs with limited VRAM. (#200)
- 6 production Sentry errors resolved: Fixed crashes from malformed inputs, edge cases in metadata handling, and error response formatting.
- 7 bugs from QA sweep: Selective metadata stripping, meme font mapping, content type detection, and missing i18n keys. (#208)
- Cryptographic password generation: Replaced
Math.random()withcrypto.getRandomValues()for password generation. - Docker Compose image name: Corrected the image name in
docker-compose.yml. (#198)
Security
- Penetration test hardening: 10 findings from external security testing addressed: XFF rate-limit bypass (PT-01), malformed JSON 500 errors (PT-03), unbounded pipeline steps DoS (PT-04), clientJobId validation (PT-06), missing security headers on SSE streams (PT-07), audit log XSS (PT-08), TRACE method enabled (PT-10), missing 429 in OpenAPI spec (PT-12), unbounded SVGZ decompression (PT-13). (#207)
- SSRF hex IPv6 bypass: Blocked hex-compressed IPv4-mapped IPv6 addresses in the URL-fetch guard. (Credit: @tonghuaroot)
- SVG XXE protection: Added test fixtures and validation for SVG XML external entity attacks.
- Dockerfile base images pinned by digest: Prevents supply chain attacks from mutable tags.
Acknowledgements
- @tonghuaroot: For responsibly disclosing the SSRF guard bypass via hex IPv4-mapped IPv6 addresses. The detailed proof-of-concept and suggested fix made for a quick turnaround.
- @rudedog7106: For reporting HEIC decoding failures on TrueNAS/Docker. (#183)
- @electricmessiah: For reporting missing shape fill transparency (#193) and the Docker Compose image name issue (#182).
- @florentineprinzessinzusachsen: For reporting CUDA out-of-memory on NVIDIA 3070 8GB. (#191)
- @albanobattistella: For contributing ~145 Italian translation strings. (#206)
Upgrade
docker pull snapotter/snapotter:1.17.2Or with Docker Compose:
docker compose pull && docker compose up -dAlso available from GitHub Container Registry:
docker pull ghcr.io/snapotter-hq/snapotter:1.17.2Full Changelog: v1.17.1...v1.17.2