Probe a target for accidentally-public admin / debug / introspection
endpoints — Spring Boot Actuator, Apache server-status, Prometheus
metrics, GraphQL playground, Swagger UI, phpMyAdmin, JMX-over-HTTP
(Jolokia), Elasticsearch _cat, Kibana / Grafana / Eureka / Consul
panels.
Use when: post-deploy verification, security audit before SOC2,
inheriting a system you didn't build, or a bug bounty hints at an
exposed introspection panel.
Threshold: any of the canonical 40+ admin/debug paths returns 200,
302 to a login, or framework-specific JSON shape (e.g., Actuator
returning a _links object, server-status HTML body containing
the Apache Server Status title).
Trigger with: "check debug endpoints", "actuator exposure", "admin
panel scan", "graphql playground check".
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Probe a target for accidentally-public admin / debug / introspection
endpoints — Spring Boot Actuator, Apache server-status, Prometheus
metrics, GraphQL playground, Swagger UI, phpMyAdmin, JMX-over-HTTP
(Jolokia), Elasticsearch _cat, Kibana / Grafana / Eureka / Consul
panels.
Use when: post-deploy verification, security audit before SOC2,
inheriting a system you didn't build, or a bug bounty hints at an
exposed introspection panel.
Threshold: any of the canonical 40+ admin/debug paths returns 200,
302 to a login, or framework-specific JSON shape (e.g., Actuator
returning a _links object, server-status HTML body containing
the Apache Server Status title).
Trigger with: "check debug endpoints", "actuator exposure", "admin
panel scan", "graphql playground check".
Modern web stacks ship rich introspection by default. Spring Boot
Actuator exposes /actuator/env (every environment variable),
/actuator/heapdump (a live heap snapshot that contains credentials),
/actuator/jolokia (JMX bean invocation = pre-auth RCE in some
configurations). Apache mod_status exposes /server-status with
internal IPs, request counts, and the URL of every active request.
Prometheus /metrics exposes operational telemetry that often
includes connection-string-bearing labels by accident. phpMyAdmin
exposes the entire database if unauthenticated.
These are not bugs in the frameworks. They're features that ship
enabled-by-default for development convenience and stay enabled in
production because nobody disabled them at install time. The probe
set covers the canonical 40+ paths and grades each by the response
fingerprint specific to that framework.
When the skill produces findings
Finding
Severity
Threshold
Affected control
Spring Boot Actuator /env exposed
CRITICAL
200 + body has "propertySources"
OWASP A05:2021
Spring Boot Actuator /heapdump exposed
CRITICAL
200 + Content-Type: application/octet-stream + multi-MB body
CWE-200
Spring Boot Actuator /jolokia exposed
CRITICAL
200 + body has "agent":"jolokia"
CWE-749
phpMyAdmin reachable
CRITICAL
200 + HTML body contains "phpMyAdmin" + login form
OWASP A07:2021
Prometheus /metrics exposed
HIGH
200 + body has # HELP or # TYPE lines
CWE-200
Apache mod_status exposed
HIGH
200 + body contains "Apache Server Status"
CWE-200
Spring Boot Actuator /actuator index
HIGH
200 + body has "_links" JSON
OWASP A05:2021
Generic /admin returning 200 (not 401/403)
HIGH
200 + HTML body with admin-shaped UI
CWE-285
Elasticsearch _cat exposed
HIGH
200 + body matches health\s+status\s+index
CWE-200
GraphQL Playground on prod
MEDIUM
200 + body contains "GraphQLPlayground"
CWE-200
Swagger UI on prod
MEDIUM
200 + body contains "swagger-ui"
CWE-200
Spring Boot Actuator /health exposed
MEDIUM
200 + body has "status":"UP"
CWE-200
phpinfo page on prod
MEDIUM
200 + body has PHP Version heading
CWE-200
/robots.txt discloses admin paths
LOW
200 + Disallow: lines mentioning /admin
CWE-200
Prerequisites
Python 3.9+ with requests
Authorization for non-local targets
Instructions
Step 1 — Confirm Authorization
"Do you have authorization to perform admin / debug endpoint
discovery on this target? I need confirmation before proceeding."
Usage: probe_debug.py URL [OPTIONS]
Options:
--authorized Attest authorization (required for non-local)
--output FILE Write findings to FILE
--format FMT json | jsonl | markdown (default: markdown)
--min-severity SEV (default: info)
--timeout SECS Per-probe timeout (default: 10)
--paths-file FILE Override the default probe set with a custom list
--include-redirects Treat 302/303 to /login as findings (debug panel
exists but auth gates it — still worth noting)
The scanner sends a GET for each path. For 200 responses, it inspects
the body for the framework-specific fingerprint to confirm a true
positive (not the app's SPA index page). For 302 responses to common
login paths, the panel exists but auth is in front — flagged only
with --include-redirects.
Step 3 — Interpret findings
CRITICAL = direct compromise vector (env vars / heapdump / Jolokia /
phpMyAdmin). Ship same-hour fix: take the endpoint behind authn or
disable it. Audit for prior exploitation.
HIGH = information disclosure substantial enough to drive subsequent
attacks (server-status reveals request URLs including session tokens
in query strings; /metrics labels often contain connection strings;
/admin reachable means brute-force can start).
MEDIUM = posture hardening (health checks, swagger).
Step 4 — Cross-skill chaining
After this skill, suggest:
detecting-exposed-secrets-files (#6) — same deploy mistake. If
/server-status is reachable, .git/ often is too.
auditing-cors-policy (#3) — if a GraphQL or admin endpoint is
reachable AND has open CORS, the attack chain compounds.
Examples
Example 1 — Inheriting a system audit
User: "We just acquired example.io. Quick audit of admin surface."
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-debug-endpoints/scripts/probe_debug.py \
https://example.io --authorized --min-severity medium
Commonly surfaces forgotten /server-status on Apache hosts,
/actuator/* left enabled from Spring Boot defaults, leftover
/phpmyadmin from initial install.
Example 2 — Spring Boot Actuator paranoia sweep
User: "We use Spring Boot heavily. Show me everywhere Actuator is
reachable."
for ENDPOINT in $(cat spring-services.txt); do
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-debug-endpoints/scripts/probe_debug.py \
"$ENDPOINT" --authorized --format jsonl
done | jq 'select(.title | contains("Actuator"))'
Example 3 — CI gate against accidental re-enablement
Exit 1 fails the deploy if any HIGH or CRITICAL endpoint exposure
appears. Catches the regression where a debug profile gets enabled
in a application-prod.yml by accident.
SPA catches every URL with 200 → use --check-only semantics
(default: fingerprint check filters out SPA matches).
WAF / CDN blocks the scanner → expected for some targets.
Coordinate with the target's security team for an allowlist; or
run the scanner from inside the target's network if you have
authorized internal access.