RKNnoVPN/.github/scripts/check_apk_privacy.sh

63 lines
2.5 KiB
Shell

#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
manifest="${repo_root}/app/app/src/main/AndroidManifest.xml"
kotlin_src="${repo_root}/app/app/src/main/kotlin"
profile_src="${repo_root}/app/app/src/main/kotlin/com/rknnovpn/panel/profile"
runtime_config="${repo_root}/runtime/internal/config/config.go"
module_default_config="${repo_root}/module/defaults/config.json"
fail=0
check_absent_file() {
local label="$1"
local pattern="$2"
local file="$3"
[ -f "${file}" ] || return 0
if grep -En -- "${pattern}" "${file}" | grep -Ev 'tools:node="remove"'; then
echo "::error file=${file},title=${label}::Forbidden APK privacy surface detected"
fail=1
fi
}
check_absent_tree() {
local label="$1"
local pattern="$2"
local dir="$3"
if grep -REn --include='*.kt' -- "${pattern}" "${dir}"; then
echo "::error title=${label}::Forbidden direct APK networking API detected"
fail=1
fi
}
check_present_file() {
local label="$1"
local pattern="$2"
local file="$3"
if ! grep -Eq -- "${pattern}" "${file}"; then
echo "::error file=${file},title=${label}::Expected privacy-preserving default is missing"
fail=1
fi
}
check_present_file "APK INTERNET permission" 'android[.]permission[.]INTERNET' "${manifest}"
check_present_file "APK ACCESS_NETWORK_STATE permission" 'android[.]permission[.]ACCESS_NETWORK_STATE' "${manifest}"
check_absent_file "No OTHER_SENSORS permission" 'android[.]permission[.]OTHER_SENSORS' "${manifest}"
check_absent_file "No boot completed permission" 'android[.]permission[.]RECEIVE_BOOT_COMPLETED' "${manifest}"
check_absent_file "No boot receiver" 'android[.]intent[.]action[.](BOOT_COMPLETED|MY_PACKAGE_REPLACED)|BootReceiver' "${manifest}"
check_absent_file "No VPN service permission" 'android[.]permission[.]BIND_VPN_SERVICE' "${manifest}"
check_absent_file "No VpnService declaration" 'android[.]net[.]VpnService|foregroundServiceType="[^"]*(vpn|dataSync)' "${manifest}"
check_absent_tree "No TUN implementation fields in APK profile domain" 'TunConfig|ipv4Address|autoRoute|strictRoute' "${profile_src}"
check_present_file "Clash API disabled by default" 'APIPort:[[:space:]]+0' "${runtime_config}"
check_absent_file "No default local helper ports in module config" '10808|10809|9090|"api_port"[[:space:]]*:[[:space:]]*[1-9]' "${module_default_config}"
if [ -e "${repo_root}/module/defaults/panel.json" ]; then
echo "::error file=${repo_root}/module/defaults/panel.json,title=No panel defaults::panel.json is not a supported v2 storage artifact"
fail=1
fi
exit "${fail}"