Skip to content
Back to skills

Detecting Directory Listing

ASecurity

Probe a target for directories that return auto-generated index listings instead of denying or serving a specific file — exposes the full file tree under any reachable directory, including files the application never linked to. Use when: post-deploy verification on a static-asset host, security audit before SOC2, or following up on a finding from skill #6 (exposed-files) where a backup-file path returned 200 with HTML body instead of the expected file content (suggests autoindex serving a dir...

  • 2,719 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 21, 2026
ai-agentspythonphpbashnodeazuregitsecurity

Works with

  • claude code

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill detecting-directory-listing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Detecting Directory Listing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Detecting Directory Listing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jeremylongshore-detecting-directory-listing-c6f4d1fa/badge)](https://www.skillsdirectory.com/skills/jeremylongshore-detecting-directory-listing-c6f4d1fa)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: detecting-directory-listing
description: |
  Probe a target for directories that return auto-generated index
  listings instead of denying or serving a specific file — exposes
  the full file tree under any reachable directory, including files
  the application never linked to.
  Use when: post-deploy verification on a static-asset host, security
  audit before SOC2, or following up on a finding from skill #6
  (exposed-files) where a backup-file path returned 200 with HTML
  body instead of the expected file content (suggests autoindex
  serving a directory listing).
  Threshold: any directory-shaped path returns 200 with HTML body
  matching the framework-specific autoindex fingerprint (nginx
  fancyindex, Apache mod_autoindex Index of/, Caddy browse, Lighttpd
  mod_dirlisting, etc.).
  Trigger with: "directory listing check", "autoindex detection",
  "open directory scan".
allowed-tools:
  - Read
  - Bash(python3:*)
  - Bash(curl:*)
disallowed-tools:
  - Bash(rm:*)
  - Edit(/etc/*)
version: 3.30.0
author: Jeremy Longshore <jeremy@intentsolutions.io>
license: MIT
compatibility: Designed for Claude Code
tags:
  - security
  - information-disclosure
  - autoindex
  - pentest
---

# Detecting Directory Listing

## Overview

Web servers can be configured to auto-generate an HTML index page
when a request hits a directory without a matching default file
(no `index.html` / `index.php` / etc.). The auto-generated page
lists every file in the directory. This is by design for static-
file servers and FTP-style file-sharing setups; it's a misconfiguration
on application servers where the file tree was never meant to be
public.

The risk compounds in two ways:

1. **File enumeration without prior knowledge.** Attackers find files
   you didn't link to (backup files, log files, old uploads).
2. **Chaining with exposed-files (#6).** A `/.git/` request that
   returns an autoindex listing reveals every object file under
   `.git/objects/` and confirms the entire repo is reachable for
   GitDumper-style reconstruction.

This skill probes commonly-vulnerable directory paths and grades
each based on the framework-specific autoindex fingerprint.

## When the skill produces findings

| Finding | Severity | Threshold | Affected control |
|---|---|---|---|
| Application-root directory listing | **HIGH** | `/` returns autoindex page | OWASP A05:2021 |
| Backup / upload / log directory listing | **HIGH** | `/backup/`, `/uploads/`, `/logs/`, `/dump/` autoindex | CWE-548 |
| Asset directory listing (`/assets/`, `/static/`) | **MEDIUM** | autoindex on asset dirs (enables file enumeration) | CWE-548 |
| Config directory listing | **CRITICAL** | `/config/`, `/conf/`, `/.config/` autoindex | NIST 800-53 SC-28 |
| VCS subdir listing (chains with skill #6) | **CRITICAL** | `/.git/`, `/.svn/`, `/.hg/` autoindex | NIST 800-53 SC-28 |
| Generic root reachable via autoindex | **MEDIUM** | `/` or arbitrary path autoindex on app server | OWASP A05:2021 |

## Prerequisites

- Python 3.9+ with `requests`
- Authorization for non-local targets

## Instructions

### Step 1 — Confirm Authorization

```text
"Do you have authorization to perform directory-listing discovery on
 this target? I need confirmation before proceeding."
```

### Step 2 — Run the scanner

```bash
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-directory-listing/scripts/probe_directory_listing.py \
    https://target.example.com \
    --authorized
```

Options:

```
Usage: probe_directory_listing.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  Custom probe set (one path per line)
```

For each candidate directory path, the scanner appends a trailing
slash and sends a GET. If the response is 200 and the HTML body
matches one of the canonical autoindex fingerprints (Apache,
nginx, Caddy, Lighttpd, IIS, Python http.server, Node serve, etc.),
it's a finding.

### Step 3 — Interpret findings

CRITICAL = config or VCS directory listing → direct credential or
source-code exposure when combined with skill #6's secret-file
probe. Ship same-hour fix.

HIGH = backup / upload / log / app-root listing → significant file
enumeration. Often reveals backup files (`.bak`, `.swp`, `.orig`),
log files with embedded credentials in URLs, and orphaned uploads
from old releases. Ship within sprint.

MEDIUM = asset directory listing → file enumeration but bounded
risk if asset content is genuinely public. Still better to disable
than to leave on.

### Step 4 — Cross-skill chaining

After this skill, suggest:

- `detecting-exposed-secrets-files` (#6) — if any of the secret-
  file paths (`.git/`, `.env`) return an autoindex page instead of
  the expected file, that's the autoindex feature confirming repo
  exposure.
- `detecting-debug-endpoints` (#7) — directory listings under
  framework paths (`/static/`, `/public/`) sometimes expose
  framework-debug artifacts.

## Examples

### Example 1 — Static-asset host audit

User: "We just spun up a new S3 + CloudFront. Verify autoindex isn't
on by accident."

```bash
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-directory-listing/scripts/probe_directory_listing.py \
    https://cdn.example.com --authorized --min-severity medium
```

S3 buckets configured with `ListBucket` permissions return XML
directory listings; the scanner detects those too.

### Example 2 — Following up on .git exposure

User: "Skill #6 found .git/HEAD exposed. Check if the full directory
is browseable."

```bash
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-directory-listing/scripts/probe_directory_listing.py \
    https://app.example.com --authorized --paths-file <(echo .git/)
```

If the `.git/` probe returns an autoindex listing instead of the
404 it should, the whole repository is reachable for reconstruction
via GitDumper-style tools.

### Example 3 — CI gate against autoindex regression

```yaml
- name: Directory-listing gate
  run: |
    python3 plugins/security/penetration-tester/skills/detecting-directory-listing/scripts/probe_directory_listing.py \
        "${{ secrets.STAGING_URL }}" \
        --authorized --min-severity high
```

Exit 1 fails the deploy if any HIGH or CRITICAL autoindex finding
lands. Catches the regression where a new vhost gets deployed
without the deny-autoindex directive.

## Output

JSON / JSONL / Markdown. Exit codes: 0 clean, 1 high/critical, 2 error.

## Error Handling

- **Target returns SPA index for every URL** → the scanner's
  fingerprint check distinguishes a real autoindex from an SPA
  catch-all. SPAs don't generate autoindex-shaped HTML.
- **WAF blocks the scanner** → expected behavior on
  Cloudflare-fronted hosts. The fingerprint will be of the CDN's
  block page, not the origin.
- **Connection error** → exit 2.

## Resources

- `references/THEORY.md` — Per-server autoindex behavior, fingerprint
  patterns, S3 / GCS / Azure Blob considerations
- `references/PLAYBOOK.md` — Per-server config to disable
  autoindex (nginx `autoindex off`, Apache `Options -Indexes`,
  Caddy disabling browse, etc.) + cloud-storage equivalents
- `../analyzing-tls-config/references/AUTHORIZATION.md` — Active-scan
  authorization pattern

Files in this skill

  • SKILL.md7.3 KB
  • references/PLAYBOOK.md6.6 KB
  • references/THEORY.md6.4 KB
  • scripts/probe_directory_listing.py7.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.