security: harden WeatherAPI cache update script.
0002-security-harden-WeatherAPI-cache-update-script.patch
--- diff --git a/bin/asl3-weatherapi-update.sh b/bin/asl3-weatherapi-update.sh --- a/bin/asl3-weatherapi-update.sh +++ b/bin/asl3-weatherapi-update.sh @@ -1,6 +1,10 @@ +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=bin/asl3-ini.sh +source "$SCRIPT_DIR/asl3-ini.sh" + @@ -8,12 +12,10 @@ if [ ! -f "$CONFIG_FILE" ]; then -# shellcheck disable=SC1090 -source "$CONFIG_FILE" - -: "${API_KEY:=}" -: "${LOCATION:=}" -: "${CACHE_DIR:=/var/cache/asl3-saytime-weather}" +API_KEY="$(asl3_ini_get "$CONFIG_FILE" API_KEY)" +LOCATION="$(asl3_ini_get "$CONFIG_FILE" LOCATION)" +CACHE_DIR="$(asl3_ini_get "$CONFIG_FILE" CACHE_DIR)" +CACHE_DIR="${CACHE_DIR:-/var/cache/asl3-saytime-weather}" @@ -25,15 +27,30 @@ if [ -z "$LOCATION" ]; then +asl3_validate_dir_path "$CACHE_DIR" "CACHE_DIR" + -URL="https://api.weatherapi.com/v1/current.json?key=${API_KEY}&q=$(printf '%s' "$LOCATION" | jq -sRr @uri)&aqi=no" +# Drop stale cache when the configured location changes. +if [ -f "$OUT_ENV" ]; then + cached_location="$(asl3_ini_get "$OUT_ENV" LOCATION_QUERY)" + if [ -n "$cached_location" ] && [ "$cached_location" != "$LOCATION" ]; then + rm -f "$OUT_JSON" "$OUT_ENV" + fi +fi + +encoded_location="$(printf '%s' "$LOCATION" | jq -sRr @uri)" +curl_cfg="$(mktemp "$CACHE_DIR/curl.XXXXXX")" +chmod 600 "$curl_cfg" +trap 'rm -f "$curl_cfg"' EXIT +printf 'url = "https://api.weatherapi.com/v1/current.json?key=%s&q=%s&aqi=no"\n' \ + "$API_KEY" "$encoded_location" > "$curl_cfg" -curl -fsSL --retry 3 --connect-timeout 10 --max-time 30 "$URL" -o "$TMP_JSON" +curl -fsSL --retry 3 --connect-timeout 10 --max-time 30 --config "$curl_cfg" -o "$TMP_JSON" @@ -43,19 +60,23 @@ mv "$TMP_JSON" "$OUT_JSON" + def safe_text: + if . == null then "" else (tostring | gsub("\r|\n"; " ")) end; - "LOCATION_NAME=\(.location.name // "")", - "REGION=\(.location.region // "")", - "COUNTRY=\(.location.country // "")", + "LOCATION_NAME=\(.location.name // "" | safe_text)", + "REGION=\(.location.region // "" | safe_text)", + "COUNTRY=\(.location.country // "" | safe_text)", - "CONDITION=\(.current.condition.text // "")", + "CONDITION=\(.current.condition.text // "" | safe_text)", -chmod 0644 "$OUT_JSON" "$OUT_ENV" +asl3_ini_set "$OUT_ENV" LOCATION_QUERY "$LOCATION" + +chmod 0640 "$OUT_JSON" "$OUT_ENV" --