@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.
Files changed (112) hide show
  1. package/.claude-plugin/plugin.json +8 -3
  2. package/README.md +8 -0
  3. package/commands/pentest.md +5 -0
  4. package/package.json +8 -3
  5. package/skills/analyzing-tls-config/SKILL.md +221 -0
  6. package/skills/analyzing-tls-config/references/AUTHORIZATION.md +133 -0
  7. package/skills/analyzing-tls-config/references/PLAYBOOK.md +267 -0
  8. package/skills/analyzing-tls-config/references/THEORY.md +128 -0
  9. package/skills/analyzing-tls-config/scripts/analyze_tls.py +415 -0
  10. package/skills/auditing-cors-policy/SKILL.md +186 -0
  11. package/skills/auditing-cors-policy/references/PLAYBOOK.md +220 -0
  12. package/skills/auditing-cors-policy/references/THEORY.md +142 -0
  13. package/skills/auditing-cors-policy/scripts/audit_cors.py +350 -0
  14. package/skills/auditing-npm-dependencies/SKILL.md +254 -0
  15. package/skills/auditing-npm-dependencies/references/PLAYBOOK.md +175 -0
  16. package/skills/auditing-npm-dependencies/references/THEORY.md +122 -0
  17. package/skills/auditing-npm-dependencies/scripts/audit_npm.py +408 -0
  18. package/skills/auditing-python-dependencies/SKILL.md +251 -0
  19. package/skills/auditing-python-dependencies/references/PLAYBOOK.md +193 -0
  20. package/skills/auditing-python-dependencies/references/THEORY.md +122 -0
  21. package/skills/auditing-python-dependencies/scripts/audit_python.py +459 -0
  22. package/skills/checking-http-security-headers/SKILL.md +176 -0
  23. package/skills/checking-http-security-headers/references/PLAYBOOK.md +212 -0
  24. package/skills/checking-http-security-headers/references/THEORY.md +137 -0
  25. package/skills/checking-http-security-headers/scripts/check_headers.py +362 -0
  26. package/skills/checking-license-compliance/SKILL.md +225 -0
  27. package/skills/checking-license-compliance/references/PLAYBOOK.md +161 -0
  28. package/skills/checking-license-compliance/references/THEORY.md +152 -0
  29. package/skills/checking-license-compliance/scripts/check_licenses.py +461 -0
  30. package/skills/composing-vulnerability-report/SKILL.md +212 -0
  31. package/skills/composing-vulnerability-report/references/PLAYBOOK.md +180 -0
  32. package/skills/composing-vulnerability-report/references/THEORY.md +178 -0
  33. package/skills/composing-vulnerability-report/scripts/compose_report.py +396 -0
  34. package/skills/confirming-pentest-authorization/SKILL.md +247 -0
  35. package/skills/confirming-pentest-authorization/references/PLAYBOOK.md +189 -0
  36. package/skills/confirming-pentest-authorization/references/THEORY.md +167 -0
  37. package/skills/confirming-pentest-authorization/scripts/check_authorization.py +457 -0
  38. package/skills/defining-pentest-scope/SKILL.md +227 -0
  39. package/skills/defining-pentest-scope/references/PLAYBOOK.md +238 -0
  40. package/skills/defining-pentest-scope/references/THEORY.md +170 -0
  41. package/skills/defining-pentest-scope/scripts/define_scope.py +472 -0
  42. package/skills/detecting-command-injection-patterns/SKILL.md +144 -0
  43. package/skills/detecting-command-injection-patterns/references/PLAYBOOK.md +302 -0
  44. package/skills/detecting-command-injection-patterns/references/THEORY.md +206 -0
  45. package/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py +290 -0
  46. package/skills/detecting-debug-endpoints/SKILL.md +207 -0
  47. package/skills/detecting-debug-endpoints/references/PLAYBOOK.md +402 -0
  48. package/skills/detecting-debug-endpoints/references/THEORY.md +218 -0
  49. package/skills/detecting-debug-endpoints/scripts/probe_debug.py +518 -0
  50. package/skills/detecting-directory-listing/SKILL.md +206 -0
  51. package/skills/detecting-directory-listing/references/PLAYBOOK.md +277 -0
  52. package/skills/detecting-directory-listing/references/THEORY.md +203 -0
  53. package/skills/detecting-directory-listing/scripts/probe_directory_listing.py +180 -0
  54. package/skills/detecting-eval-exec-usage/SKILL.md +128 -0
  55. package/skills/detecting-eval-exec-usage/references/PLAYBOOK.md +306 -0
  56. package/skills/detecting-eval-exec-usage/references/THEORY.md +159 -0
  57. package/skills/detecting-eval-exec-usage/scripts/scan_eval.py +223 -0
  58. package/skills/detecting-exposed-secrets-files/SKILL.md +179 -0
  59. package/skills/detecting-exposed-secrets-files/references/PLAYBOOK.md +274 -0
  60. package/skills/detecting-exposed-secrets-files/references/THEORY.md +174 -0
  61. package/skills/detecting-exposed-secrets-files/scripts/probe_secrets.py +207 -0
  62. package/skills/detecting-insecure-deserialization/SKILL.md +148 -0
  63. package/skills/detecting-insecure-deserialization/references/PLAYBOOK.md +333 -0
  64. package/skills/detecting-insecure-deserialization/references/THEORY.md +199 -0
  65. package/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py +250 -0
  66. package/skills/detecting-sql-injection-patterns/SKILL.md +161 -0
  67. package/skills/detecting-sql-injection-patterns/references/PLAYBOOK.md +317 -0
  68. package/skills/detecting-sql-injection-patterns/references/THEORY.md +261 -0
  69. package/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py +354 -0
  70. package/skills/detecting-ssl-cert-issues/SKILL.md +182 -0
  71. package/skills/detecting-ssl-cert-issues/references/PLAYBOOK.md +203 -0
  72. package/skills/detecting-ssl-cert-issues/references/THEORY.md +133 -0
  73. package/skills/detecting-ssl-cert-issues/scripts/check_cert_chain.py +481 -0
  74. package/skills/detecting-weak-cryptography/SKILL.md +147 -0
  75. package/skills/detecting-weak-cryptography/references/PLAYBOOK.md +466 -0
  76. package/skills/detecting-weak-cryptography/references/THEORY.md +194 -0
  77. package/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py +417 -0
  78. package/skills/fingerprinting-server-software/SKILL.md +191 -0
  79. package/skills/fingerprinting-server-software/references/PLAYBOOK.md +337 -0
  80. package/skills/fingerprinting-server-software/references/THEORY.md +183 -0
  81. package/skills/fingerprinting-server-software/scripts/fingerprint_server.py +347 -0
  82. package/skills/generating-executive-summary/SKILL.md +261 -0
  83. package/skills/generating-executive-summary/references/PLAYBOOK.md +201 -0
  84. package/skills/generating-executive-summary/references/THEORY.md +195 -0
  85. package/skills/generating-executive-summary/scripts/exec_summary.py +538 -0
  86. package/skills/mapping-findings-to-owasp-top10/SKILL.md +235 -0
  87. package/skills/mapping-findings-to-owasp-top10/references/PLAYBOOK.md +193 -0
  88. package/skills/mapping-findings-to-owasp-top10/references/THEORY.md +160 -0
  89. package/skills/mapping-findings-to-owasp-top10/scripts/map_owasp.py +540 -0
  90. package/skills/performing-penetration-testing/SKILL.md +282 -190
  91. package/skills/performing-penetration-testing/references/OWASP_TOP_10.md +22 -0
  92. package/skills/performing-penetration-testing/references/REMEDIATION_PLAYBOOK.md +46 -0
  93. package/skills/performing-penetration-testing/references/SECURITY_HEADERS.md +41 -0
  94. package/skills/performing-penetration-testing/scripts/code_security_scanner.py +144 -79
  95. package/skills/performing-penetration-testing/scripts/dependency_auditor.py +116 -93
  96. package/skills/performing-penetration-testing/scripts/security_scanner.py +574 -446
  97. package/skills/probing-dangerous-http-methods/SKILL.md +182 -0
  98. package/skills/probing-dangerous-http-methods/references/PLAYBOOK.md +234 -0
  99. package/skills/probing-dangerous-http-methods/references/THEORY.md +145 -0
  100. package/skills/probing-dangerous-http-methods/scripts/probe_methods.py +263 -0
  101. package/skills/recording-pentest-engagement/SKILL.md +253 -0
  102. package/skills/recording-pentest-engagement/references/PLAYBOOK.md +203 -0
  103. package/skills/recording-pentest-engagement/references/THEORY.md +195 -0
  104. package/skills/recording-pentest-engagement/scripts/record_engagement.py +461 -0
  105. package/skills/scanning-for-hardcoded-secrets/SKILL.md +215 -0
  106. package/skills/scanning-for-hardcoded-secrets/references/PLAYBOOK.md +325 -0
  107. package/skills/scanning-for-hardcoded-secrets/references/THEORY.md +175 -0
  108. package/skills/scanning-for-hardcoded-secrets/scripts/scan_secrets.py +395 -0
  109. package/skills/tracing-transitive-vulnerabilities/SKILL.md +235 -0
  110. package/skills/tracing-transitive-vulnerabilities/references/PLAYBOOK.md +233 -0
  111. package/skills/tracing-transitive-vulnerabilities/references/THEORY.md +138 -0
  112. 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)