How the plugin handles the remote catalogue, and why.
Wallpapers, previews and the datasets that describe them are downloaded from a remote CDN. The catalogue is therefore treated as untrusted input at install time: everything it carries (file names, URLs, sizes, hashes) is data, not instructions, and must not be able to make the installer write outside the wallpaper folder.
The sha256 recorded in the catalogue is not a trust anchor on its own — a
compromised catalogue would ship a matching hash — so it is only a integrity
check downstream of the controls below.
- Extension allowlist —
is_allowed_image()accepts onlywebp,jpg,jpeg,png; anything else is skipped, so a crafted entry cannot drop a non-image (script, symlink, config) into the backgrounds folder. - Bare file name —
is_safe_filename()rejects an empty name, any directory component (/),./..and a leading dash. A catalogue entry is a single file name, never a path. - Bare theme name — a theme is a directory under
DEST_BASEand comes from the same untrusted datasets, sorequire_safe_theme()applies the same rule to it in every command that takes a theme. The theme keys ofdatasets.jsonare validated withis_safe_filename()too, both when the catalogs are prefetched into the cache and when the theme list is built. - Path containment —
download_one()resolves the destination withrealpath -mand refuses it unless it stays underDEST_BASE(~/.config/omarchy/backgrounds/<theme>/). This is defence in depth, independent of how the caller built the path. - Atomic writes — downloads land on a
.tmpfile and aremv'd only after thesha256recorded in the catalogue matches; a mismatch is discarded, so a failed or interrupted write never replaces a good file. - Numeric budget —
is_nonneg_int()forces a cataloguesize_bytesto be a plain non-negative integer before it is used in Bash arithmetic (the bulk/random install budgets). Bash recursively evaluates a variable's value in arithmetic context, so a value such asa[$(cmd)]would otherwise run the command substitution as the desktop user. An invalid size is coerced to 0. - http(s) URLs only —
is_remote_url()requires every catalogue/dataset URL to start withhttp://orhttps://before it is fetched, so it cannot be read as a curl option (a leading-) or as a localfile://read. The downloaders also pass the URL after--. ..cannot become the background —cmd_set_default()only accepts a file name that is also present in the theme's catalogue.
The install paths that read a catalogue name (cmd_install(),
cmd_random_install(), cmd_set_default()) apply is_safe_filename() and
is_allowed_image() before building any destination, and require_safe_theme()
validates the theme on entry.
Open a private security advisory on the repository
(emkcloud/omarchy-wallpapers-plugin) rather than a public issue, and include
the commit, a description and, if possible, a reproducer.