agentsclimarketplace

Detecting debug endpoints

Skill jeremylongshore/claude-code-plugins-plus-skills/plugins/security/penetration-tester/skills/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.

Install
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill detecting-debug-endpoints

Assembled 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

FindingSeverityThresholdAffected control
Spring Boot Actuator /env exposedCRITICAL200 + body has "propertySources"OWASP A05:2021
Spring Boot Actuator /heapdump exposedCRITICAL200 + Content-Type: application/octet-stream + multi-MB bodyCWE-200
Spring Boot Actuator /jolokia exposedCRITICAL200 + body has "agent":"jolokia"CWE-749
phpMyAdmin reachableCRITICAL200 + HTML body contains "phpMyAdmin" + login formOWASP A07:2021
Prometheus /metrics exposedHIGH200 + body has # HELP or # TYPE linesCWE-200
Apache mod_status exposedHIGH200 + body contains "Apache Server Status"CWE-200
Spring Boot Actuator /actuator indexHIGH200 + body has "_links" JSONOWASP A05:2021
Generic /admin returning 200 (not 401/403)HIGH200 + HTML body with admin-shaped UICWE-285
Elasticsearch _cat exposedHIGH200 + body matches health\s+status\s+indexCWE-200
GraphQL Playground on prodMEDIUM200 + body contains "GraphQLPlayground"CWE-200
Swagger UI on prodMEDIUM200 + body contains "swagger-ui"CWE-200
Spring Boot Actuator /health exposedMEDIUM200 + body has "status":"UP"CWE-200
phpinfo page on prodMEDIUM200 + body has PHP Version headingCWE-200
/robots.txt discloses admin pathsLOW200 + Disallow: lines mentioning /adminCWE-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-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

- 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-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.
  • 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 fingerprints
  • references/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

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.