Detecting debug endpoints
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill detecting-debug-endpointsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
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".
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
7.9 KB, as published. Nobody here has run it
Detecting Debug Endpoints
Overview
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."
Step 2 — Run the scanner
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-debug-endpoints/scripts/probe_debug.py \
https://target.example.com \
--authorized
Options:
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-statusis 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
- name: Debug-endpoint guard
run: |
python3 plugins/security/penetration-tester/skills/detecting-debug-endpoints/scripts/probe_debug.py \
"${{ secrets.STAGING_URL }}" \
--authorized --min-severity high
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.
Output
JSON / JSONL / Markdown per lib/report.py. Exit codes: 0 clean, 1
high/critical, 2 error.
Error Handling
- SPA catches every URL with 200 → use
--check-onlysemantics (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.
- Connection error → exit 2 with underlying error.
Resources
references/THEORY.md— Per-framework reasoning: why Actuator, mod_status, Prometheus, GraphQL Playground, Swagger, phpMyAdmin each matter; canonical fingerprintsreferences/PLAYBOOK.md— Per-framework remediation: Spring Boot Actuator authn, Apache mod_status<Location>deny, Prometheus Bearer-token, GraphQL introspection toggle, Swagger profile gate../analyzing-tls-config/references/AUTHORIZATION.md— Active-scan authorization pattern