Merge pull request #7972 from acrogenesis/harden-browser-policy-dirs

Stop world-writable browser policy directories
This commit is contained in:
Ryan Hughes
2026-08-28 18:00:20 -04:00
committed by GitHub
17 changed files with 968 additions and 49 deletions
+11 -17
View File
@@ -6,9 +6,10 @@
set -e
setup_policy_directory() {
sudo mkdir -p "$1"
sudo chmod a+rw "$1"
source "$OMARCHY_PATH/install/helpers/browser-policy.sh"
setup_chromium_policy_directory() {
browser_policy_setup_dir "$1"
}
announce_browser_installed() {
@@ -23,13 +24,6 @@ copy_chromium_flags() {
omarchy-install-chromium-ytdlp
}
setup_firefox_preferences() {
local distribution_dir="$1"
setup_policy_directory "$distribution_dir"
sudo cp -f "$OMARCHY_PATH/default/firefox/policies.json" "$distribution_dir/policies.json"
}
setup_firefox_wayland() {
mkdir -p ~/.config/environment.d
echo "MOZ_ENABLE_WAYLAND=1" > ~/.config/environment.d/omarchy-firefox-wayland.conf
@@ -40,7 +34,7 @@ chromium)
echo "Installing Chromium..."
omarchy-pkg-add chromium
setup_policy_directory /etc/chromium/policies/managed
setup_chromium_policy_directory /etc/chromium/policies/managed
copy_chromium_flags ~/.config/chromium-flags.conf
omarchy-theme-set-browser
announce_browser_installed "Chromium"
@@ -49,7 +43,7 @@ chrome)
echo "Installing Chrome..."
omarchy-pkg-aur-add google-chrome || exit 1
setup_policy_directory /etc/opt/chrome/policies/managed
setup_chromium_policy_directory /etc/opt/chrome/policies/managed
copy_chromium_flags ~/.config/chrome-flags.conf
omarchy-theme-set-browser
announce_browser_installed "Chrome"
@@ -58,7 +52,7 @@ edge)
echo "Installing Edge..."
omarchy-pkg-aur-add microsoft-edge-stable-bin || exit 1
setup_policy_directory /etc/opt/edge/policies/managed
setup_chromium_policy_directory /etc/opt/edge/policies/managed
copy_chromium_flags ~/.config/microsoft-edge-stable-flags.conf
omarchy-theme-set-browser
announce_browser_installed "Edge"
@@ -67,7 +61,7 @@ brave)
echo "Installing Brave..."
omarchy-pkg-aur-add brave-bin || exit 1
setup_policy_directory /etc/brave/policies/managed
setup_chromium_policy_directory /etc/brave/policies/managed
copy_chromium_flags ~/.config/brave-flags.conf
omarchy-theme-set-browser
announce_browser_installed "Brave"
@@ -76,7 +70,7 @@ brave-origin)
echo "Installing Brave Origin..."
omarchy-pkg-aur-add brave-origin-bin || exit 1
setup_policy_directory /etc/brave/policies/managed
setup_chromium_policy_directory /etc/brave/policies/managed
copy_chromium_flags ~/.config/brave-origin-flags.conf
omarchy-theme-set-browser
announce_browser_installed "Brave Origin"
@@ -85,7 +79,7 @@ firefox)
echo "Installing Firefox..."
omarchy-pkg-add firefox || exit 1
setup_firefox_preferences /usr/lib/firefox/distribution
browser_policy_setup_firefox_distribution /usr/lib/firefox/distribution
setup_firefox_wayland
announce_browser_installed "Firefox"
;;
@@ -93,7 +87,7 @@ zen)
echo "Installing Zen..."
omarchy-pkg-aur-add zen-browser-bin || exit 1
setup_firefox_preferences /opt/zen-browser/distribution
browser_policy_setup_firefox_distribution /opt/zen-browser/distribution
setup_firefox_wayland
announce_browser_installed "Zen"
;;
+6
View File
@@ -742,6 +742,12 @@ create_user() {
# for specific commands), and a duplicate grant is harmless.
echo "%wheel ALL=(ALL:ALL) ALL" >/etc/sudoers.d/00-omarchy-wheel
chmod 440 /etc/sudoers.d/00-omarchy-wheel
source "$OMARCHY_PATH/install/helpers/browser-policy.sh"
for dir in "${BROWSER_POLICY_MANAGED_DIRS[@]}"; do
[[ -d $dir || -L $dir ]] || continue
browser_policy_setup_dir "$dir"
done
}
install_authorized_keys() {
+9 -19
View File
@@ -3,23 +3,15 @@
# omarchy:summary=Apply the current theme color to Chromium, Chrome, Edge, and Brave
# omarchy:hidden=true
source "$OMARCHY_PATH/install/helpers/browser-policy.sh"
CHROMIUM_THEME=$HOME/.local/state/omarchy/current/theme/chromium.theme
THEME_HEX_COLOR=$BROWSER_POLICY_DEFAULT_COLOR
if [[ -f $CHROMIUM_THEME ]]; then
THEME_RGB_COLOR=$(<$CHROMIUM_THEME)
THEME_HEX_COLOR=$(printf '#%02x%02x%02x' ${THEME_RGB_COLOR//,/ })
else
# Use a default, neutral grey if theme doesn't have a color
THEME_HEX_COLOR="#1c2027"
THEME_HEX_COLOR=$(browser_policy_theme_hex "$(<$CHROMIUM_THEME)")
fi
set_browser_policy() {
local policy_dir="$1"
[[ -d $policy_dir ]] || return
echo "{\"BrowserThemeColor\": \"$THEME_HEX_COLOR\", \"BrowserColorScheme\": \"device\"}" | tee "$policy_dir/color.json" >/dev/null
}
refresh_running_browser() {
local process="$1"
local command="$2"
@@ -30,17 +22,15 @@ refresh_running_browser() {
fi
}
set_browser_policy /etc/chromium/policies/managed
failed=0
omarchy-theme-set-browser-policy "${THEME_HEX_COLOR#\#}" || failed=1
refresh_running_browser chromium chromium
set_browser_policy /etc/opt/chrome/policies/managed
refresh_running_browser chrome google-chrome-stable || refresh_running_browser chrome google-chrome
set_browser_policy /etc/opt/edge/policies/managed
refresh_running_browser msedge microsoft-edge-stable
set_browser_policy /etc/brave/policies/managed
refresh_running_browser brave brave
# Match on the binary path: the running process is named plain "brave", and a
# bare -f brave-origin pattern would also match the installer's own terminal.
refresh_running_browser /opt/brave-origin-bin/ brave-origin -f
exit "$failed"
+118
View File
@@ -0,0 +1,118 @@
#!/bin/bash
# omarchy:summary=Write the current theme color into the browser policy directories
# omarchy:args=<rrggbb>
# omarchy:hidden=true
set -euo pipefail
# Whenever this runs as root — invoked directly through the passwordless
# sudoers rule, or re-execed by require_root below — sudo's secure_path decides
# where a bare helper resolves, and a dev link (etc/sudoers.d/omarchy-dev-path)
# prepends a user-writable checkout bin/ to it. Every helper this script calls
# by bare name (printf's builtin aside: install, mktemp, rm) is a system tool,
# never an omarchy-* command, so pin PATH to trusted system directories and keep
# root from resolving one out of that checkout. The unprivileged wrapper phase
# keeps the caller's PATH so it can still find sudo/pkexec.
if (( EUID == 0 )); then
export PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
fi
# Enterprise policy trust roots. The list is fixed here rather than taken from
# the caller: the caller chooses a color, never a path.
POLICY_DIRS=(
/etc/chromium/policies/managed
/etc/opt/chrome/policies/managed
/etc/opt/edge/policies/managed
/etc/brave/policies/managed
)
# The path etc/sudoers.d/omarchy-theme-browser names. The privileged half always
# runs from there rather than from whichever copy was invoked, so the rule
# matches even where $OMARCHY_PATH points at a checkout.
PACKAGED_PATH=/usr/bin/omarchy-theme-set-browser-policy
usage() {
echo "Usage: omarchy-theme-set-browser-policy <rrggbb>" >&2
}
if (( $# != 1 )); then
usage
exit 1
fi
color="$1"
# Six lowercase hex digits is the whole of what this accepts. The leading "#"
# is added when the JSON is written rather than passed in: "#" opens a comment
# in sudoers, and keeping it out of argv lets the sudoers rule spell the
# argument as a plain six-character glob.
if [[ ! $color =~ ^[0-9a-f]{6}$ ]]; then
echo "omarchy-theme-set-browser-policy: expected six lowercase hex digits, got '$color'" >&2
exit 1
fi
# True when sudo would run this exact command without stopping for a password.
# `sudo -l` on its own reports whether a command is permitted, which the blanket
# %wheel rule answers yes to for everything; the long listing prints the matched
# entry's tags, so !authenticate is the grant in
# etc/sudoers.d/omarchy-theme-browser and nothing else. Listing runs nothing
# and, under -n, prompts for nothing.
sudo_grants_passwordless() {
sudo -n -l -l "$PACKAGED_PATH" "$@" 2>/dev/null | grep -q '!authenticate'
}
require_root() {
if (( EUID == 0 )); then
return
elif [[ -t 0 ]] || sudo_grants_passwordless "$@"; then
exec sudo "$PACKAGED_PATH" "$@"
else
exec pkexec "$PACKAGED_PATH" "$@"
fi
}
require_root "$color"
failed=0
staged=""
cleanup() {
[[ -n $staged ]] && rm -f "$staged"
}
trap cleanup EXIT
for policy_dir in "${POLICY_DIRS[@]}"; do
# Only browsers Omarchy has installed have a policy directory. Creating one
# here would hand a browser a managed-policy root it does not otherwise have.
[[ -d $policy_dir && ! -L $policy_dir ]] || continue
dest=$policy_dir/color.json
staged=$(mktemp) || {
failed=1
continue
}
printf '{"BrowserThemeColor": "#%s", "BrowserColorScheme": "device"}\n' "$color" >"$staged"
if [[ -L $dest || -d $dest ]]; then
if ! rm -rf -- "$dest"; then
rm -f "$staged"
staged=""
echo "omarchy-theme-set-browser-policy: cannot replace $dest" >&2
failed=1
continue
fi
fi
if ! install -m 0644 -o root -g root -T "$staged" "$dest"; then
rm -f "$staged"
staged=""
echo "omarchy-theme-set-browser-policy: cannot write $dest" >&2
failed=1
continue
fi
rm -f "$staged"
staged=""
done
exit "$failed"
+20 -1
View File
@@ -1312,7 +1312,21 @@ apply_system_transition() {
/usr/share/icons/Yaru/scalable/actions/go-next-symbolic.svg
as_root gtk-update-icon-cache /usr/share/icons/Yaru >/dev/null 2>&1 || true
as_root install -d -m 0777 /etc/chromium/policies/managed
local browser_policy_helper=/usr/share/omarchy/install/helpers/browser-policy.sh
if ! as_root test -f "$browser_policy_helper"; then
warn "$browser_policy_helper is unavailable; Chromium policy directories were not hardened."
else
as_root env OMARCHY_PATH=/usr/share/omarchy \
bash -euo pipefail -c '
source "$OMARCHY_PATH/install/helpers/browser-policy.sh"
browser_policy_setup_dir /etc/chromium/policies/managed
for dir in "${BROWSER_POLICY_MANAGED_DIRS[@]}"; do
[[ $dir == "/etc/chromium/policies/managed" ]] && continue
[[ -d $dir || -L $dir ]] || continue
browser_policy_setup_dir "$dir"
done
'
fi
as_root install -d -m 0755 /usr/lib/chromium
printf '%s\n' '{"browser":{"theme":{"color_scheme":0,"color_scheme2":0}}}' | \
as_root tee /usr/lib/chromium/initial_preferences >/dev/null
@@ -2306,6 +2320,11 @@ refresh_current_theme_after_upgrade() {
# hooks because one of them runs `hyprctl reload`. Still poke terminal
# emulators so the active upgrade terminal picks up generated theme files.
run_as_user_omarchy omarchy-restart-terminal >/dev/null 2>&1 || true
# apply_system_transition purged user-owned color.json. Headless theme-set
# skipped omarchy-theme-set-browser, so rewrite the colour here.
run_as_user_omarchy omarchy-theme-set-browser >/dev/null 2>&1 ||
warn "Could not apply browser theme colour. Run 'omarchy theme set \"$theme_name\"' after reboot if Chromium's theme looks stale."
}
# Everything below mutates the system, so a non-zero exit from here on leaves a