AUTONOMY DIRECTORATE

๐Ÿ  Main

๐Ÿงช Interactive Apps

๐Ÿ“ฐ News

๐Ÿ›ก๏ธ PQ Crypta Proxy

๐Ÿ‘ค Account

โŸจ QUANTUM ERROR PORTAL โŸฉ

Navigate the Error Dimensions

PQ Crypta Logo

Script Viewer

Red Team Suite › 21_supply_chain.sh

21_supply_chain.sh 127 lines
1 #!/bin/bash
2 # Supply Chain & Dependency Security (black-box perspective)
3 # Checks for exposed dependency manifests, version disclosure, build artifacts
4 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5 source "$SCRIPT_DIR/../config.sh"
6 OUT="$OUT/supply_chain"
7 mkdir -p "$OUT"
8
9 echo '=== SUPPLY CHAIN & DEPENDENCY SECURITY ===' | tee "$OUT/summary.txt"
10
11 BROWSER="$BROWSER_UA"
12
13 # โ”€โ”€ 1. Exposed Dependency Manifests โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
14 echo '' | tee -a "$OUT/summary.txt"
15 echo '--- Exposed Dependency Files ---' | tee -a "$OUT/summary.txt"
16 MANIFESTS=(
17 "/package.json" "/package-lock.json" "/yarn.lock" "/pnpm-lock.yaml"
18 "/composer.json" "/composer.lock"
19 "/requirements.txt" "/Pipfile" "/Pipfile.lock" "/poetry.lock"
20 "/Gemfile" "/Gemfile.lock"
21 "/go.mod" "/go.sum"
22 "/Cargo.toml" "/Cargo.lock"
23 "/pom.xml" "/build.gradle" "/build.gradle.kts"
24 "/vendor/" "/node_modules/" "/bower_components/"
25 "/.npmrc" "/.yarnrc" "/pyproject.toml"
26 )
27 for path in "${MANIFESTS[@]}"; do
28 resp=$(curl -sk -o "$OUT/manifest_check.tmp" -w '%{http_code}' --max-time 8 -A "$BROWSER" "$TARGET$path")
29 if [ "$resp" = "200" ]; then
30 size=$(wc -c < "$OUT/manifest_check.tmp")
31 echo " [!!!] EXPOSED: $path ($size bytes)" | tee -a "$OUT/summary.txt"
32 head -3 "$OUT/manifest_check.tmp" | tee -a "$OUT/summary.txt"
33 else
34 echo " [PASS] $path โ†’ $resp"
35 fi
36 done
37
38 # โ”€โ”€ 2. Version Disclosure via Headers & Responses โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
39 echo '' | tee -a "$OUT/summary.txt"
40 echo '--- Version Disclosure in Headers ---' | tee -a "$OUT/summary.txt"
41 headers=$(curl -sk -I --max-time 10 -A "$BROWSER" "$TARGET/")
42 echo "$headers" | grep -iE 'Server:|X-Powered-By:|X-Generator:|X-Runtime:|X-Version:|X-App-Version:' | tee -a "$OUT/summary.txt"
43 echo "$headers" | grep -iE 'Server:|X-Powered-By:' | grep -qi '\d\.\d' && \
44 echo " [WARN] Version number in header" || echo " [PASS] No version in Server/X-Powered-By" | tee -a "$OUT/summary.txt"
45
46 echo '' | tee -a "$OUT/summary.txt"
47 echo '--- Version Disclosure in API Responses ---' | tee -a "$OUT/summary.txt"
48 resp_body=$(curl -sk --max-time 8 -A "$BROWSER" "$API_TARGET/health")
49 echo "$resp_body" | python3 -c "
50 import sys, json
51 try:
52 d = json.load(sys.stdin)
53 keys = ['version','build','commit','sha','tag','release','runtime','framework','dependencies']
54 found = {k: d.get(k) for k in keys if k in d}
55 if found:
56 print(' [WARN] Version fields in /health response:', found)
57 else:
58 print(' [PASS] No sensitive version fields in /health')
59 except:
60 print(' [INFO] /health not JSON or unavailable')
61 " | tee -a "$OUT/summary.txt"
62
63 # โ”€โ”€ 3. Source Map Exposure (JS source leakage) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
64 echo '' | tee -a "$OUT/summary.txt"
65 echo '--- JavaScript Source Map Exposure ---' | tee -a "$OUT/summary.txt"
66 # Get main page, extract JS files, check for .map URLs
67 js_files=$(curl -sk --max-time 10 -A "$BROWSER" "$TARGET/" | grep -oP 'src="[^"]*\.js[^"]*"' | sed 's/src="//;s/"//' | head -10)
68 found_map=0
69 for jsf in $js_files; do
70 [[ "$jsf" == http* ]] || jsf="$TARGET$jsf"
71 mapurl="${jsf%.js}.js.map"
72 resp=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 8 -A "$BROWSER" "$mapurl")
73 if [ "$resp" = "200" ]; then
74 echo " [!!!] Source map EXPOSED: $mapurl" | tee -a "$OUT/summary.txt"
75 found_map=1
76 fi
77 done
78 [ "$found_map" -eq 0 ] && echo " [PASS] No exposed source maps found" | tee -a "$OUT/summary.txt"
79
80 # โ”€โ”€ 4. Build Artifact & CI/CD Exposure โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
81 echo '' | tee -a "$OUT/summary.txt"
82 echo '--- Build Artifacts & CI/CD Files ---' | tee -a "$OUT/summary.txt"
83 BUILD_PATHS=(
84 "/.github/workflows/" "/.github/actions/" "/.gitlab-ci.yml"
85 "/Dockerfile" "/docker-compose.yml" "/docker-compose.prod.yml"
86 "/.dockerignore" "/Makefile" "/Taskfile.yml"
87 "/deploy.sh" "/release.sh" "/ci.sh"
88 "/.travis.yml" "/Jenkinsfile" "/bitbucket-pipelines.yml"
89 "/dist/" "/build/" "/target/"
90 "/.env.example" "/.env.template"
91 )
92 for path in "${BUILD_PATHS[@]}"; do
93 resp=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 8 -A "$BROWSER" "$TARGET$path")
94 [ "$resp" = "200" ] && echo " [!!!] EXPOSED: $path ($resp)" || echo " [PASS] $path โ†’ $resp" | tee -a "$OUT/summary.txt"
95 done
96
97 # โ”€โ”€ 5. Dependency Confusion Attack Surface โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
98 echo '' | tee -a "$OUT/summary.txt"
99 echo '--- Internal Package Names (dependency confusion check) ---' | tee -a "$OUT/summary.txt"
100 # Pull package names from any exposed manifests and check if they exist on public npm
101 pkg_json=$(curl -sk --max-time 8 -A "$BROWSER" "$TARGET/package.json" 2>/dev/null)
102 if echo "$pkg_json" | python3 -c "import sys,json; json.load(sys.stdin)" 2>/dev/null; then
103 echo "$pkg_json" | python3 -c "
104 import sys, json
105 d = json.load(sys.stdin)
106 deps = {**d.get('dependencies',{}), **d.get('devDependencies',{})}
107 internal = [k for k in deps if not k.startswith('@') and '-internal' in k or 'private' in k or k.startswith('pq')]
108 print(' Internal/private package names found:', internal if internal else 'none')
109 " | tee -a "$OUT/summary.txt"
110 else
111 echo " [PASS] package.json not accessible โ€” dependency confusion surface not exposed" | tee -a "$OUT/summary.txt"
112 fi
113
114 # โ”€โ”€ 6. Subresource Integrity (SRI) on External Scripts โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
115 echo '' | tee -a "$OUT/summary.txt"
116 echo '--- Subresource Integrity (SRI) Check ---' | tee -a "$OUT/summary.txt"
117 page=$(curl -sk --max-time 10 -A "$BROWSER" "$TARGET/")
118 external_no_sri=$(echo "$page" | grep -oP '<script[^>]*src="https?://(?!'"$(echo $TARGET | sed 's|https://||')"')[^"]*"[^>]*>' | grep -v 'integrity=')
119 if [ -n "$external_no_sri" ]; then
120 echo " [WARN] External scripts WITHOUT SRI:" | tee -a "$OUT/summary.txt"
121 echo "$external_no_sri" | head -5 | tee -a "$OUT/summary.txt"
122 else
123 echo " [PASS] All external scripts have SRI or are self-hosted" | tee -a "$OUT/summary.txt"
124 fi
125
126 cat "$OUT/summary.txt"
127