65 lines
2.4 KiB
Bash
65 lines
2.4 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
#
|
||
|
|
# extract.sh — pre-extract symlink scan + cpmove untar.
|
||
|
|
#
|
||
|
|
# Usage: extract.sh <tarball> <dest> <username>
|
||
|
|
#
|
||
|
|
# Calls scripts/lib/scan-symlinks.php first; if it reports any DANGEROUS
|
||
|
|
# findings we abort BEFORE tar runs (per spec §0 step 2). On clean,
|
||
|
|
# extracts with the same hardening flags CpanelBackupImporter::extractBackup
|
||
|
|
# uses on the panel today (see web-files/libs/CpanelBackupImporter.php).
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
TARBALL="${1:?usage: extract.sh <tarball> <dest> <username>}"
|
||
|
|
DEST="${2:?usage: extract.sh <tarball> <dest> <username>}"
|
||
|
|
USERNAME="${3:?usage: extract.sh <tarball> <dest> <username>}"
|
||
|
|
|
||
|
|
ts() { date -u +'%Y-%m-%dT%H:%M:%SZ'; }
|
||
|
|
log() { printf '[%s] extract: %s\n' "$(ts)" "$*"; }
|
||
|
|
|
||
|
|
[[ -f "$TARBALL" ]] || { log "tarball not found: $TARBALL"; exit 2; }
|
||
|
|
mkdir -p "$DEST"
|
||
|
|
|
||
|
|
# --- pre-extract symlink scan ---------------------------------------------
|
||
|
|
|
||
|
|
log "scanning tarball for dangerous symlinks (cpmove vector check)"
|
||
|
|
SYMLINK_REPORT=$(mktemp -p /tmp scan-symlinks.XXXXXX.json)
|
||
|
|
if ! php /scripts/lib/scan-symlinks.php \
|
||
|
|
--tarball "$TARBALL" \
|
||
|
|
--username "$USERNAME" \
|
||
|
|
--report "$SYMLINK_REPORT"; then
|
||
|
|
log "scan-symlinks.php exited non-zero"
|
||
|
|
cat "$SYMLINK_REPORT" >&2 || true
|
||
|
|
log "ABORT: tarball contains dangerous symlinks; aborting"
|
||
|
|
# Propagate the report on stdout so entrypoint.sh can include it
|
||
|
|
# in the failure record.
|
||
|
|
exit 3
|
||
|
|
fi
|
||
|
|
|
||
|
|
log "symlink scan clean (no DANGEROUS findings)"
|
||
|
|
|
||
|
|
# --- extract --------------------------------------------------------------
|
||
|
|
|
||
|
|
# Detect compression. cpmove can be .tar.gz / .tar.bz2 / .tar.
|
||
|
|
TAR_FLAGS="-xf"
|
||
|
|
case "$TARBALL" in
|
||
|
|
*.tar.gz|*.tgz) TAR_FLAGS="-xzf" ;;
|
||
|
|
*.tar.bz2|*.tbz2) TAR_FLAGS="-xjf" ;;
|
||
|
|
*.tar.xz|*.txz) TAR_FLAGS="-xJf" ;;
|
||
|
|
*.tar) TAR_FLAGS="-xf" ;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
log "extracting with hardened tar flags into $DEST"
|
||
|
|
# Hardening flags (mirrored from CpanelBackupImporter::extractBackup):
|
||
|
|
# --no-same-owner / --no-same-permissions: drop archive-recorded
|
||
|
|
# uid/perm bits so the cpmove can't drop setuid binaries at us.
|
||
|
|
# --no-overwrite-dir: refuse to clobber existing directory metadata,
|
||
|
|
# closing one historical tar-symlink-escape vector.
|
||
|
|
# --absolute-names is NOT used — leading / in a member name is stripped.
|
||
|
|
cd "$DEST"
|
||
|
|
tar --no-same-owner --no-same-permissions --no-overwrite-dir $TAR_FLAGS "$TARBALL"
|
||
|
|
|
||
|
|
log "extracted OK ($(find "$DEST" -type f | wc -l) files)"
|
||
|
|
exit 0
|