@intentsolutionsio/penetration-tester 2.0.0 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +8 -3
- package/README.md +8 -0
- package/commands/pentest.md +5 -0
- package/package.json +8 -3
- package/skills/analyzing-tls-config/SKILL.md +221 -0
- package/skills/analyzing-tls-config/references/AUTHORIZATION.md +133 -0
- package/skills/analyzing-tls-config/references/PLAYBOOK.md +267 -0
- package/skills/analyzing-tls-config/references/THEORY.md +128 -0
- package/skills/analyzing-tls-config/scripts/analyze_tls.py +415 -0
- package/skills/auditing-cors-policy/SKILL.md +186 -0
- package/skills/auditing-cors-policy/references/PLAYBOOK.md +220 -0
- package/skills/auditing-cors-policy/references/THEORY.md +142 -0
- package/skills/auditing-cors-policy/scripts/audit_cors.py +350 -0
- package/skills/auditing-npm-dependencies/SKILL.md +254 -0
- package/skills/auditing-npm-dependencies/references/PLAYBOOK.md +175 -0
- package/skills/auditing-npm-dependencies/references/THEORY.md +122 -0
- package/skills/auditing-npm-dependencies/scripts/audit_npm.py +408 -0
- package/skills/auditing-python-dependencies/SKILL.md +251 -0
- package/skills/auditing-python-dependencies/references/PLAYBOOK.md +193 -0
- package/skills/auditing-python-dependencies/references/THEORY.md +122 -0
- package/skills/auditing-python-dependencies/scripts/audit_python.py +459 -0
- package/skills/checking-http-security-headers/SKILL.md +176 -0
- package/skills/checking-http-security-headers/references/PLAYBOOK.md +212 -0
- package/skills/checking-http-security-headers/references/THEORY.md +137 -0
- package/skills/checking-http-security-headers/scripts/check_headers.py +362 -0
- package/skills/checking-license-compliance/SKILL.md +225 -0
- package/skills/checking-license-compliance/references/PLAYBOOK.md +161 -0
- package/skills/checking-license-compliance/references/THEORY.md +152 -0
- package/skills/checking-license-compliance/scripts/check_licenses.py +461 -0
- package/skills/composing-vulnerability-report/SKILL.md +212 -0
- package/skills/composing-vulnerability-report/references/PLAYBOOK.md +180 -0
- package/skills/composing-vulnerability-report/references/THEORY.md +178 -0
- package/skills/composing-vulnerability-report/scripts/compose_report.py +396 -0
- package/skills/confirming-pentest-authorization/SKILL.md +247 -0
- package/skills/confirming-pentest-authorization/references/PLAYBOOK.md +189 -0
- package/skills/confirming-pentest-authorization/references/THEORY.md +167 -0
- package/skills/confirming-pentest-authorization/scripts/check_authorization.py +457 -0
- package/skills/defining-pentest-scope/SKILL.md +227 -0
- package/skills/defining-pentest-scope/references/PLAYBOOK.md +238 -0
- package/skills/defining-pentest-scope/references/THEORY.md +170 -0
- package/skills/defining-pentest-scope/scripts/define_scope.py +472 -0
- package/skills/detecting-command-injection-patterns/SKILL.md +144 -0
- package/skills/detecting-command-injection-patterns/references/PLAYBOOK.md +302 -0
- package/skills/detecting-command-injection-patterns/references/THEORY.md +206 -0
- package/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py +290 -0
- package/skills/detecting-debug-endpoints/SKILL.md +207 -0
- package/skills/detecting-debug-endpoints/references/PLAYBOOK.md +402 -0
- package/skills/detecting-debug-endpoints/references/THEORY.md +218 -0
- package/skills/detecting-debug-endpoints/scripts/probe_debug.py +518 -0
- package/skills/detecting-directory-listing/SKILL.md +206 -0
- package/skills/detecting-directory-listing/references/PLAYBOOK.md +277 -0
- package/skills/detecting-directory-listing/references/THEORY.md +203 -0
- package/skills/detecting-directory-listing/scripts/probe_directory_listing.py +180 -0
- package/skills/detecting-eval-exec-usage/SKILL.md +128 -0
- package/skills/detecting-eval-exec-usage/references/PLAYBOOK.md +306 -0
- package/skills/detecting-eval-exec-usage/references/THEORY.md +159 -0
- package/skills/detecting-eval-exec-usage/scripts/scan_eval.py +223 -0
- package/skills/detecting-exposed-secrets-files/SKILL.md +179 -0
- package/skills/detecting-exposed-secrets-files/references/PLAYBOOK.md +274 -0
- package/skills/detecting-exposed-secrets-files/references/THEORY.md +174 -0
- package/skills/detecting-exposed-secrets-files/scripts/probe_secrets.py +207 -0
- package/skills/detecting-insecure-deserialization/SKILL.md +148 -0
- package/skills/detecting-insecure-deserialization/references/PLAYBOOK.md +333 -0
- package/skills/detecting-insecure-deserialization/references/THEORY.md +199 -0
- package/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py +250 -0
- package/skills/detecting-sql-injection-patterns/SKILL.md +161 -0
- package/skills/detecting-sql-injection-patterns/references/PLAYBOOK.md +317 -0
- package/skills/detecting-sql-injection-patterns/references/THEORY.md +261 -0
- package/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py +354 -0
- package/skills/detecting-ssl-cert-issues/SKILL.md +182 -0
- package/skills/detecting-ssl-cert-issues/references/PLAYBOOK.md +203 -0
- package/skills/detecting-ssl-cert-issues/references/THEORY.md +133 -0
- package/skills/detecting-ssl-cert-issues/scripts/check_cert_chain.py +481 -0
- package/skills/detecting-weak-cryptography/SKILL.md +147 -0
- package/skills/detecting-weak-cryptography/references/PLAYBOOK.md +466 -0
- package/skills/detecting-weak-cryptography/references/THEORY.md +194 -0
- package/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py +417 -0
- package/skills/fingerprinting-server-software/SKILL.md +191 -0
- package/skills/fingerprinting-server-software/references/PLAYBOOK.md +337 -0
- package/skills/fingerprinting-server-software/references/THEORY.md +183 -0
- package/skills/fingerprinting-server-software/scripts/fingerprint_server.py +347 -0
- package/skills/generating-executive-summary/SKILL.md +261 -0
- package/skills/generating-executive-summary/references/PLAYBOOK.md +201 -0
- package/skills/generating-executive-summary/references/THEORY.md +195 -0
- package/skills/generating-executive-summary/scripts/exec_summary.py +538 -0
- package/skills/mapping-findings-to-owasp-top10/SKILL.md +235 -0
- package/skills/mapping-findings-to-owasp-top10/references/PLAYBOOK.md +193 -0
- package/skills/mapping-findings-to-owasp-top10/references/THEORY.md +160 -0
- package/skills/mapping-findings-to-owasp-top10/scripts/map_owasp.py +540 -0
- package/skills/performing-penetration-testing/SKILL.md +282 -190
- package/skills/performing-penetration-testing/references/OWASP_TOP_10.md +22 -0
- package/skills/performing-penetration-testing/references/REMEDIATION_PLAYBOOK.md +46 -0
- package/skills/performing-penetration-testing/references/SECURITY_HEADERS.md +41 -0
- package/skills/performing-penetration-testing/scripts/code_security_scanner.py +144 -79
- package/skills/performing-penetration-testing/scripts/dependency_auditor.py +116 -93
- package/skills/performing-penetration-testing/scripts/security_scanner.py +574 -446
- package/skills/probing-dangerous-http-methods/SKILL.md +182 -0
- package/skills/probing-dangerous-http-methods/references/PLAYBOOK.md +234 -0
- package/skills/probing-dangerous-http-methods/references/THEORY.md +145 -0
- package/skills/probing-dangerous-http-methods/scripts/probe_methods.py +263 -0
- package/skills/recording-pentest-engagement/SKILL.md +253 -0
- package/skills/recording-pentest-engagement/references/PLAYBOOK.md +203 -0
- package/skills/recording-pentest-engagement/references/THEORY.md +195 -0
- package/skills/recording-pentest-engagement/scripts/record_engagement.py +461 -0
- package/skills/scanning-for-hardcoded-secrets/SKILL.md +215 -0
- package/skills/scanning-for-hardcoded-secrets/references/PLAYBOOK.md +325 -0
- package/skills/scanning-for-hardcoded-secrets/references/THEORY.md +175 -0
- package/skills/scanning-for-hardcoded-secrets/scripts/scan_secrets.py +395 -0
- package/skills/tracing-transitive-vulnerabilities/SKILL.md +235 -0
- package/skills/tracing-transitive-vulnerabilities/references/PLAYBOOK.md +233 -0
- package/skills/tracing-transitive-vulnerabilities/references/THEORY.md +138 -0
- package/skills/tracing-transitive-vulnerabilities/scripts/trace_vulns.py +484 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: probing-dangerous-http-methods
|
|
3
|
+
description: |
|
|
4
|
+
Probe a target for HTTP methods that should not be enabled in
|
|
5
|
+
production — TRACE (XST attack), unrestricted PUT/DELETE,
|
|
6
|
+
DEBUG/CONNECT, WebDAV (PROPFIND/MKCOL/COPY/MOVE), and Allow header
|
|
7
|
+
enumeration.
|
|
8
|
+
Use when: penetration test rules of engagement include HTTP method
|
|
9
|
+
testing, OR a load balancer change went live and you suspect default
|
|
10
|
+
methods were exposed.
|
|
11
|
+
Threshold: TRACE returns 200 on any path (XST), PUT/DELETE returns
|
|
12
|
+
anything other than 405/403/404 on a non-API endpoint, OPTIONS Allow
|
|
13
|
+
header lists DEBUG/CONNECT/PROPFIND, or WebDAV methods succeed.
|
|
14
|
+
Trigger with: "audit http methods", "trace check", "options
|
|
15
|
+
enumeration", "webdav probe".
|
|
16
|
+
allowed-tools:
|
|
17
|
+
- Read
|
|
18
|
+
- Bash(python3:*)
|
|
19
|
+
- Bash(curl:*)
|
|
20
|
+
disallowed-tools:
|
|
21
|
+
- Bash(rm:*)
|
|
22
|
+
- Edit(/etc/*)
|
|
23
|
+
version: 3.0.0-dev
|
|
24
|
+
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
25
|
+
license: MIT
|
|
26
|
+
compatibility: Designed for Claude Code
|
|
27
|
+
tags:
|
|
28
|
+
- security
|
|
29
|
+
- http-methods
|
|
30
|
+
- xst
|
|
31
|
+
- webdav
|
|
32
|
+
- pentest
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
# Probing Dangerous HTTP Methods
|
|
36
|
+
|
|
37
|
+
## Overview
|
|
38
|
+
|
|
39
|
+
Most HTTP methods beyond GET/POST/HEAD are vestigial — leftover from
|
|
40
|
+
WebDAV authoring stacks of the early 2000s, debugging features in
|
|
41
|
+
legacy servers, or default-enabled methods nobody disabled at install
|
|
42
|
+
time. Each enabled method that the application doesn't use is an
|
|
43
|
+
attack surface: TRACE enables Cross-Site Tracing (XST), PUT enables
|
|
44
|
+
arbitrary file upload to unprotected paths, CONNECT enables proxy
|
|
45
|
+
abuse against internal services, WebDAV enables directory manipulation.
|
|
46
|
+
|
|
47
|
+
This skill probes the canonical method set and grades each based on
|
|
48
|
+
its presence and response.
|
|
49
|
+
|
|
50
|
+
## When the skill produces findings
|
|
51
|
+
|
|
52
|
+
| Finding | Severity | Threshold | Affected control |
|
|
53
|
+
|---|---|---|---|
|
|
54
|
+
| TRACE method enabled | **HIGH** | TRACE returns 200 with request echo | OWASP A05:2021, CWE-693 |
|
|
55
|
+
| PUT method enabled outside API path | **HIGH** | PUT returns 200/201/204 on non-API path | CWE-434 |
|
|
56
|
+
| DELETE method enabled outside API path | **HIGH** | DELETE returns 200/204 on non-API path | CWE-285 |
|
|
57
|
+
| CONNECT method enabled | **CRITICAL** | CONNECT returns 200 (proxy abuse open) | CWE-441 |
|
|
58
|
+
| DEBUG method enabled | **HIGH** | DEBUG returns response (legacy IIS / dev servers) | CWE-489 |
|
|
59
|
+
| WebDAV methods enabled (PROPFIND/MKCOL/COPY/MOVE) | **HIGH** | Any return 207 or 201 | CWE-538 |
|
|
60
|
+
| Allow header discloses unused methods | **LOW** | OPTIONS Allow includes methods app doesn't use | CWE-200 |
|
|
61
|
+
| OPTIONS returns full method enumeration | **LOW** | Allow:* or broad list | CWE-200 |
|
|
62
|
+
|
|
63
|
+
## Prerequisites
|
|
64
|
+
|
|
65
|
+
- Python 3.9+
|
|
66
|
+
- Authorization for non-local targets
|
|
67
|
+
|
|
68
|
+
## Instructions
|
|
69
|
+
|
|
70
|
+
### Step 1 — Confirm authorization
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
"Do you have authorization to perform HTTP method probing on this
|
|
74
|
+
target? I need confirmation before proceeding."
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Step 2 — Run the scanner
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
python3 ${CLAUDE_PLUGIN_ROOT}/skills/probing-dangerous-http-methods/scripts/probe_methods.py \
|
|
81
|
+
https://example.com \
|
|
82
|
+
--authorized
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Options:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Usage: probe_methods.py URL [OPTIONS]
|
|
89
|
+
|
|
90
|
+
Options:
|
|
91
|
+
--authorized Attest authorization (required)
|
|
92
|
+
--output FILE
|
|
93
|
+
--format FMT json | jsonl | markdown (default: markdown)
|
|
94
|
+
--min-severity SEV (default: info)
|
|
95
|
+
--timeout SECS
|
|
96
|
+
--is-api Treat URL as API endpoint (relaxes PUT/DELETE checks)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
By default the scanner treats the URL as a non-API endpoint where
|
|
100
|
+
PUT/DELETE should return 405. With `--is-api`, those methods are
|
|
101
|
+
expected and don't trigger findings — only the auth checks behind them
|
|
102
|
+
matter (delegated to other skills).
|
|
103
|
+
|
|
104
|
+
### Step 3 — Interpret findings
|
|
105
|
+
|
|
106
|
+
CRITICAL CONNECT-open = your reverse proxy is letting external clients
|
|
107
|
+
connect to arbitrary internal hosts (e.g., metadata endpoints in
|
|
108
|
+
AWS/GCP). Ship same-hour fix.
|
|
109
|
+
|
|
110
|
+
HIGH TRACE = XST attack open. Combined with any XSS, attacker can
|
|
111
|
+
read HttpOnly cookies via XHR. Ship-within-sprint fix.
|
|
112
|
+
|
|
113
|
+
HIGH WebDAV = file upload + manipulation surface. Audit `references/
|
|
114
|
+
PLAYBOOK.md` § disabling WebDAV.
|
|
115
|
+
|
|
116
|
+
### Step 4 — Cross-skill chaining
|
|
117
|
+
|
|
118
|
+
After this skill, suggest:
|
|
119
|
+
|
|
120
|
+
- `auditing-cors-policy` (#3) if Allow-Methods:* surfaced
|
|
121
|
+
- `detecting-debug-endpoints` (#7) for the broader exposed-feature
|
|
122
|
+
audit if DEBUG/TRACE both fired
|
|
123
|
+
|
|
124
|
+
## Examples
|
|
125
|
+
|
|
126
|
+
### Example 1 — Post-deploy method audit
|
|
127
|
+
|
|
128
|
+
User: "We rolled out a new ALB config. Audit the method surface."
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
python3 ${CLAUDE_PLUGIN_ROOT}/skills/probing-dangerous-http-methods/scripts/probe_methods.py \
|
|
132
|
+
https://api.example.com \
|
|
133
|
+
--authorized --is-api --min-severity high
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Example 2 — TRACE / XST audit after XSS finding
|
|
137
|
+
|
|
138
|
+
User: "Found XSS on /search; checking if XST chain is possible."
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
python3 ${CLAUDE_PLUGIN_ROOT}/skills/probing-dangerous-http-methods/scripts/probe_methods.py \
|
|
142
|
+
https://example.com \
|
|
143
|
+
--authorized
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
If TRACE-enabled finding fires, the XST chain works: attacker XSS
|
|
147
|
+
issues a TRACE request via XHR, the server echoes the request
|
|
148
|
+
(including HttpOnly cookies that XHR-set-cookies access can't normally
|
|
149
|
+
read), JavaScript reads the response body, full session theft.
|
|
150
|
+
|
|
151
|
+
### Example 3 — WebDAV legacy audit on a recently-acquired domain
|
|
152
|
+
|
|
153
|
+
User: "We just acquired example.io — quick method-surface check before
|
|
154
|
+
we re-point DNS."
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
python3 ${CLAUDE_PLUGIN_ROOT}/skills/probing-dangerous-http-methods/scripts/probe_methods.py \
|
|
158
|
+
https://example.io \
|
|
159
|
+
--authorized --min-severity medium
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Often surfaces decade-old WebDAV / DEBUG defaults that nobody disabled
|
|
163
|
+
on the previous owner's stack.
|
|
164
|
+
|
|
165
|
+
## Output
|
|
166
|
+
|
|
167
|
+
JSON / JSONL / Markdown. Exit 0 / 1 / 2 per `lib/report.py`.
|
|
168
|
+
|
|
169
|
+
## Error Handling
|
|
170
|
+
|
|
171
|
+
- **Method returns 405** → expected behavior, no finding
|
|
172
|
+
- **Method returns 403** → access-controlled (acceptable), no finding,
|
|
173
|
+
but INFO note recorded
|
|
174
|
+
- **Method returns 500** → INFO finding flagging error-handling concern
|
|
175
|
+
- **Connection error** → exit 2
|
|
176
|
+
|
|
177
|
+
## Resources
|
|
178
|
+
|
|
179
|
+
- `references/THEORY.md` — Per-method attack semantics
|
|
180
|
+
- `references/PLAYBOOK.md` — How to disable each method per server type
|
|
181
|
+
- `../analyzing-tls-config/references/AUTHORIZATION.md` — Active-scan
|
|
182
|
+
authorization
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# HTTP Methods — Remediation Playbook
|
|
2
|
+
|
|
3
|
+
## Disable TRACE
|
|
4
|
+
|
|
5
|
+
### nginx
|
|
6
|
+
|
|
7
|
+
```nginx
|
|
8
|
+
server {
|
|
9
|
+
listen 443 ssl http2;
|
|
10
|
+
server_name example.com;
|
|
11
|
+
|
|
12
|
+
if ($request_method = TRACE) {
|
|
13
|
+
return 405;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
# ... rest of config ...
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The `if` directive is generally discouraged in nginx, but this is the
|
|
21
|
+
canonical pattern for method filtering and is safe.
|
|
22
|
+
|
|
23
|
+
### Apache (httpd 2.4)
|
|
24
|
+
|
|
25
|
+
```apache
|
|
26
|
+
TraceEnable Off
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This is a server-global directive; place it in the main config.
|
|
30
|
+
|
|
31
|
+
### IIS
|
|
32
|
+
|
|
33
|
+
1. IIS Manager → site → Request Filtering → HTTP Verbs tab.
|
|
34
|
+
2. Click "Deny Verb" → enter `TRACE`.
|
|
35
|
+
3. Apply.
|
|
36
|
+
|
|
37
|
+
### AWS ALB
|
|
38
|
+
|
|
39
|
+
ALB doesn't expose method-level filtering directly. Use a Lambda@Edge
|
|
40
|
+
function or WAF rule:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"Type": "RegexMatchStatement",
|
|
45
|
+
"FieldToMatch": {"Method": {}},
|
|
46
|
+
"RegexString": "^(TRACE|CONNECT|DEBUG|PROPFIND|MKCOL|COPY|MOVE)$",
|
|
47
|
+
"Action": "Block"
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Cloudflare WAF
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
http.request.method in {"TRACE" "CONNECT" "DEBUG" "PROPFIND" "MKCOL" "COPY" "MOVE"}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Action: Block.
|
|
58
|
+
|
|
59
|
+
## Disable CONNECT
|
|
60
|
+
|
|
61
|
+
CONNECT should never be enabled on a public-facing server. If your
|
|
62
|
+
audit found it enabled, the cause is one of:
|
|
63
|
+
|
|
64
|
+
### Apache with mod_proxy as forward proxy
|
|
65
|
+
|
|
66
|
+
Bad:
|
|
67
|
+
|
|
68
|
+
```apache
|
|
69
|
+
ProxyRequests On
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Fix: change to `ProxyRequests Off`. The reverse-proxy `ProxyPass` and
|
|
73
|
+
`ProxyPassReverse` directives still work without it.
|
|
74
|
+
|
|
75
|
+
### nginx misconfigured as forward proxy
|
|
76
|
+
|
|
77
|
+
Check for `proxy_method CONNECT` anywhere in config and remove.
|
|
78
|
+
|
|
79
|
+
### Squid or other proxy software exposed publicly
|
|
80
|
+
|
|
81
|
+
Move the proxy behind authentication or behind a VPN; don't expose it
|
|
82
|
+
publicly.
|
|
83
|
+
|
|
84
|
+
## Disable DEBUG (IIS)
|
|
85
|
+
|
|
86
|
+
1. IIS Manager → site → Handler Mappings.
|
|
87
|
+
2. Find any handler with DEBUG in its verb list (typically aspnet
|
|
88
|
+
handlers).
|
|
89
|
+
3. Edit → remove DEBUG from the Verb field.
|
|
90
|
+
4. Restart IIS.
|
|
91
|
+
|
|
92
|
+
Express dev: ensure `process.env.NODE_ENV === 'production'`. The
|
|
93
|
+
Express dev middleware exposes DEBUG only in non-production mode.
|
|
94
|
+
|
|
95
|
+
## Disable PUT and DELETE on non-API paths
|
|
96
|
+
|
|
97
|
+
### nginx
|
|
98
|
+
|
|
99
|
+
```nginx
|
|
100
|
+
location / {
|
|
101
|
+
limit_except GET POST HEAD {
|
|
102
|
+
deny all;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
location /api/ {
|
|
107
|
+
# API location — all methods allowed; auth handled by upstream
|
|
108
|
+
proxy_pass http://api-backend;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Apache
|
|
113
|
+
|
|
114
|
+
```apache
|
|
115
|
+
<Location />
|
|
116
|
+
<LimitExcept GET POST HEAD>
|
|
117
|
+
Require all denied
|
|
118
|
+
</LimitExcept>
|
|
119
|
+
</Location>
|
|
120
|
+
|
|
121
|
+
<Location /api>
|
|
122
|
+
# API location
|
|
123
|
+
</Location>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Express (Node.js)
|
|
127
|
+
|
|
128
|
+
By default, Express only handles routes you register. To explicitly
|
|
129
|
+
block:
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
app.all('*', (req, res, next) => {
|
|
133
|
+
const allowed = ['GET', 'POST', 'HEAD', 'OPTIONS'];
|
|
134
|
+
if (!allowed.includes(req.method)) {
|
|
135
|
+
return res.status(405).send('Method Not Allowed');
|
|
136
|
+
}
|
|
137
|
+
next();
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Disable WebDAV
|
|
142
|
+
|
|
143
|
+
### nginx
|
|
144
|
+
|
|
145
|
+
Check vhost for any `dav_methods` directive:
|
|
146
|
+
|
|
147
|
+
```nginx
|
|
148
|
+
location / {
|
|
149
|
+
dav_methods off; # explicit
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The default is `off`, but some sample configs enable it implicitly.
|
|
154
|
+
|
|
155
|
+
If your nginx was compiled with `--with-http_dav_module`, recompile
|
|
156
|
+
without it or move to a packaged binary that doesn't include it.
|
|
157
|
+
|
|
158
|
+
### Apache
|
|
159
|
+
|
|
160
|
+
```apache
|
|
161
|
+
# Comment out or remove:
|
|
162
|
+
# LoadModule dav_module modules/mod_dav.so
|
|
163
|
+
# LoadModule dav_fs_module modules/mod_dav_fs.so
|
|
164
|
+
|
|
165
|
+
# If you can't remove the module, deny WebDAV methods explicitly:
|
|
166
|
+
<Location />
|
|
167
|
+
<LimitExcept GET POST HEAD OPTIONS>
|
|
168
|
+
Require all denied
|
|
169
|
+
</LimitExcept>
|
|
170
|
+
</Location>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### IIS
|
|
174
|
+
|
|
175
|
+
Server Manager → Roles & Features → uncheck "WebDAV Publishing" under
|
|
176
|
+
Web Server (IIS) → Common HTTP Features. Restart IIS.
|
|
177
|
+
|
|
178
|
+
Or via PowerShell:
|
|
179
|
+
|
|
180
|
+
```powershell
|
|
181
|
+
Uninstall-WindowsFeature -Name Web-DAV-Publishing
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Restrict OPTIONS Allow header
|
|
185
|
+
|
|
186
|
+
The right approach is to let the framework compute Allow from
|
|
187
|
+
registered routes; most modern frameworks do this by default.
|
|
188
|
+
|
|
189
|
+
### nginx custom Allow response
|
|
190
|
+
|
|
191
|
+
If you need to override:
|
|
192
|
+
|
|
193
|
+
```nginx
|
|
194
|
+
location /api/users {
|
|
195
|
+
if ($request_method = OPTIONS) {
|
|
196
|
+
add_header Allow "GET, POST, PUT, DELETE, OPTIONS";
|
|
197
|
+
return 204;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## CI integration
|
|
203
|
+
|
|
204
|
+
```yaml
|
|
205
|
+
- name: HTTP method probe
|
|
206
|
+
run: |
|
|
207
|
+
python3 plugins/security/penetration-tester/skills/probing-dangerous-http-methods/scripts/probe_methods.py \
|
|
208
|
+
"${{ secrets.PROD_URL }}" \
|
|
209
|
+
--authorized \
|
|
210
|
+
--min-severity high \
|
|
211
|
+
--format json \
|
|
212
|
+
--output method-probe.json
|
|
213
|
+
- run: |
|
|
214
|
+
if jq 'any(.severity == "critical" or .severity == "high")' method-probe.json | grep -q true; then
|
|
215
|
+
echo "::error::Dangerous HTTP method found enabled"
|
|
216
|
+
exit 1
|
|
217
|
+
fi
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Recommended cadence: every deploy + nightly. WAF/LB config drift is
|
|
221
|
+
the most common regression source.
|
|
222
|
+
|
|
223
|
+
## Verification after remediation
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
python3 ${CLAUDE_PLUGIN_ROOT}/skills/probing-dangerous-http-methods/scripts/probe_methods.py \
|
|
227
|
+
https://example.com \
|
|
228
|
+
--authorized \
|
|
229
|
+
--min-severity medium
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Expected: exit 0, no MEDIUM-or-higher findings. INFO findings about
|
|
233
|
+
"OPTIONS Allow discloses unused methods" may persist if your framework's
|
|
234
|
+
default Allow is broad; consider customizing per the section above.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# HTTP Methods — Theory
|
|
2
|
+
|
|
3
|
+
## TRACE and XST
|
|
4
|
+
|
|
5
|
+
RFC 7231 §4.3.8 defines TRACE as a debugging method: the server should
|
|
6
|
+
echo the request back to the client. The intent was diagnostic — see
|
|
7
|
+
exactly what intermediate proxies added or stripped.
|
|
8
|
+
|
|
9
|
+
The problem: in 2003, Jeremiah Grossman demonstrated Cross-Site Tracing
|
|
10
|
+
(XST). An attacker who can execute JavaScript on the origin (e.g., via
|
|
11
|
+
XSS) issues an XHR request with method TRACE. The server echoes the
|
|
12
|
+
request body — including HttpOnly cookies that XHR-set-cookies cannot
|
|
13
|
+
normally read. The attacker's JavaScript reads the response body and
|
|
14
|
+
exfiltrates the cookies.
|
|
15
|
+
|
|
16
|
+
HttpOnly was meant to make session cookies inaccessible to JavaScript;
|
|
17
|
+
TRACE makes them accessible again. The fix is to disable TRACE on
|
|
18
|
+
every web server, period. There is no legitimate production use case
|
|
19
|
+
that requires TRACE.
|
|
20
|
+
|
|
21
|
+
Modern servers ship with TRACE disabled by default. If you see TRACE
|
|
22
|
+
enabled on a target, it's typically a server with hand-rolled config
|
|
23
|
+
that forgot to disable it, or a stale install of older nginx/Apache.
|
|
24
|
+
|
|
25
|
+
## CONNECT
|
|
26
|
+
|
|
27
|
+
CONNECT (RFC 7231 §4.3.6) is for HTTP proxies: the client asks the
|
|
28
|
+
proxy to open a TCP tunnel to a specified destination. Once the tunnel
|
|
29
|
+
is established, the proxy blindly forwards bytes both ways.
|
|
30
|
+
|
|
31
|
+
The danger: if your reverse proxy implements CONNECT, external clients
|
|
32
|
+
can ask it to connect to ARBITRARY internal hosts. The proxy obediently
|
|
33
|
+
opens TCP to internal-database:5432 and forwards bytes. Cloud metadata
|
|
34
|
+
endpoints (169.254.169.254 in AWS / GCP / Azure) are a particular
|
|
35
|
+
prize — they require no authentication, exposing credentials and
|
|
36
|
+
config to anyone who can reach them.
|
|
37
|
+
|
|
38
|
+
nginx and Apache reject CONNECT by default. Seeing CONNECT enabled
|
|
39
|
+
means someone misconfigured `ProxyRequests On` (Apache) or a
|
|
40
|
+
similar nginx pattern.
|
|
41
|
+
|
|
42
|
+
## DEBUG
|
|
43
|
+
|
|
44
|
+
Microsoft's IIS shipped a DEBUG HTTP method for ASP.NET application
|
|
45
|
+
debugging. Sending `DEBUG /path HTTP/1.0` with `Command: stop-debug`
|
|
46
|
+
header would gracefully halt active debugging sessions. The auth model
|
|
47
|
+
was implicit — if you could send the request, you could stop debug.
|
|
48
|
+
|
|
49
|
+
Modern stacks don't use DEBUG. If you see it enabled, the target is
|
|
50
|
+
either:
|
|
51
|
+
|
|
52
|
+
- An older IIS install with debugging features incompletely disabled
|
|
53
|
+
- A development server (Flask dev, Django runserver) exposed publicly
|
|
54
|
+
- A custom server that recognizes the method by accident
|
|
55
|
+
|
|
56
|
+
Any of those is worth investigating.
|
|
57
|
+
|
|
58
|
+
## PUT and DELETE
|
|
59
|
+
|
|
60
|
+
Both are legitimate REST methods. The "dangerous" part is when they're
|
|
61
|
+
exposed on paths the application doesn't actually serve as REST APIs.
|
|
62
|
+
|
|
63
|
+
The classic exploit: server allows PUT on `/uploads/`. Attacker PUTs a
|
|
64
|
+
`.php` (or `.jsp` or `.aspx`) file. Server stores it. Attacker
|
|
65
|
+
requests the file; server-side runtime executes it. Full RCE from one
|
|
66
|
+
unauthenticated PUT.
|
|
67
|
+
|
|
68
|
+
Modern frameworks (Express, FastAPI, Spring, Rails) don't enable
|
|
69
|
+
PUT/DELETE on routes unless you explicitly bind handlers. The danger
|
|
70
|
+
is at the server-software layer: older nginx with WebDAV module
|
|
71
|
+
loaded, older Apache with mod_dav, IIS with WebDAV authoring feature.
|
|
72
|
+
|
|
73
|
+
If the target is an actual REST API (`/api/v1/users/{id}` should
|
|
74
|
+
accept PUT/DELETE with auth), use `--is-api` to suppress the
|
|
75
|
+
PUT/DELETE finding — at that point, the audit moves to skill #21
|
|
76
|
+
(`confirming-pentest-authorization`) and the authentication-validator
|
|
77
|
+
plugin.
|
|
78
|
+
|
|
79
|
+
## WebDAV (PROPFIND, MKCOL, COPY, MOVE)
|
|
80
|
+
|
|
81
|
+
RFC 4918 defines WebDAV — an extension of HTTP for collaborative
|
|
82
|
+
authoring. Methods:
|
|
83
|
+
|
|
84
|
+
- PROPFIND: list directory contents + properties
|
|
85
|
+
- MKCOL: create new directory
|
|
86
|
+
- COPY: copy file/dir on server
|
|
87
|
+
- MOVE: move file/dir on server
|
|
88
|
+
- LOCK/UNLOCK: file locking for collaborative editing
|
|
89
|
+
|
|
90
|
+
In modern web stacks WebDAV is essentially unused. It survives as a
|
|
91
|
+
default in:
|
|
92
|
+
|
|
93
|
+
- Older nginx with `dav_methods` enabled in vhost
|
|
94
|
+
- Apache with mod_dav loaded
|
|
95
|
+
- IIS with WebDAV Publishing role
|
|
96
|
+
|
|
97
|
+
If WebDAV is enabled and any write method (MKCOL, MOVE, COPY) succeeds
|
|
98
|
+
without auth, the consequence is identical to enabling PUT — arbitrary
|
|
99
|
+
file write becomes a code-execution vector if the target serves
|
|
100
|
+
executable file types.
|
|
101
|
+
|
|
102
|
+
PROPFIND alone is information disclosure (directory listing). Bounded
|
|
103
|
+
risk but rarely intentional in 2026.
|
|
104
|
+
|
|
105
|
+
## OPTIONS and Allow header
|
|
106
|
+
|
|
107
|
+
OPTIONS is meant to be informational — "what can I do here?" The
|
|
108
|
+
response's Allow header lists supported methods. This is fine in
|
|
109
|
+
principle.
|
|
110
|
+
|
|
111
|
+
The problem: many servers respond with a broad Allow header that
|
|
112
|
+
includes methods the application doesn't use. Attackers scrape Allow
|
|
113
|
+
to enumerate the method surface and pick targets.
|
|
114
|
+
|
|
115
|
+
The fix isn't to disable OPTIONS (CORS preflight needs it) — it's to
|
|
116
|
+
configure the Allow response to list only methods the application
|
|
117
|
+
actually supports. Many frameworks compute Allow dynamically from
|
|
118
|
+
registered route handlers, which gives you the correct answer for
|
|
119
|
+
free.
|
|
120
|
+
|
|
121
|
+
`Allow: *` is the worst case — server-asserted "anything goes." Even
|
|
122
|
+
when paired with proper handler-level checks, the disclosure of
|
|
123
|
+
"anything is on the table" is information attackers can use.
|
|
124
|
+
|
|
125
|
+
## Why this skill's defaults treat non-API paths strictly
|
|
126
|
+
|
|
127
|
+
The "is-API" assumption is binary in this skill: either the URL is a
|
|
128
|
+
REST API endpoint where PUT/DELETE are expected, or it isn't. In real
|
|
129
|
+
production stacks there are mixed cases — `/api/v1/users` serves PUT,
|
|
130
|
+
`/index.html` doesn't. The right operational pattern is to run this
|
|
131
|
+
skill twice per target with `--is-api` toggled, against representative
|
|
132
|
+
URLs of each type.
|
|
133
|
+
|
|
134
|
+
For monolithic apps where everything is on `/`, treat as non-API and
|
|
135
|
+
fix any PUT/DELETE exposure by adding `limit_except GET POST { deny
|
|
136
|
+
all; }` at the server level.
|
|
137
|
+
|
|
138
|
+
## Primary sources
|
|
139
|
+
|
|
140
|
+
- [RFC 7231 — HTTP/1.1 Semantics §4.3](https://datatracker.ietf.org/doc/html/rfc7231#section-4.3)
|
|
141
|
+
- [RFC 4918 — WebDAV](https://datatracker.ietf.org/doc/html/rfc4918)
|
|
142
|
+
- [OWASP WSTG-CONF-06 — Test HTTP Methods](https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/06-Test_HTTP_Methods)
|
|
143
|
+
- Jeremiah Grossman — Cross-Site Tracing (XST), 2003
|
|
144
|
+
- [CWE-441 — Unintended Proxy or Intermediary](https://cwe.mitre.org/data/definitions/441.html)
|
|
145
|
+
- [CWE-538 — File and Directory Information Exposure](https://cwe.mitre.org/data/definitions/538.html)
|