From da4aa818f45358ba39f1093b3fe96206f631cf5f Mon Sep 17 00:00:00 2001 From: weizong song Date: Tue, 4 Aug 2026 06:45:21 +0800 Subject: [PATCH] up --- scripts/vuln01_regression.sh | 50 +++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/scripts/vuln01_regression.sh b/scripts/vuln01_regression.sh index 6f236aa..c6cd0a1 100755 --- a/scripts/vuln01_regression.sh +++ b/scripts/vuln01_regression.sh @@ -3,16 +3,33 @@ set -euo pipefail BASE_URL="${BASE_URL:-https://wx.sstbc.com}" COURSE_ID="${COURSE_ID:-}" +CURL_TIMEOUT="${CURL_TIMEOUT:-20}" TMP_DIR="$(mktemp -d)" trap 'rm -rf "$TMP_DIR"' EXIT +if ! command -v php >/dev/null 2>&1; then + printf 'ERROR: php CLI is required to parse API responses\n' >&2 + exit 2 +fi + +CURL_ARGS=(-sS -L --max-time "$CURL_TIMEOUT") +if [[ "${CURL_INSECURE:-0}" == "1" ]]; then + CURL_ARGS+=(-k) +fi + request() { local name="$1" local url="$2" local body="$TMP_DIR/$name.json" local status - status="$(curl -sS --max-time 20 -o "$body" -w '%{http_code}' "$url")" + if ! status="$(curl "${CURL_ARGS[@]}" -o "$body" -w '%{http_code}' "$url")"; then + status="000" + : > "$body" + printf '%-28s HTTP %s REQUEST_FAILED\n' "$name" "$status" + printf '%s\n' "$body" + return 0 + fi printf '%-28s HTTP %s\n' "$name" "$status" printf '%s\n' "$body" } @@ -27,7 +44,22 @@ scan_sensitive_keys() { local body="$TMP_DIR/$name.json" local forbidden - forbidden="$(jq -r '.. | objects | keys[]' "$body" | sort -u | rg -i '^(mobile|idcard|id_card|identity_card|remark|admin_id|department_id|teacher_id|deleted_at|password|remember_token)$' || true)" + forbidden="$(php -r ' + $data = json_decode(file_get_contents($argv[1]), true); + if (!is_array($data)) { exit(2); } + $blocked = ["mobile", "idcard", "id_card", "identity_card", "remark", "admin_id", "department_id", "teacher_id", "deleted_at", "password", "remember_token"]; + $found = []; + $walk = function ($value) use (&$walk, &$found, $blocked) { + if (!is_array($value)) { return; } + foreach ($value as $key => $child) { + if (in_array(strtolower((string) $key), $blocked, true)) { $found[(string) $key] = true; } + $walk($child); + } + }; + $walk($data); + ksort($found); + echo implode(PHP_EOL, array_keys($found)); + ' "$body" || true)" if [[ -n "$forbidden" ]]; then printf '%s FORBIDDEN_KEYS\n%s\n' "$name" "$forbidden" exit 1 @@ -36,10 +68,10 @@ scan_sensitive_keys() { } list_body="$TMP_DIR/course-list.json" -if jq -e '.data and (.data | type == "array")' "$list_body" >/dev/null; then +if php -r '$d=json_decode(file_get_contents($argv[1]), true); exit(is_array($d) && isset($d["data"]) && is_array($d["data"]) ? 0 : 1);' "$list_body"; then scan_sensitive_keys course-list if [[ -z "$COURSE_ID" ]]; then - COURSE_ID="$(jq -r '.data[0].id // empty' "$list_body")" + COURSE_ID="$(php -r '$d=json_decode(file_get_contents($argv[1]), true); echo $d["data"][0]["id"] ?? "";' "$list_body")" fi if [[ -n "$COURSE_ID" ]]; then @@ -47,8 +79,8 @@ if jq -e '.data and (.data | type == "array")' "$list_body" >/dev/null; then request course-detail-pc-valid "$BASE_URL/api/mobile/course/course-detail-pc?course_id=$COURSE_ID" scan_sensitive_keys course-detail-valid scan_sensitive_keys course-detail-pc-valid - jq -e '.id and .name' "$TMP_DIR/course-detail-valid.json" >/dev/null - jq -e '.id and .name' "$TMP_DIR/course-detail-pc-valid.json" >/dev/null + php -r '$d=json_decode(file_get_contents($argv[1]), true); exit(is_array($d) && isset($d["id"], $d["name"]) ? 0 : 1);' "$TMP_DIR/course-detail-valid.json" + php -r '$d=json_decode(file_get_contents($argv[1]), true); exit(is_array($d) && isset($d["id"], $d["name"]) ? 0 : 1);' "$TMP_DIR/course-detail-pc-valid.json" printf 'DETAIL_CORE_FIELDS PASS\n' else printf 'DETAIL_SCAN SKIP: course list is empty\n' @@ -57,21 +89,21 @@ else printf 'SENSITIVE_SCAN SKIP: course list did not return a data array\n' fi -if jq -e '.errcode == 10001' "$TMP_DIR/course-list-page-size-51.json" >/dev/null; then +if php -r '$d=json_decode(file_get_contents($argv[1]), true); exit(is_array($d) && (($d["errcode"] ?? null) === 10001) ? 0 : 1);' "$TMP_DIR/course-list-page-size-51.json"; then printf 'PAGE_SIZE_VALIDATION PASS\n' else printf 'PAGE_SIZE_VALIDATION FAIL\n' exit 1 fi -if [[ "$(jq -r 'type' "$TMP_DIR/course-detail-invalid.json")" == "object" ]] && jq -e '.errcode == 10001' "$TMP_DIR/course-detail-invalid.json" >/dev/null; then +if php -r '$d=json_decode(file_get_contents($argv[1]), true); exit(is_array($d) && (($d["errcode"] ?? null) === 10001) ? 0 : 1);' "$TMP_DIR/course-detail-invalid.json"; then printf 'COURSE_ID_VALIDATION PASS\n' else printf 'COURSE_ID_VALIDATION FAIL\n' exit 1 fi -if [[ "$(jq -r 'type' "$TMP_DIR/course-detail-missing.json")" == "object" ]] && jq -e 'has("message") and .message == "课程不存在"' "$TMP_DIR/course-detail-missing.json" >/dev/null; then +if php -r '$d=json_decode(file_get_contents($argv[1]), true); exit(is_array($d) && (($d["message"] ?? null) === "课程不存在") ? 0 : 1);' "$TMP_DIR/course-detail-missing.json"; then printf 'MISSING_COURSE_VALIDATION PASS\n' else printf 'MISSING_COURSE_VALIDATION FAIL\n'