@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,267 @@
|
|
|
1
|
+
# TLS Remediation Playbook — copy-paste templates per finding
|
|
2
|
+
|
|
3
|
+
Match the finding to a row below; the right column is a copy-paste-ready
|
|
4
|
+
config snippet for the relevant server type. Reload (NOT restart) the
|
|
5
|
+
server after applying — restart drops in-flight connections; reload
|
|
6
|
+
preserves them on every server type listed here.
|
|
7
|
+
|
|
8
|
+
## Obsolete protocol (TLSv1.0 / TLSv1.1)
|
|
9
|
+
|
|
10
|
+
### nginx
|
|
11
|
+
|
|
12
|
+
```nginx
|
|
13
|
+
ssl_protocols TLSv1.2 TLSv1.3;
|
|
14
|
+
ssl_prefer_server_ciphers on;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Reload: `nginx -t && systemctl reload nginx`
|
|
18
|
+
|
|
19
|
+
### Caddy
|
|
20
|
+
|
|
21
|
+
TLSv1.2 is the minimum default since Caddy 2.0; no config needed unless
|
|
22
|
+
you've explicitly downgraded. Verify with `caddy adapt --pretty` and
|
|
23
|
+
look for any `min_version` overrides.
|
|
24
|
+
|
|
25
|
+
### Apache (httpd 2.4)
|
|
26
|
+
|
|
27
|
+
```apache
|
|
28
|
+
SSLProtocol TLSv1.2 TLSv1.3
|
|
29
|
+
SSLHonorCipherOrder on
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Reload: `apachectl configtest && systemctl reload httpd`
|
|
33
|
+
|
|
34
|
+
### HAProxy
|
|
35
|
+
|
|
36
|
+
```haproxy
|
|
37
|
+
bind :443 ssl crt /etc/ssl/private/cert.pem ssl-min-ver TLSv1.2
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Reload: `systemctl reload haproxy`
|
|
41
|
+
|
|
42
|
+
### AWS ALB
|
|
43
|
+
|
|
44
|
+
Listener config → Security policy → choose `ELBSecurityPolicy-TLS13-1-2-2021-06` (TLSv1.2+TLSv1.3) or `ELBSecurityPolicy-TLS13-1-3-2021-06` (TLSv1.3 only).
|
|
45
|
+
Console path: EC2 → Load Balancers → your ALB → Listeners tab → edit on the HTTPS listener.
|
|
46
|
+
|
|
47
|
+
### GCP HTTPS Load Balancer
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
gcloud compute ssl-policies create modern-tls \
|
|
51
|
+
--profile MODERN --min-tls-version 1.2
|
|
52
|
+
# then attach to your target proxy:
|
|
53
|
+
gcloud compute target-https-proxies update YOUR_PROXY --ssl-policy modern-tls
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Weak cipher (RC4 / 3DES / NULL / EXPORT)
|
|
57
|
+
|
|
58
|
+
### nginx (Mozilla intermediate)
|
|
59
|
+
|
|
60
|
+
```nginx
|
|
61
|
+
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
|
62
|
+
ssl_prefer_server_ciphers off;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Caddy
|
|
66
|
+
|
|
67
|
+
Default cipher list is already safe. To explicitly set:
|
|
68
|
+
|
|
69
|
+
```caddy
|
|
70
|
+
example.com {
|
|
71
|
+
tls {
|
|
72
|
+
ciphers TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Apache
|
|
78
|
+
|
|
79
|
+
```apache
|
|
80
|
+
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### HAProxy
|
|
84
|
+
|
|
85
|
+
```haproxy
|
|
86
|
+
bind :443 ssl crt /etc/ssl/private/cert.pem \
|
|
87
|
+
ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 \
|
|
88
|
+
ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Certificate expires soon
|
|
92
|
+
|
|
93
|
+
### Let's Encrypt via certbot
|
|
94
|
+
|
|
95
|
+
Verify the renewal timer is healthy:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
systemctl status certbot.timer
|
|
99
|
+
sudo certbot renew --dry-run
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Force renewal in an emergency:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
sudo certbot renew --force-renewal
|
|
106
|
+
sudo systemctl reload nginx # or apache / haproxy
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Caddy auto-issuance
|
|
110
|
+
|
|
111
|
+
Caddy auto-renews; if it's failing, check logs:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
journalctl -u caddy -n 200 | grep -i tls
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Common cause: ACME challenge failure due to firewall blocking port 80
|
|
118
|
+
(HTTP-01) or DNS API credentials expired (DNS-01).
|
|
119
|
+
|
|
120
|
+
### AWS ACM
|
|
121
|
+
|
|
122
|
+
Renewal is automatic for ACM-issued certs. If the cert shows "Pending
|
|
123
|
+
renewal" for >7 days, ACM cannot validate ownership — usually because
|
|
124
|
+
the CNAME validation record is missing or pointing to an old cert.
|
|
125
|
+
Re-issue the validation record from the ACM console.
|
|
126
|
+
|
|
127
|
+
## Certificate hostname mismatch
|
|
128
|
+
|
|
129
|
+
You will need to reissue the cert with the correct SAN list. There is no
|
|
130
|
+
runtime-only fix.
|
|
131
|
+
|
|
132
|
+
### Let's Encrypt — single-cert SAN reissuance
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
sudo certbot certonly --nginx \
|
|
136
|
+
-d example.com \
|
|
137
|
+
-d www.example.com \
|
|
138
|
+
-d api.example.com \
|
|
139
|
+
--expand
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The `--expand` flag tells Let's Encrypt to expand an existing cert with
|
|
143
|
+
additional SANs rather than issue a new cert.
|
|
144
|
+
|
|
145
|
+
### Caddy
|
|
146
|
+
|
|
147
|
+
Just list every hostname in your Caddyfile; Caddy issues separate certs
|
|
148
|
+
per hostname automatically, or you can request one cert with SAN
|
|
149
|
+
via the `tls.issuance_policy` block (advanced).
|
|
150
|
+
|
|
151
|
+
### AWS ACM
|
|
152
|
+
|
|
153
|
+
Request a new cert with all required SANs (you cannot edit SANs on an
|
|
154
|
+
issued ACM cert). After validation, swap the ACM ARN on the ALB
|
|
155
|
+
listener.
|
|
156
|
+
|
|
157
|
+
## Chain trust failure
|
|
158
|
+
|
|
159
|
+
The leaf cert is fine, but the chain to the trusted root is broken.
|
|
160
|
+
Most common cause: the server isn't returning intermediate certs.
|
|
161
|
+
|
|
162
|
+
### Verify locally
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
openssl s_client -connect example.com:443 -showcerts < /dev/null
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Look for **two or three** `BEGIN CERTIFICATE` blocks. One = chain broken.
|
|
169
|
+
|
|
170
|
+
### nginx
|
|
171
|
+
|
|
172
|
+
```nginx
|
|
173
|
+
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
|
|
174
|
+
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Use `fullchain.pem` (not `cert.pem`) — fullchain includes the
|
|
178
|
+
intermediate.
|
|
179
|
+
|
|
180
|
+
### Apache
|
|
181
|
+
|
|
182
|
+
```apache
|
|
183
|
+
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
|
|
184
|
+
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
|
|
185
|
+
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
On Apache 2.4.8+, fullchain via SSLCertificateFile also works.
|
|
189
|
+
|
|
190
|
+
### Caddy
|
|
191
|
+
|
|
192
|
+
Auto-handled. If you see this finding on Caddy, look at storage
|
|
193
|
+
permissions — Caddy couldn't load the chain from `~/.local/share/caddy/`.
|
|
194
|
+
|
|
195
|
+
## Forward secrecy absent
|
|
196
|
+
|
|
197
|
+
Pure RSA key exchange (TLS_RSA_*) — fix by enabling ECDHE.
|
|
198
|
+
|
|
199
|
+
### nginx
|
|
200
|
+
|
|
201
|
+
```nginx
|
|
202
|
+
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:...;
|
|
203
|
+
ssl_ecdh_curve secp384r1:secp521r1;
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Generic — use Mozilla's intermediate config
|
|
207
|
+
|
|
208
|
+
Visit [ssl-config.mozilla.org](https://ssl-config.mozilla.org/), pick
|
|
209
|
+
your server type + version, paste the generated config. Every snippet
|
|
210
|
+
in that generator enables ECDHE by default.
|
|
211
|
+
|
|
212
|
+
## Weak key size
|
|
213
|
+
|
|
214
|
+
Reissue the cert with adequate key size. Modern issuance defaults are
|
|
215
|
+
2048-bit RSA or P-256 ECDSA — both meet the floor.
|
|
216
|
+
|
|
217
|
+
### Let's Encrypt — request RSA 4096 or ECDSA P-384
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
sudo certbot certonly --nginx \
|
|
221
|
+
-d example.com \
|
|
222
|
+
--key-type rsa --rsa-key-size 4096
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Or:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
sudo certbot certonly --nginx \
|
|
229
|
+
-d example.com \
|
|
230
|
+
--key-type ecdsa --elliptic-curve secp384r1
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### AWS ACM
|
|
234
|
+
|
|
235
|
+
Request → "Request a public certificate" → "Algorithm" → choose
|
|
236
|
+
`RSA 2048`, `ECDSA P-256`, or stronger.
|
|
237
|
+
|
|
238
|
+
## Validation after remediation
|
|
239
|
+
|
|
240
|
+
After applying any fix, re-run this skill:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
python3 ${CLAUDE_PLUGIN_ROOT}/skills/analyzing-tls-config/scripts/analyze_tls.py \
|
|
244
|
+
https://example.com \
|
|
245
|
+
--authorized \
|
|
246
|
+
--min-severity high
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Expected: exit code 0, no HIGH or CRITICAL findings.
|
|
250
|
+
|
|
251
|
+
For ongoing posture monitoring, embed the scanner in CI:
|
|
252
|
+
|
|
253
|
+
```yaml
|
|
254
|
+
# GitHub Actions example
|
|
255
|
+
- name: TLS posture check
|
|
256
|
+
run: |
|
|
257
|
+
python3 plugins/security/penetration-tester/skills/analyzing-tls-config/scripts/analyze_tls.py \
|
|
258
|
+
"${{ secrets.PROD_URL }}" \
|
|
259
|
+
--authorized \
|
|
260
|
+
--min-severity high \
|
|
261
|
+
--format json \
|
|
262
|
+
--output tls-report.json
|
|
263
|
+
- uses: actions/upload-artifact@v4
|
|
264
|
+
with:
|
|
265
|
+
name: tls-report
|
|
266
|
+
path: tls-report.json
|
|
267
|
+
```
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# TLS Theory — what this skill checks and why each check matters
|
|
2
|
+
|
|
3
|
+
## TLS handshake in one paragraph
|
|
4
|
+
|
|
5
|
+
A client opens a TCP connection to the server's TLS port. They negotiate a
|
|
6
|
+
**protocol version** (TLSv1.0–1.3), pick a **cipher suite** describing how
|
|
7
|
+
to authenticate, exchange keys, and bulk-encrypt, then exchange the
|
|
8
|
+
server's **certificate chain**. The client verifies the chain validates
|
|
9
|
+
to a trusted root and the leaf cert's SAN/CN matches the hostname it
|
|
10
|
+
intended to reach. If any step fails, the handshake aborts. If every step
|
|
11
|
+
succeeds, both sides derive session keys and switch to encrypted
|
|
12
|
+
application data.
|
|
13
|
+
|
|
14
|
+
Every check this skill performs maps to one of those four phases
|
|
15
|
+
(protocol, cipher, cert, hostname). A finding tells you which phase
|
|
16
|
+
landed in a posture below current best practice.
|
|
17
|
+
|
|
18
|
+
## Why protocol version matters
|
|
19
|
+
|
|
20
|
+
Each TLS version has known weaknesses that have driven the IETF and
|
|
21
|
+
NIST to mark them obsolete:
|
|
22
|
+
|
|
23
|
+
- **SSLv2/SSLv3** — DROWN (CVE-2016-0800), POODLE (CVE-2014-3566). Deprecated
|
|
24
|
+
by RFC 7568 (SSLv3) and RFC 6176 (SSLv2). Should never appear on any
|
|
25
|
+
production endpoint.
|
|
26
|
+
- **TLSv1.0** — BEAST (CVE-2011-3389), block-cipher IV-reuse vulnerabilities.
|
|
27
|
+
Deprecated by RFC 8996 (March 2021). PCI DSS forbids since v3.1 (2015).
|
|
28
|
+
- **TLSv1.1** — same RFC 8996 deprecation. Inherited TLSv1.0's MAC-then-encrypt
|
|
29
|
+
pattern with no AEAD support.
|
|
30
|
+
- **TLSv1.2** — current acceptable minimum. AEAD support via GCM and
|
|
31
|
+
ChaCha20-Poly1305 cipher suites. Required by NIST 800-52r2.
|
|
32
|
+
- **TLSv1.3** — preferred. RFC 8446 (2018). Reduces handshake round trips,
|
|
33
|
+
removes legacy options entirely, mandates forward secrecy.
|
|
34
|
+
|
|
35
|
+
Primary references:
|
|
36
|
+
|
|
37
|
+
- [RFC 8996 — Deprecating TLS 1.0 and TLS 1.1](https://datatracker.ietf.org/doc/html/rfc8996)
|
|
38
|
+
- [NIST SP 800-52r2 §3.1](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf)
|
|
39
|
+
- [PCI DSS v4.0 Req 4.2.1.1](https://www.pcisecuritystandards.org/)
|
|
40
|
+
|
|
41
|
+
## Why cipher suite matters
|
|
42
|
+
|
|
43
|
+
A cipher suite in TLSv1.2 names four algorithms:
|
|
44
|
+
`TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` =
|
|
45
|
+
ECDHE (key exchange) + RSA (auth) + AES-256-GCM (bulk) + SHA384 (HMAC for PRF).
|
|
46
|
+
|
|
47
|
+
A weak cipher in any axis weakens the whole connection:
|
|
48
|
+
|
|
49
|
+
- **NULL** ciphers — no encryption. Any in-path attacker reads cleartext.
|
|
50
|
+
Used historically for negotiation testing; should never be permitted.
|
|
51
|
+
- **EXPORT** ciphers — intentionally weakened in the 1990s to comply with
|
|
52
|
+
US export controls. Broken (FREAK CVE-2015-0204, Logjam CVE-2015-4000).
|
|
53
|
+
- **aNULL** (anonymous DH) — no server authentication. MITM trivially.
|
|
54
|
+
- **RC4** — biased keystream byte distribution makes plaintext recovery
|
|
55
|
+
feasible at scale ([RFC 7465](https://datatracker.ietf.org/doc/html/rfc7465)).
|
|
56
|
+
- **3DES** — 64-bit block size makes Sweet32 (CVE-2016-2183) practical
|
|
57
|
+
for long-lived sessions.
|
|
58
|
+
- **CBC-mode without AEAD** — vulnerable to padding-oracle attacks
|
|
59
|
+
(Lucky13, POODLE). AEAD modes (GCM, CCM, ChaCha20-Poly1305) eliminate
|
|
60
|
+
the class.
|
|
61
|
+
- **Non-(EC)DHE key exchange** — no forward secrecy. If the server key is
|
|
62
|
+
later compromised, all past traffic an attacker captured decrypts.
|
|
63
|
+
|
|
64
|
+
Mozilla maintains the canonical "what's safe to use" recommendation at
|
|
65
|
+
[ssl-config.mozilla.org](https://ssl-config.mozilla.org/). The
|
|
66
|
+
"intermediate" config is the right default for backward-compat with
|
|
67
|
+
existing browsers; the "modern" config is for greenfield TLSv1.3-only
|
|
68
|
+
deployments.
|
|
69
|
+
|
|
70
|
+
## Why certificate expiry matters
|
|
71
|
+
|
|
72
|
+
Three classes of expiry pain:
|
|
73
|
+
|
|
74
|
+
1. **Service outage** — the next handshake fails, the service is
|
|
75
|
+
unreachable to validating clients. This is the most common security-
|
|
76
|
+
related outage cause in production.
|
|
77
|
+
2. **Forced rotation noise** — short-notice renewals trigger urgent
|
|
78
|
+
change tickets at 2am. Automated renewal (certbot, caddy) is the fix;
|
|
79
|
+
surfacing expiry early gives you time to verify automation is healthy.
|
|
80
|
+
3. **OCSP/CRL window** — even after renewal, OCSP stapling caches the old
|
|
81
|
+
response for some seconds; clients hitting the lag window see slow
|
|
82
|
+
handshakes or transient validation errors.
|
|
83
|
+
|
|
84
|
+
NIST SP 800-52r2 §4.1 mandates lifecycle monitoring. PCI DSS Req 4.2.1
|
|
85
|
+
flags expired certs as cardholder-data-exposure issues.
|
|
86
|
+
|
|
87
|
+
## Why hostname matching matters
|
|
88
|
+
|
|
89
|
+
RFC 6125 §6 requires the client to verify the leaf cert's SAN (or, for
|
|
90
|
+
legacy clients, CN) covers the hostname it dialed. A mismatch means
|
|
91
|
+
either:
|
|
92
|
+
|
|
93
|
+
- The server is mis-configured (cert for `example.com` serving
|
|
94
|
+
`api.example.com` traffic) — operational error.
|
|
95
|
+
- A proxy or load balancer is presenting a different cert than intended —
|
|
96
|
+
configuration drift.
|
|
97
|
+
- An attacker has hijacked DNS or BGP and presented their own cert — the
|
|
98
|
+
client SHOULD reject and surface to the user, but legacy clients may
|
|
99
|
+
not, opening MITM.
|
|
100
|
+
|
|
101
|
+
Wildcard cert handling: `*.example.com` covers `api.example.com` and
|
|
102
|
+
`www.example.com` but NOT `example.com` (the apex) or
|
|
103
|
+
`x.api.example.com` (deeper sub). This skill's `_check_hostname`
|
|
104
|
+
implements the RFC 6125 rules precisely.
|
|
105
|
+
|
|
106
|
+
## Why key size matters
|
|
107
|
+
|
|
108
|
+
Brute-force resistance against current attacker compute:
|
|
109
|
+
|
|
110
|
+
- **RSA < 2048 bits** — factoring within reach for sustained adversary
|
|
111
|
+
effort (1024-bit broken by 2003 academic teams; 2048 still considered
|
|
112
|
+
safe through ~2030 per NIST SP 800-57).
|
|
113
|
+
- **ECDSA < 256 bits** — discrete-log over weak curves vulnerable to
|
|
114
|
+
Pollard rho. 256-bit curves (P-256, Curve25519) are the current floor.
|
|
115
|
+
|
|
116
|
+
NIST SP 800-52r2 §3.4 mandates these floors. PCI DSS Req 4.2.1.1
|
|
117
|
+
includes "strong cryptography" requirement; the SAQ glossary defines
|
|
118
|
+
"strong" by the same NIST bands.
|
|
119
|
+
|
|
120
|
+
## Primary sources
|
|
121
|
+
|
|
122
|
+
- [NIST SP 800-52r2 — Guidelines for the Selection, Configuration, and Use of TLS Implementations](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf)
|
|
123
|
+
- [NIST SP 800-57 — Recommendation for Key Management](https://csrc.nist.gov/projects/key-management/key-management-guidelines)
|
|
124
|
+
- [Mozilla TLS Configuration Generator](https://ssl-config.mozilla.org/)
|
|
125
|
+
- [RFC 8446 — TLS 1.3](https://datatracker.ietf.org/doc/html/rfc8446)
|
|
126
|
+
- [RFC 8996 — Deprecating TLS 1.0 and TLS 1.1](https://datatracker.ietf.org/doc/html/rfc8996)
|
|
127
|
+
- [RFC 6125 — Server Hostname Verification](https://datatracker.ietf.org/doc/html/rfc6125)
|
|
128
|
+
- [RFC 7465 — Prohibiting RC4 Cipher Suites](https://datatracker.ietf.org/doc/html/rfc7465)
|