This document describes the security model of Snippet and how to report vulnerabilities.
Snippet is an Electron desktop app that downloads and converts audio from web URLs to MP3, or converts uploaded local MP3/MP4 files. Security is implemented in layers: the renderer process is isolated and sandboxed, all communication with the main process is validated, and user input (URLs and file paths) is restricted to prevent abuse.
- Context isolation — The renderer runs with
contextIsolation: true; it cannot access Node.js or the preload script’s internals. - No Node integration —
nodeIntegration: falseso the renderer has norequire()orprocess. - Sandbox —
sandbox: trueso the renderer runs in Chromium’s sandbox with reduced privileges. - No mixed content —
allowRunningInsecureContent: falseso insecure resources are not loaded. - DevTools only in development — In production,
devTools: falseso the DevTools cannot be opened from the app. - Navigation and new windows —
setWindowOpenHandler(() => ({ action: 'deny' }))blocks new windows;will-navigateandwill-redirectallow only same-origin navigation (in production:file://; in dev:http://localhost:5173).
- Minimal API — Only
getVideoInfo(url),openFileDialog(),getLocalFileInfo(filePath),downloadMP3(params), andshowItemInFolder(filePath)are exposed viacontextBridge. - Type checks — The preload ensures
urlandfilePathare strings andparamsis a plain object before forwarding to the main process. - Structured params — For
downloadMP3, onlyurl,sourceFilePath,title,startTime,endTime, andplaybackSpeedare passed through; other keys are dropped.
- IPC origin checks — Every IPC handler verifies the sender with
isAllowedSender(event): the call must come from the app’s main window and from an allowed origin (in production:file://; in dev:http://localhost:5173orhttp://127.0.0.1:5173). Other origins receive “Unauthorized”. - URL validation (SSRF mitigation) — All URLs passed to yt-dlp are validated:
- Only
http:andhttps:protocols. - Localhost and loopback are blocked (
localhost,127.0.0.1,0.0.0.0,::1). - Private IP ranges are blocked (e.g.
10.x,172.16–31.x,192.168.x). - Alternate IP forms are blocked: decimal IPv4 (e.g.
2130706433= 127.0.0.1), IPv6 loopback (::1), and IPv4-mapped loopback (::ffff:127.0.0.1). - Maximum length: 2048 characters.
- Only
- Local file path validation — Paths passed for upload (e.g. from the file picker) are validated:
- Path must be a non-empty string; extension must be
.mp3or.mp4. - Path must resolve to an existing file (not a directory).
- Path must be under an allowed base: the user’s home directory, the app temp directory, or (on macOS) under
/Volumesfor mounted drives. Paths outside these bases are rejected to prevent reading arbitrary system or other users’ files.
- Path must be a non-empty string; extension must be
- Download parameter validation —
startTimeandendTimemust be non-negative numbers and capped at 7 days (604 800 seconds) to avoid DoS or overflow;playbackSpeedmust be between 0.25 and 4. - Title handling — Only string values are used for the download filename; non-strings are ignored to avoid main-process crashes.
- Filename sanitization — User-provided titles are sanitized (invalid characters removed, length capped) before being used as file names.
- Show in Finder —
show-item-in-folderaccepts only a file path that must resolve under the user’s Downloads folder; other paths are rejected. Sender is checked withisAllowedSender.
/api/video-info— When running the app in the browser (no Electron), the Vite dev server can serve GET/api/video-info?url=...to fetch video metadata usingbin/yt-dlp. This route is only registered in dev; it is not in the production build. URL validation matches main-process SSRF rules: onlyhttp:/https:, no localhost, no private IP ranges. Use only on a trusted dev machine.
- CSP — Applied via both a
<meta>tag inindex.htmland (in production) viasession.defaultSession.webRequestforfile://responses. Scripts and resources are restricted to'self'; inline scripts are disallowed;style-srcallows'unsafe-inline'for UI styling. - Security headers (for
file://in production, and via meta where applicable):X-Content-Type-Options: nosniff,X-Frame-Options: DENY,Referrer-Policy: strict-origin-when-cross-origin, and a restrictive Permissions-Policy (camera, microphone, geolocation, etc. disabled).
- Bundled binaries — yt-dlp and ffmpeg are bundled or downloaded from trusted sources; in production, only unpacked app resources are used.
- Temp files — Download and conversion use a temp directory under the app’s user data path; files are removed after use or on error.
If you believe you’ve found a security issue in Snippet:
- Do not open a public GitHub issue for it.
- Send a private report to the maintainers (e.g. via email or a private security advisory if the project is on GitHub). Include:
- A clear description of the issue and how to reproduce it.
- The impact you think it has (e.g. what an attacker could do).
- Any suggested fix or reference, if you have one.
- Allow a reasonable time for a fix before disclosing publicly (e.g. 90 days), unless already disclosed.
We will acknowledge receipt and work on a fix. We may ask for more details and will keep you updated when possible.
- URL validation — Hostnames are checked for private IP patterns; DNS rebinding or other resolution tricks are not mitigated at the URL-parsing level.
- Third-party sites — Downloading from a URL sends requests to that host; the app does not control the security or content of external sites (e.g. YouTube, other video hosts).
- Electron and dependencies — Keep Electron and npm dependencies up to date and review their security advisories (e.g.
npm audit, Electron release notes).
Thank you for helping keep Snippet secure.