You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
4.3 KiB
112 lines
4.3 KiB
#!/usr/bin/env bash
|
|
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
|
|
|
|
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"
|
|
}
|
|
|
|
request course-list "$BASE_URL/api/mobile/course/course?page=1&page_size=1"
|
|
request course-list-page-size-51 "$BASE_URL/api/mobile/course/course?page=1&page_size=51"
|
|
request course-detail-invalid "$BASE_URL/api/mobile/course/course-detail?course_id=not-an-id"
|
|
request course-detail-missing "$BASE_URL/api/mobile/course/course-detail?course_id=2147483647"
|
|
|
|
scan_sensitive_keys() {
|
|
local name="$1"
|
|
local body="$TMP_DIR/$name.json"
|
|
local forbidden
|
|
|
|
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
|
|
fi
|
|
printf '%s SENSITIVE_SCAN PASS\n' "$name"
|
|
}
|
|
|
|
list_body="$TMP_DIR/course-list.json"
|
|
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="$(php -r '$d=json_decode(file_get_contents($argv[1]), true); echo $d["data"][0]["id"] ?? "";' "$list_body")"
|
|
fi
|
|
|
|
if [[ -n "$COURSE_ID" ]]; then
|
|
request course-detail-valid "$BASE_URL/api/mobile/course/course-detail?course_id=$COURSE_ID"
|
|
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
|
|
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'
|
|
fi
|
|
else
|
|
printf 'SENSITIVE_SCAN SKIP: course list did not return a data array\n'
|
|
fi
|
|
|
|
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 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 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'
|
|
exit 1
|
|
fi
|