Enriquefft adf3855ac8 harden wallpaper resolver against traversal, PII, and SSOT drift
Adversarial review surfaced four defects and four drive-bys. All applied:

B1 (security, MEDIUM) — Path traversal via encodeRelativeAssetPath.
encodeURIComponent passed "." and ".." through unchanged; percent-encoded
"%2e%2e" got decoded by the URL constructor. Either form escaped the
asset root: new URL("../../etc/passwd", "file:///opt/Openscreen/resources/")
→ file:///opt/etc/passwd. Reject both at src/lib/assetPath.ts via a new
UnsafeAssetPathError thrown when a decoded segment equals "." or "..".

B2 (correctness) — classifyWallpaper returned { kind: "image" } for
conic-gradient(...), rgb(...), hsl(...), oklch(...), empty string,
and named colors like "red". Old frameRenderer's bare fillStyle = value
handled these; new code would throw BackgroundLoadError with misleading
message. Classification now anchors on regexes, accepts all CSS color
functions and all three gradient types, treats unknown strings as
fallthrough color (old behavior), and normalizes "" to "#000000".

B3 (SSOT) — DEFAULT_WALLPAPER, projectPersistence.WALLPAPER_PATHS, and
SettingsPanel.WALLPAPER_RELATIVE independently hardcoded the same
/wallpapers/wallpaperN.jpg pattern. Three drift sites collapse into one:
WALLPAPER_PATHS lives in src/lib/wallpaper.ts, DEFAULT_WALLPAPER derives
from WALLPAPER_PATHS[0], projectPersistence re-exports from the canonical
module, SettingsPanel imports it directly.

B4 (privacy) — BackgroundLoadError.message and the translated toast
surfaced full file paths like file:///home/<user>/…/wallpaper.jpg —
leaks the user's home directory in copy-pasted bug reports. Added a
displayUrl getter that returns just the basename (or "data:…" for data
URIs), wired into the toast. Full URL remains in console.error and
error.url for debugging.

N1 — resolveImageWallpaperUrl now rejects image paths that don't live
under /wallpapers/ (throws BackgroundLoadError). Narrows the blast
radius of the returned <resourcesPath>/ base so the renderer can only
request files within the wallpapers directory, regardless of what the
project JSON claims.

N2 — videoExporter retry loop no longer calls cleanup() twice in the
BackgroundLoadError branch; the finally handles it.

N3 — Browser tests assert BackgroundLoadError.url contains the failing
path. Guards the {{url}} i18n interpolation contract.

N4 — VideoPlayback wallpaper resolve effect now catches resolver
throws (UnsafeAssetPathError, BackgroundLoadError from /wallpapers/
prefix enforcement). Prevents the new strict-rejection logic from
silently leaving the preview without a background.

Tests: 35 unit tests pass (up from 20); new coverage for all color
functions, all gradient types, empty string, named color fallback,
whitespace trimming, /wallpapers/ prefix enforcement, traversal
rejection, percent-encoded traversal rejection, displayUrl basename
and data-URI abbreviation.
2026-04-24 18:16:57 -05:00
2026-03-07 22:13:33 -08:00
2026-04-18 11:32:42 +02:00
2026-03-07 18:37:45 -08:00
2026-03-19 19:25:07 +08:00
2026-03-07 17:59:41 -08:00
2025-11-19 13:01:35 -07:00
isc
2025-11-09 18:08:44 -07:00
2025-11-19 00:46:37 -07:00
2026-03-07 17:59:41 -08:00
2026-03-07 17:59:41 -08:00
2026-03-07 17:59:41 -08:00

Warning

This is very much in beta and might be buggy here and there (but hope you have a good experience!).

OpenScreen Logo

siddharthvaddem%2Fopenscreen | Trendshift

Ask DeepWiki   Join Discord

OpenScreen

OpenScreen is your free, open-source alternative to Screen Studio (sort of).

If you don't want to pay $29/month for Screen Studio but want a much simpler version that does what most people seem to need, making beautiful product demos and walkthroughs, here's a free-to-use app for you. OpenScreen does not offer all Screen Studio features, but covers the basics well!

Screen Studio is an awesome product and this is definitely not a 1:1 clone. OpenScreen is a much simpler take, just the basics for folks who want control and don't want to pay. If you need all the fancy features, your best bet is to support Screen Studio (they really do a great job, haha). But if you just want something free (no gotchas) and open, this project does the job!

OpenScreen is 100% free for personal and commercial use. Use it, modify it, distribute it. (Just be cool 😁 and give a shoutout if you feel like it !)

OpenScreen App Preview 3 OpenScreen App Preview 4

Core Features

  • Record specific windows or your whole screen.
  • Add automatic or manual zooms (adjustable depth levels) and customize their durarion and position.
  • Record microphone and system audio.
  • Crop video recordings to hide parts.
  • Choose between wallpapers, solid colors, gradients or a custom background.
  • Motion blur for smoother pan and zoom effects.
  • Add annotations (text, arrows, images).
  • Trim sections of the clip.
  • Customize the speed of different segments.
  • Export in different aspect ratios and resolutions.

Installation

Download the latest installer for your platform from the GitHub Releases page.

macOS

If you encounter issues with macOS Gatekeeper blocking the app (since it does not come with a developer certificate), you can bypass this by running the following command in your terminal after installation:

xattr -rd com.apple.quarantine /Applications/Openscreen.app

Note: Give your terminal Full Disk Access in System Settings > Privacy & Security to grant you access and then run the above command.

After running this command, proceed to System Preferences > Security & Privacy to grant the necessary permissions for "screen recording" and "accessibility". Once permissions are granted, you can launch the app.

Linux

Download the .AppImage file from the releases page. Make it executable and run:

chmod +x Openscreen-Linux-*.AppImage
./Openscreen-Linux-*.AppImage

You may need to grant screen recording permissions depending on your desktop environment.

Note: If the app fails to launch due to a "sandbox" error, run it with --no-sandbox:

./Openscreen-Linux-*.AppImage --no-sandbox

Limitations

System audio capture relies on Electron's desktopCapturer and has some platform-specific quirks:

  • macOS: Requires macOS 13+. On macOS 14.2+ you'll be prompted to grant audio capture permission. macOS 12 and below does not support system audio (mic still works).
  • Windows: Works out of the box.
  • Linux: Needs PipeWire (default on Ubuntu 22.04+, Fedora 34+). Older PulseAudio-only setups may not support system audio (mic should still work).

Built with

  • Electron
  • React
  • TypeScript
  • Vite
  • PixiJS
  • dnd-timeline

I'm new to open source, idk what I'm doing lol. If something is wrong please raise an issue 🙏

Documentation

See the documentation here: OpenScreen Docs

Contributing

Contributions are welcome! If youd like to help out or see whats currently being worked on, take a look at the open issues and the project roadmap to understand the current direction of the project and find ways to contribute.

Star History

Star History Chart

License

This project is licensed under the MIT License. By using this software, you agree that the authors are not liable for any issues, damages, or claims arising from its use.

S
Description
OpenScreen desktop recorder and guide generator
Readme MIT 3.8 GiB
2026-06-05 14:00:11 +00:00
Languages
TypeScript 80.5%
C++ 9.4%
JavaScript 5.3%
Swift 1.5%
Python 1.1%
Other 2.1%