56 lines
2.1 KiB
Bash
Executable File
56 lines
2.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Vector 13: GraphQL Injection & Introspection
|
|
# Desc: GraphQL introspection, injection, batching attacks
|
|
# Detect: /graphql endpoints, query params, POST with query
|
|
# Severity: HIGH
|
|
# Tools: curl
|
|
|
|
vector_graphql() {
|
|
local target="$1"
|
|
local report="$2"
|
|
local findings=0
|
|
local domain=$(echo "$target" | sed 's|https\?://||' | cut -d/ -f1)
|
|
|
|
print_info "Testing GraphQL vectors..."
|
|
|
|
# Check common GraphQL endpoints
|
|
local gql_paths=("/graphql" "/v1/graphql" "/v2/graphql" "/api/graphql" "/graph" "/query" "/gql")
|
|
local base=$(echo "$target" | sed 's|\(https\?://[^/]*\).*|\1|')
|
|
|
|
for path in "${gql_paths[@]}"; do
|
|
local code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 10 "${base}${path}" 2>/dev/null)
|
|
|
|
if [ "$code" != "000" ] && [ "$code" != "404" ]; then
|
|
print_info "Found GraphQL endpoint: ${base}${path} (HTTP $code)"
|
|
|
|
# Test introspection
|
|
local introspection='{"query":"query{__schema{types{name fields{name type{name kind}}}}}"}'
|
|
local response=$(curl -s --connect-timeout 5 --max-time 10 \
|
|
-X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d "$introspection" \
|
|
"${base}${path}" 2>/dev/null)
|
|
|
|
if echo "$response" | grep -qi '"data"' && echo "$response" | grep -qi '__schema\|types\|fields'; then
|
|
print_find "GraphQL Introspection Enabled!" "Full schema available at ${base}${path}"
|
|
|
|
# Extract type names from schema
|
|
local types=$(echo "$response" | jq -r '.data.__schema.types[].name' 2>/dev/null | grep -v '__\|Query\|Mutation\|Subscription\|String\|Int\|Float\|Boolean\|ID' | head -10)
|
|
|
|
echo "SEVERITY: HIGH
|
|
VECTOR: GraphQL Introspection
|
|
DETAIL: GraphQL introspection enabled at ${base}${path} on $target
|
|
EVIDENCE: Full schema accessible
|
|
EXPLOIT: Extract all queries/mutations: query{__schema{types{name fields{name type{name kind}}}}}" > "$REPORTS_DIR/.finding_$(date +%s)_graphql.txt"
|
|
findings=$((findings + 1))
|
|
|
|
if [ -n "$types" ]; then
|
|
print_info "Types found: $types"
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
|
|
return $findings
|
|
}
|