Keep web app launchers on http(s)
Chromium --app= will run javascript:, file:, and data: URLs. Prefix schemeless input with https as before, then refuse anything else.
This commit is contained in:
@@ -42,6 +42,27 @@ download_icon() {
|
|||||||
[[ -s $2 && $(file -b --mime-type "$2") == image/* ]]
|
[[ -s $2 && $(file -b --mime-type "$2") == image/* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Chromium --app= treats javascript:, file:, and data: as a document to
|
||||||
|
# run. Prefix schemeless input with https as before, then refuse anything
|
||||||
|
# that is not http(s). Desktop-file value escaping is a separate concern
|
||||||
|
# (see open work on the freedesktop string/Exec rules).
|
||||||
|
normalize_webapp_url() {
|
||||||
|
local url=$1
|
||||||
|
if [[ ! $url =~ ^[a-zA-Z][a-zA-Z0-9+.-]*: ]]; then
|
||||||
|
url="https://$url"
|
||||||
|
fi
|
||||||
|
printf '%s' "$url"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_http_url() {
|
||||||
|
local url=$1
|
||||||
|
if [[ $url =~ ^https?:// ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "Error: web app URL must be http or https." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
fetch_site_icon() {
|
fetch_site_icon() {
|
||||||
local site_url="$1" dest="$2"
|
local site_url="$1" dest="$2"
|
||||||
local origin page icon_url
|
local origin page icon_url
|
||||||
@@ -69,9 +90,7 @@ if (( $# < 3 )); then
|
|||||||
echo -e "\e[32mLet's create a new web app you can start with the app launcher.\n\e[0m"
|
echo -e "\e[32mLet's create a new web app you can start with the app launcher.\n\e[0m"
|
||||||
APP_NAME=$(gum input --prompt "Name> " --placeholder "My favorite web app")
|
APP_NAME=$(gum input --prompt "Name> " --placeholder "My favorite web app")
|
||||||
APP_URL=$(gum input --prompt "URL> " --placeholder "https://example.com")
|
APP_URL=$(gum input --prompt "URL> " --placeholder "https://example.com")
|
||||||
if [[ ! $APP_URL =~ ^[a-zA-Z][a-zA-Z0-9+.-]*: ]]; then
|
APP_URL=$(normalize_webapp_url "$APP_URL")
|
||||||
APP_URL="https://$APP_URL"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Try to fetch the site's icon automatically first.
|
# Try to fetch the site's icon automatically first.
|
||||||
mkdir -p "$ICON_DIR"
|
mkdir -p "$ICON_DIR"
|
||||||
@@ -88,10 +107,7 @@ if (( $# < 3 )); then
|
|||||||
INTERACTIVE_MODE=true
|
INTERACTIVE_MODE=true
|
||||||
else
|
else
|
||||||
APP_NAME="$1"
|
APP_NAME="$1"
|
||||||
APP_URL="$2"
|
APP_URL=$(normalize_webapp_url "$2")
|
||||||
if [[ ! $APP_URL =~ ^[a-zA-Z][a-zA-Z0-9+.-]*: ]]; then
|
|
||||||
APP_URL="https://$APP_URL"
|
|
||||||
fi
|
|
||||||
ICON_REF="$3"
|
ICON_REF="$3"
|
||||||
CUSTOM_EXEC="$4" # Optional custom exec command
|
CUSTOM_EXEC="$4" # Optional custom exec command
|
||||||
MIME_TYPES="$5" # Optional mime types
|
MIME_TYPES="$5" # Optional mime types
|
||||||
@@ -104,6 +120,8 @@ if [[ -z $APP_NAME || -z $APP_URL ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
require_http_url "$APP_URL"
|
||||||
|
|
||||||
if [[ -z $ICON_REF ]]; then
|
if [[ -z $ICON_REF ]]; then
|
||||||
ICON_VALUE=$(safe_icon_name "$APP_NAME")
|
ICON_VALUE=$(safe_icon_name "$APP_NAME")
|
||||||
mkdir -p "$ICON_DIR"
|
mkdir -p "$ICON_DIR"
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||||
|
|
||||||
|
tmpdir=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$tmpdir"' EXIT
|
||||||
|
|
||||||
|
home="$tmpdir/home"
|
||||||
|
mkdir -p "$home/.local/share/applications"
|
||||||
|
|
||||||
|
install_webapp() {
|
||||||
|
HOME="$home" "$ROOT/bin/omarchy-webapp-install" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
desktop_for() {
|
||||||
|
printf '%s' "$home/.local/share/applications/$1.desktop"
|
||||||
|
}
|
||||||
|
|
||||||
|
if install_webapp "Example" "https://example.com" "webapp" >"$tmpdir/out" 2>"$tmpdir/err"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
fail "webapp install accepts an https URL" "$(cat "$tmpdir/err")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
desktop=$(desktop_for Example)
|
||||||
|
[[ -f $desktop ]] || fail "webapp install writes a desktop file"
|
||||||
|
grep -Fxq 'Name=Example' "$desktop" || fail "webapp install writes the app name"
|
||||||
|
grep -Fxq 'Exec=omarchy-launch-webapp https://example.com' "$desktop" ||
|
||||||
|
fail "webapp install launches the https URL" "$(cat "$desktop")"
|
||||||
|
pass "webapp install writes an https desktop entry"
|
||||||
|
|
||||||
|
if install_webapp "Plain" "example.org/app" "webapp" >"$tmpdir/out" 2>"$tmpdir/err"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
fail "webapp install prefixes a schemeless URL with https" "$(cat "$tmpdir/err")"
|
||||||
|
fi
|
||||||
|
grep -Fxq 'Exec=omarchy-launch-webapp https://example.org/app' "$(desktop_for Plain)" ||
|
||||||
|
fail "webapp install stores the prefixed https URL" "$(cat "$(desktop_for Plain)")"
|
||||||
|
pass "webapp install prefixes a schemeless URL with https"
|
||||||
|
|
||||||
|
if install_webapp "Local" "https://localhost:47990" "webapp" "omarchy-launch-webapp https://localhost:47990 --ignore-certificate-errors" >"$tmpdir/out" 2>"$tmpdir/err"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
fail "webapp install keeps a custom https exec" "$(cat "$tmpdir/err")"
|
||||||
|
fi
|
||||||
|
grep -Fxq 'Exec=omarchy-launch-webapp https://localhost:47990 --ignore-certificate-errors' "$(desktop_for Local)" ||
|
||||||
|
fail "webapp install writes the custom exec" "$(cat "$(desktop_for Local)")"
|
||||||
|
pass "webapp install keeps a custom https exec"
|
||||||
|
|
||||||
|
for url in "javascript:alert(1)" "file:///etc/passwd" "data:text/html,hi" "ftp://example.com" "ext://x"; do
|
||||||
|
if install_webapp "Bad" "$url" "webapp" >"$tmpdir/out" 2>"$tmpdir/err"; then
|
||||||
|
fail "webapp install refuses '$url'"
|
||||||
|
fi
|
||||||
|
grep -Fq 'must be http or https' "$tmpdir/err" ||
|
||||||
|
fail "webapp install names the scheme refusal for '$url'" "$(cat "$tmpdir/err")"
|
||||||
|
[[ ! -e $(desktop_for Bad) ]] || fail "webapp install does not write a desktop file for '$url'"
|
||||||
|
done
|
||||||
|
pass "webapp install refuses non-http(s) URLs"
|
||||||
Reference in New Issue
Block a user