feat: publish generic Telegram WEB proxy stack
This commit is contained in:
Executable
+167
@@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
repository="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
||||
cd "$repository"
|
||||
|
||||
failures=0
|
||||
|
||||
report() {
|
||||
printf 'FAIL: %s\n' "$1" >&2
|
||||
failures=$((failures + 1))
|
||||
}
|
||||
|
||||
scan_file() {
|
||||
local label=$1 file=$2 pattern=$3
|
||||
if LC_ALL=C grep -IqiE -- "$pattern" "$file"; then
|
||||
report "$label in $file"
|
||||
fi
|
||||
}
|
||||
|
||||
collect_matches() {
|
||||
local result_name=$1 label=$2 output status
|
||||
shift 2
|
||||
if output="$(LC_ALL=C "$@" 2>/dev/null)"; then
|
||||
status=0
|
||||
else
|
||||
status=$?
|
||||
fi
|
||||
if ((status > 1)); then
|
||||
report "$label could not complete"
|
||||
output=''
|
||||
fi
|
||||
printf -v "$result_name" '%s' "$output"
|
||||
}
|
||||
|
||||
scan_network_literals() {
|
||||
local file=$1 context=$2 addresses domains address domain
|
||||
collect_matches addresses "IPv4 scan for $context$file" \
|
||||
grep -IhoE -- '([0-9]{1,3}\.){3}[0-9]{1,3}' "$file"
|
||||
while IFS= read -r address; do
|
||||
[[ -z "$address" ]] && continue
|
||||
case "$address" in
|
||||
127.0.0.1 | 0.0.0.0) ;;
|
||||
*) report "unexpected IPv4 literal $address in $context$file" ;;
|
||||
esac
|
||||
done <<<"$(printf '%s\n' "$addresses" | sort -u)"
|
||||
|
||||
collect_matches domains "hostname scan for $context$file" \
|
||||
grep -IhoE -- '([[:alnum:]][[:alnum:]-]*\.)+(com|org|net|ru|io|dev|app|cloud|info|biz|me|ai|local|localhost|de|uk|fr|us|ca|au|ch|nl|se|no|fi|pl|cz|kz|by|ua|su)([^[:alnum:]_.-]|$)' "$file"
|
||||
while IFS= read -r domain; do
|
||||
[[ -z "$domain" ]] && continue
|
||||
domain="$(printf '%s' "$domain" | tr '[:upper:]' '[:lower:]' | sed 's/[^[:alnum:].-]$//')"
|
||||
case "$domain" in
|
||||
github.com | core.telegram.org | example.com | *.example.com | *.localhost | \
|
||||
*.md | *.sh | *.json | *.yml | *.yaml | *.html | *.go | *.js | \
|
||||
*.gz | *.pem | *.key | *.p12 | *.pfx | *.example) ;;
|
||||
*) report "unexpected hostname $domain in $context$file" ;;
|
||||
esac
|
||||
done <<<"$(printf '%s\n' "$domains" | sort -u)"
|
||||
}
|
||||
|
||||
scan_local_denylist() {
|
||||
local file=$1 context=$2 literal
|
||||
[[ -f .audit-private-patterns ]] || return 0
|
||||
while IFS= read -r literal || [[ -n "$literal" ]]; do
|
||||
[[ -z "$literal" || "$literal" == \#* ]] && continue
|
||||
if LC_ALL=C grep -IFqi -- "$literal" "$file"; then
|
||||
report "locally denied identifier in $context$file"
|
||||
fi
|
||||
done < .audit-private-patterns
|
||||
}
|
||||
|
||||
# The scanner contains signatures for credentials, so it is excluded only from
|
||||
# those signature checks. Address, hostname and optional local deny-list checks
|
||||
# still inspect it. Every tracked or untracked file not ignored by Git is read.
|
||||
while IFS= read -r -d '' file; do
|
||||
[[ -f "$file" ]] || continue
|
||||
if [[ "$file" != scripts/audit-public.sh ]]; then
|
||||
scan_file "private-key material" "$file" \
|
||||
'-----BEGIN ([A-Z0-9]+ )?PRIVATE KEY-----'
|
||||
scan_file "access-token pattern" "$file" \
|
||||
'(ptr_|gh[pousr]_|github_pat_|glpat-|xox[baprs]-)[A-Za-z0-9_+/=-]{16,}'
|
||||
scan_file "cloud credential pattern" "$file" \
|
||||
'(AKIA|ASIA)[A-Z0-9]{16}|AIza[0-9A-Za-z_-]{35}'
|
||||
scan_file "credential embedded in URL" "$file" \
|
||||
'https?://[^/:[:space:]]+:[^/@[:space:]]+@'
|
||||
scan_file "Bearer token" "$file" \
|
||||
'Bearer[[:space:]]+[A-Za-z0-9._~+/-]{20,}={0,2}'
|
||||
scan_file "32-hex client secret" "$file" \
|
||||
'(^|[^0-9a-f])[0-9a-f]{32}([^0-9a-f]|$)'
|
||||
scan_file "credential assignment" "$file" \
|
||||
'(api[_-]?key|api[_-]?token|access[_-]?token|password|secret)[[:space:]]*[:=][[:space:]]*[^$[:space:]][A-Za-z0-9_+./=-]{15,}'
|
||||
fi
|
||||
scan_network_literals "$file" ''
|
||||
scan_local_denylist "$file" ''
|
||||
done < <(git ls-files --cached --others --exclude-standard -z)
|
||||
|
||||
while IFS= read -r -d '' file; do
|
||||
case "$file" in
|
||||
.env.example) ;;
|
||||
.env | .env.* | */.env | */.env.* | *client-secret* | *profiles.json | \
|
||||
*.pem | *.key | *.p12 | *.pfx | id_rsa | id_ed25519)
|
||||
report "sensitive filename is tracked: $file"
|
||||
;;
|
||||
esac
|
||||
done < <(git ls-files -z)
|
||||
|
||||
history_pattern='-----BEGIN ([A-Z0-9]+ )?PRIVATE KEY-----|(ptr_|gh[pousr]_|github_pat_|glpat-|xox[baprs]-)[A-Za-z0-9_+/=-]{16,}|(AKIA|ASIA)[A-Z0-9]{16}|AIza[0-9A-Za-z_-]{35}|https?://[^/:[:space:]]+:[^/@[:space:]]+@|Bearer[[:space:]]+[A-Za-z0-9._~+/-]{20,}={0,2}|(^|[^0-9a-f])[0-9a-f]{32}([^0-9a-f]|$)|(api[_-]?key|api[_-]?token|access[_-]?token|password|secret)[[:space:]]*[:=][[:space:]]*[^$[:space:]][A-Za-z0-9_+./=-]{15,}'
|
||||
if revisions="$(git rev-list --all)"; then
|
||||
:
|
||||
else
|
||||
report "Git history could not be enumerated"
|
||||
revisions=''
|
||||
fi
|
||||
while IFS= read -r revision; do
|
||||
[[ -z "$revision" ]] && continue
|
||||
collect_matches matches "credential scan for Git history ${revision:0:12}" \
|
||||
git grep -IilE -- "$history_pattern" "$revision" -- . \
|
||||
':(exclude)scripts/audit-public.sh'
|
||||
if [[ -n "$matches" ]]; then
|
||||
while IFS= read -r match; do
|
||||
report "sensitive content in Git history: $match"
|
||||
done <<<"$matches"
|
||||
fi
|
||||
collect_matches addresses "IPv4 scan for Git history ${revision:0:12}" \
|
||||
git grep -IhoE -- '([0-9]{1,3}\.){3}[0-9]{1,3}' "$revision" -- .
|
||||
while IFS= read -r address; do
|
||||
[[ -z "$address" ]] && continue
|
||||
case "$address" in
|
||||
127.0.0.1 | 0.0.0.0) ;;
|
||||
*) report "unexpected IPv4 literal $address in Git history ${revision:0:12}" ;;
|
||||
esac
|
||||
done <<<"$(printf '%s\n' "$addresses" | sort -u)"
|
||||
|
||||
collect_matches domains "hostname scan for Git history ${revision:0:12}" \
|
||||
git grep -IhoE -- '([[:alnum:]][[:alnum:]-]*\.)+(com|org|net|ru|io|dev|app|cloud|info|biz|me|ai|local|localhost|de|uk|fr|us|ca|au|ch|nl|se|no|fi|pl|cz|kz|by|ua|su)([^[:alnum:]_.-]|$)' "$revision" -- .
|
||||
while IFS= read -r domain; do
|
||||
[[ -z "$domain" ]] && continue
|
||||
domain="$(printf '%s' "$domain" | tr '[:upper:]' '[:lower:]' | sed 's/[^[:alnum:].-]$//')"
|
||||
case "$domain" in
|
||||
github.com | core.telegram.org | example.com | *.example.com | *.localhost | \
|
||||
*.md | *.sh | *.json | *.yml | *.yaml | *.html | *.go | *.js | \
|
||||
*.gz | *.pem | *.key | *.p12 | *.pfx | *.example) ;;
|
||||
*) report "unexpected hostname $domain in Git history ${revision:0:12}" ;;
|
||||
esac
|
||||
done <<<"$(printf '%s\n' "$domains" | sort -u)"
|
||||
done <<<"$revisions"
|
||||
|
||||
while IFS= read -r identity_email; do
|
||||
[[ -z "$identity_email" || "$identity_email" == *noreply* ]] && continue
|
||||
report "personal author or committer e-mail remains in Git history"
|
||||
break
|
||||
done < <(git log --all --format='%ae%n%ce' | sort -u)
|
||||
|
||||
while IFS= read -r identity_name; do
|
||||
[[ -z "$identity_name" || "$identity_name" == Maintainer ]] && continue
|
||||
report "non-generic author or committer name remains in Git history"
|
||||
break
|
||||
done < <(git log --all --format='%an%n%cn' | sort -u)
|
||||
|
||||
if ((failures > 0)); then
|
||||
printf '\nPublic-release audit failed with %d finding(s).\n' "$failures" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Public-release audit passed: no secrets, deployment identifiers or unexpected address literals found."
|
||||
Reference in New Issue
Block a user