github snapotter-hq/SnapOtter v1.17.2

4 hours ago

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, and SNAPOTTER_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.gz and snapotter-vX.Y.Z-linux-arm64.tar.gz from 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/later labels.

Improvements

  • WCAG 2.2 AA accessibility: Skip navigation, route announcer, focus trapping on all modals, aria-live regions for processing status, prefers-reduced-motion support, correct contrast ratios, and 44px minimum touch targets. All 49 hardcoded aria-label strings 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.txt added 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=0 in the Dockerfile caused @fastify/rate-limit to 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 libgles2 to the Docker image.
  • Docker: HEIC files broken on ARM: heif-convert crashed with "undefined symbol: heif_get_plugin_directories" on arm64 due to library version mismatch. Fixed with LD_LIBRARY_PATH=/usr/local/lib to prioritize the custom libheif 1.21.2 build.
  • Docker: upscale and restore-photo AI bundles failed on ARM: basicsr could not build from source on arm64 because wheel and setuptools were 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-url to --index-url for 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() with crypto.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.2

Or with Docker Compose:

docker compose pull && docker compose up -d

Also available from GitHub Container Registry:

docker pull ghcr.io/snapotter-hq/snapotter:1.17.2

Full Changelog: v1.17.1...v1.17.2

Don't miss a new SnapOtter release

NewReleases is sending notifications on new releases.