MetaLens is designed with security-first principles:
- Offline by default β all metadata reading and writing happens on your machine. The only network access is the update check (see below), which runs only when you click Check for updates or have enabled the opt-in startup check
- Localhost-only sidecar β the Python (FastAPI) backend binds to
127.0.0.1only, on a dynamically chosen port, never0.0.0.0 - Electron hardening β
nodeIntegration: false,contextIsolation: true,sandbox: true; IPC accepts only the application's main frame. Navigation and popups are blocked and a Content Security Policy limits renderer resources - Authenticated sidecar β a fresh random token is generated for each session, passed to Python through the environment and sent in an Authorization header. Requests without valid credentials are rejected; localhost binding alone is not treated as authentication
- Atomic, verified writes β every save (edits and deletions together) is prepared on a copy in a private temporary directory beside the target, read back and checked against the request, and checked for concurrent modification before the copy replaces the original (
ReplaceFileWon Windows, preserving the security descriptor, alternate data streams and file attributes such as hidden;os.replaceelsewhere). Any failure leaves the original content intact. The replacement is a new file, so hard links to the original are detached. A read-only file is refused (HTTP 403), not modified - Path validation β a dedicated
core.path_securitymodule normalizes every path (resolves~,..and symbolic links) and checks that it is an existing, readable regular file or directory before any filesystem access, across all API routes. This is normalization, not a sandbox: an authenticated caller may name any file the user account can access, which is why every request must carry the session token - Hardened update check β requests are made by the Electron main process, never by the renderer (whose CSP still only allows the local sidecar). It queries the GitHub Releases API of
overwrite00/MetaLensonly, and the renderer cannot supply URLs. Release and asset URLs must point to that repository, and the installer is downloaded only when you click Download & install (Windows installed builds), checked against its size and the SHA-256 digest published by GitHub, and discarded on any mismatch. Release notes are shown as plain text - No internal details in errors β API error bodies carry fixed, structured messages only; the text of internal exceptions stays in the local log
- Clean shutdown β the Exit button (and closing the app) stops the sidecar's whole process tree, cancels any update download and releases the port and memory
- Transparent code β all handler and analysis logic is open-source and auditable
- β No user accounts or authentication
- β No telemetry or usage tracking
- β No data collection or analytics
- β No cloud processing or storage
- β No automatic phone-home: the update check is manual, or opt-in (off by default) at startup
- β Your files and their metadata never leave your machine
- β Nothing is written anywhere except the file you explicitly edit (and its short-lived private temporary copy beside it, removed after the save)
- β The undo stack and the sidecar's Undo journal (original values of the last 50 saves, at most 64 MiB) live in memory only β they are cleared when you close the app, never written to disk
- β Full source code transparency
- Uses established libraries per format: Pillow (image properties), piexif tag tables plus MetaLens's own structure-preserving EXIF/XMP/IPTC codecs and JPEG segment writer (images), mutagen (audio/MP4), pypdf (PDF), Python's
zipfile/xml.etree(Office Open XML packages), olefile (legacy Office), hachoir (read-only fallback for other formats). XMP packets (JPEG, PDF) containing DOCTYPE or entity declarations are refused - Field capabilities are enforced by the API; client-provided editability flags cannot override them. Writable: EXIF/XMP/IPTC of JPEG, PNG, WebP, TIFF, TIFF-based RAW and HEIC/AVIF (what a format cannot hold is refused), audio tags (except AAC), MP4/MOV and MKV/WebM metadata, PDF document info and XMP, Office and OpenDocument/EPUB properties,
fs:mtimeand Linuxuser.extended attributes; legacy Office (DOC/XLS/PPT) allows removing properties only. Read-only: GIF/BMP, Canon CR3 and Fujifilm RAF, AAC, AVI and other video read through hachoir, encrypted or digitally signed PDFs, digitally signed Office packages (so a signature is never silently invalidated), everything read through hachoir. Every write is checked so that the picture, audio or video data comes out identical - Every value is validated before the file is touched; library errors caused by a value are reported as validation errors (HTTP 422), never as crashes
- Filesystem access always goes through
validate_file_path/validate_directory_pathbefore touching disk
- The Electron renderer talks to the OS only through the
preload.jscontextBridgesurface (dialogs, path helpers, drive listing) β no direct filesystem or process access - The renderer talks to the Python sidecar only over HTTP to
127.0.0.1:{dynamic_port}(never a hardcoded port), with the port and session token obtained from the main process through theget-sidecar-connectionIPC channel; the Content Security Policy only allows connections to127.0.0.1 - The sidecar rejects foreign browser origins and requires its session token, including for
/health. The normal development path is Vite plus Electron; opening the frontend in a standalone browser does not grant sidecar access
- Code-signed installers β releases are currently unsigned (no purchased certificate). Windows SmartScreen will warn on first run; this is expected, not a compromise indicator. See Installation Guide for how to proceed safely
- Malware/content scanning β MetaLens edits metadata; it does not scan file contents for malicious payloads
- Encryption β files and their metadata are stored and edited in plain form on disk, as with any local file manager
- Guarantee against all data loss β while writes are atomic, always keep backups of files you can't afford to lose
For files handled outside MetaLens, also rely on your OS's built-in protections (Windows Defender / your Linux distro's package signing) and keep regular backups.
If you discover a security vulnerability in MetaLens:
- Do not open a public GitHub issue β this exposes the vulnerability before a fix ships
- Use GitHub Security Advisory:
- Navigate to: https://github.com/overwrite00/MetaLens/security/advisories
- Click "Report a vulnerability"
- Describe the vulnerability in detail, including reproduction steps
- 48 hours: acknowledgment of your report
- 2 weeks (critical): target fix timeline for critical vulnerabilities
- 30 days (high): target fix timeline for high-severity vulnerabilities
- Coordinated disclosure: we'll work with you on a disclosure timeline
We appreciate responsible disclosure and will credit you in the security advisory (unless you prefer anonymity).
- Subscribe to releases: Watch the Releases page
- Check security advisories: GitHub Security Advisory
- Update regularly: dependency security fixes are tracked in CHANGELOG.md
- Code of Conduct β community guidelines
- Contributing Guide β how to contribute securely
- REQUIREMENTS.md β dependency information
- CHANGELOG.md β version history and security fixes
Last updated: 2026-11-04 β Contributing | Back to README β