@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,203 @@
|
|
|
1
|
+
# Certificate Posture Remediation Playbook
|
|
2
|
+
|
|
3
|
+
## Enable OCSP stapling
|
|
4
|
+
|
|
5
|
+
### nginx
|
|
6
|
+
|
|
7
|
+
```nginx
|
|
8
|
+
server {
|
|
9
|
+
listen 443 ssl http2;
|
|
10
|
+
server_name example.com;
|
|
11
|
+
|
|
12
|
+
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
|
|
13
|
+
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
|
|
14
|
+
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
|
|
15
|
+
|
|
16
|
+
ssl_stapling on;
|
|
17
|
+
ssl_stapling_verify on;
|
|
18
|
+
resolver 1.1.1.1 8.8.8.8 valid=300s;
|
|
19
|
+
resolver_timeout 5s;
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The `ssl_trusted_certificate` directive is REQUIRED for stapling to
|
|
24
|
+
work — nginx uses it to verify the OCSP response signature.
|
|
25
|
+
|
|
26
|
+
Reload: `nginx -t && systemctl reload nginx`
|
|
27
|
+
|
|
28
|
+
Verify:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
openssl s_client -connect example.com:443 -status < /dev/null 2>&1 | grep -A 20 "OCSP response:"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Expected: a populated OCSP response block, NOT "no response sent".
|
|
35
|
+
|
|
36
|
+
### Caddy
|
|
37
|
+
|
|
38
|
+
Auto-enabled since Caddy 2.0. No config needed. Verify with the same
|
|
39
|
+
openssl command.
|
|
40
|
+
|
|
41
|
+
### Apache (httpd 2.4)
|
|
42
|
+
|
|
43
|
+
```apache
|
|
44
|
+
SSLUseStapling on
|
|
45
|
+
SSLStaplingCache shmcb:/var/run/ocsp(150000)
|
|
46
|
+
SSLStaplingResponderTimeout 5
|
|
47
|
+
SSLStaplingReturnResponderErrors off
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Place `SSLStaplingCache` at the global / virtualhost-shared scope, not
|
|
51
|
+
inside a single virtualhost.
|
|
52
|
+
|
|
53
|
+
### HAProxy
|
|
54
|
+
|
|
55
|
+
```haproxy
|
|
56
|
+
frontend https
|
|
57
|
+
bind :443 ssl crt /etc/ssl/private/cert.pem
|
|
58
|
+
# Manual stapling — HAProxy doesn't fetch OCSP itself
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
HAProxy requires an external OCSP fetcher (e.g., `haproxy-ocsp-updater`
|
|
62
|
+
or systemd timer running `openssl ocsp` and writing to a `.ocsp` file
|
|
63
|
+
that HAProxy auto-loads).
|
|
64
|
+
|
|
65
|
+
## Fix chain order
|
|
66
|
+
|
|
67
|
+
Most common cause: `fullchain.pem` is correct but operators serve
|
|
68
|
+
`cert.pem` (leaf only) or `chain.pem` (intermediate only). Verify:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
openssl crl2pkcs7 -nocrl -certfile /etc/letsencrypt/live/example.com/fullchain.pem \
|
|
72
|
+
| openssl pkcs7 -print_certs -noout
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Expected output: leaf subject first, then intermediate(s). If you see
|
|
76
|
+
the root subject anywhere, the wrong file is being served. Update
|
|
77
|
+
nginx/Apache config to point at `fullchain.pem` (Let's Encrypt) or
|
|
78
|
+
rebuild from `cat cert.pem intermediate.pem > fullchain.pem` (NOT
|
|
79
|
+
`intermediate.pem cert.pem`).
|
|
80
|
+
|
|
81
|
+
## SCT shortage
|
|
82
|
+
|
|
83
|
+
You cannot add SCTs to an issued cert. Reissue from a CA that submits
|
|
84
|
+
to ≥2 CT logs:
|
|
85
|
+
|
|
86
|
+
### Let's Encrypt (default)
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
sudo certbot certonly --nginx -d example.com --force-renewal
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Let's Encrypt submits to ≥3 logs at issuance.
|
|
93
|
+
|
|
94
|
+
### Verify SCTs post-issuance
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -text \
|
|
98
|
+
| grep -A 4 "CT Precertificate"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
You should see ≥2 `Signed Certificate Timestamp:` blocks.
|
|
102
|
+
|
|
103
|
+
Or cross-check via crt.sh:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
curl -s "https://crt.sh/?q=example.com&output=json" | jq '.[0].id'
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## AIA correctness
|
|
110
|
+
|
|
111
|
+
If your cert is from a public CA and AIA is missing, contact the CA
|
|
112
|
+
support team — this is unusual.
|
|
113
|
+
|
|
114
|
+
If your cert is from a private CA, edit the CA's issuance template to
|
|
115
|
+
include AIA URLs. For step-ca:
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
authority:
|
|
119
|
+
template: |
|
|
120
|
+
{
|
|
121
|
+
"extensions": {
|
|
122
|
+
"authorityInfoAccess": [
|
|
123
|
+
{"id": "ocsp", "value": "http://ocsp.internal.example.com/"},
|
|
124
|
+
{"id": "caIssuers", "value": "http://ca.internal.example.com/intermediate.crt"}
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Wildcard scope tightening
|
|
131
|
+
|
|
132
|
+
You cannot narrow an issued cert. Reissue:
|
|
133
|
+
|
|
134
|
+
### Let's Encrypt — replace wildcard with explicit SANs
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
sudo certbot certonly --nginx \
|
|
138
|
+
-d example.com \
|
|
139
|
+
-d www.example.com \
|
|
140
|
+
-d api.example.com \
|
|
141
|
+
-d app.example.com
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This issues one cert with explicit SAN list instead of a wildcard.
|
|
145
|
+
Performance is identical at handshake time; blast radius if private
|
|
146
|
+
key compromised is bounded to the SAN list.
|
|
147
|
+
|
|
148
|
+
### Move to per-service certs
|
|
149
|
+
|
|
150
|
+
For high-security postures (banking, healthcare), issue one cert per
|
|
151
|
+
service so a key compromise on `internal-admin.example.com` doesn't
|
|
152
|
+
allow MITM on `app.example.com`. Use Caddy with auto-issuance per host
|
|
153
|
+
or certbot with `--cert-name` per service.
|
|
154
|
+
|
|
155
|
+
## Key Usage fix
|
|
156
|
+
|
|
157
|
+
CA-side issuance config. For step-ca:
|
|
158
|
+
|
|
159
|
+
```yaml
|
|
160
|
+
keyUsage:
|
|
161
|
+
- digitalSignature
|
|
162
|
+
- keyEncipherment
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
For public CAs, this is set correctly by default; missing KU on a
|
|
166
|
+
public cert means contact CA support.
|
|
167
|
+
|
|
168
|
+
## CI posture monitoring
|
|
169
|
+
|
|
170
|
+
Run on every deploy + nightly:
|
|
171
|
+
|
|
172
|
+
```yaml
|
|
173
|
+
- name: Certificate posture audit
|
|
174
|
+
run: |
|
|
175
|
+
python3 plugins/security/penetration-tester/skills/detecting-ssl-cert-issues/scripts/check_cert_chain.py \
|
|
176
|
+
"${{ secrets.PROD_URL }}" \
|
|
177
|
+
--authorized \
|
|
178
|
+
--min-severity medium \
|
|
179
|
+
--format json \
|
|
180
|
+
--output cert-posture.json
|
|
181
|
+
- uses: actions/upload-artifact@v4
|
|
182
|
+
with:
|
|
183
|
+
name: cert-posture
|
|
184
|
+
path: cert-posture.json
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Pair with skill #1 `analyzing-tls-config` for a complete TLS-layer
|
|
188
|
+
audit on the same target.
|
|
189
|
+
|
|
190
|
+
## Verification after remediation
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-ssl-cert-issues/scripts/check_cert_chain.py \
|
|
194
|
+
https://example.com \
|
|
195
|
+
--authorized \
|
|
196
|
+
--min-severity high
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Expected: exit code 0, no HIGH / CRITICAL findings.
|
|
200
|
+
|
|
201
|
+
For a paranoid pre-launch check, drop `--min-severity` to surface all
|
|
202
|
+
LOW findings — they're operational backlog hardening rather than
|
|
203
|
+
blockers.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Certificate Posture Theory
|
|
2
|
+
|
|
3
|
+
## OCSP stapling — why it matters
|
|
4
|
+
|
|
5
|
+
OCSP (RFC 6960) lets clients ask the issuing CA "is this cert still
|
|
6
|
+
valid?" at handshake time. The problem: every client phoning home for
|
|
7
|
+
every connection (a) adds latency, (b) leaks browsing metadata to the
|
|
8
|
+
CA, (c) creates a CA-side single point of failure.
|
|
9
|
+
|
|
10
|
+
OCSP stapling (RFC 6066 `status_request` extension) fixes this. The
|
|
11
|
+
server periodically fetches a signed OCSP response from the CA, caches
|
|
12
|
+
it, and serves it inline during the TLS handshake. Clients trust the
|
|
13
|
+
stapled response because the CA's signature is verifiable offline.
|
|
14
|
+
|
|
15
|
+
If your server doesn't staple:
|
|
16
|
+
|
|
17
|
+
- **SOC2 CC6.6 / CC6.7** auditors flag this as transmission-confidentiality
|
|
18
|
+
weakness because the CA learns who's connecting where.
|
|
19
|
+
- **Privacy regulators** treat OCSP traffic as PII metadata.
|
|
20
|
+
- **Latency** — first-handshake users pay an extra round trip to the CA.
|
|
21
|
+
- **Reliability** — if the CA's OCSP responder is down, clients with
|
|
22
|
+
must-staple cached fail-closed (the original purpose of Must-Staple).
|
|
23
|
+
|
|
24
|
+
## Certificate Transparency — why ≥2 SCTs
|
|
25
|
+
|
|
26
|
+
CT logs (RFC 6962) are append-only, publicly auditable records of every
|
|
27
|
+
issued certificate. The intent: if a CA mis-issues a cert (e.g., for
|
|
28
|
+
google.com to an attacker), someone monitoring the logs sees it.
|
|
29
|
+
|
|
30
|
+
The model relies on browser enforcement. Chrome's CT policy (active
|
|
31
|
+
since 2018) requires every TLS cert to be accompanied by ≥2 Signed
|
|
32
|
+
Certificate Timestamps from independently-operated logs. Delivery
|
|
33
|
+
options:
|
|
34
|
+
|
|
35
|
+
1. **Embedded** — SCTs baked into the cert at issuance via the
|
|
36
|
+
`precertificate_signed_certificate_timestamps` extension (the common
|
|
37
|
+
path; what this skill checks).
|
|
38
|
+
2. **TLS extension** — server sends SCTs in the handshake via the
|
|
39
|
+
`signed_certificate_timestamp` extension.
|
|
40
|
+
3. **OCSP-stapled SCTs** — SCTs delivered alongside an OCSP staple.
|
|
41
|
+
|
|
42
|
+
Public CAs (Let's Encrypt, ZeroSSL, DigiCert, etc.) all submit to ≥2
|
|
43
|
+
logs at issuance. If the leaf has fewer than 2 SCTs, the most common
|
|
44
|
+
cause is a private CA cert masquerading as public.
|
|
45
|
+
|
|
46
|
+
Chrome enforcement is silent — connections fail, users see generic
|
|
47
|
+
errors, and the diagnostic surface is limited. This skill surfaces the
|
|
48
|
+
SCT shortage explicitly.
|
|
49
|
+
|
|
50
|
+
## Chain ordering — RFC 5246 §7.4.2
|
|
51
|
+
|
|
52
|
+
The TLS Certificate message includes a `certificate_list` field. The
|
|
53
|
+
RFC requires it to be ordered: leaf first, each subsequent certificate
|
|
54
|
+
must directly certify the one preceding it, root SHOULD be excluded
|
|
55
|
+
(clients have it in their trust store; sending it is wasted bytes).
|
|
56
|
+
|
|
57
|
+
Common misorder causes:
|
|
58
|
+
|
|
59
|
+
- Cert files concatenated in alphabetical order rather than chain order.
|
|
60
|
+
- A migration where `cat *.pem > fullchain.pem` orders by filename.
|
|
61
|
+
- An ops engineer who saw the chain rejected and reordered "fix" trips
|
|
62
|
+
by also including the root.
|
|
63
|
+
|
|
64
|
+
Older clients (Java 6, older curl) reject out-of-order chains. Modern
|
|
65
|
+
browsers tolerate but log. Either way, an audit catches it; a slow
|
|
66
|
+
handshake or odd-platform compatibility report leads back to chain
|
|
67
|
+
ordering.
|
|
68
|
+
|
|
69
|
+
## AIA extension — Authority Info Access
|
|
70
|
+
|
|
71
|
+
RFC 5280 §4.2.2.1 defines two access methods worth tracking:
|
|
72
|
+
|
|
73
|
+
- **CA Issuers** — URL where the issuing intermediate cert can be
|
|
74
|
+
downloaded. Some clients fetch missing intermediates here ("AIA chasing").
|
|
75
|
+
- **OCSP responder** — URL where revocation can be queried.
|
|
76
|
+
|
|
77
|
+
Missing AIA → clients with incomplete chains have no recovery path;
|
|
78
|
+
clients that don't trust a stapled OCSP response have nowhere to verify.
|
|
79
|
+
|
|
80
|
+
Both fields are CA-side issuance config. Public CAs include them by
|
|
81
|
+
default. A leaf cert without AIA is almost certainly from a private CA
|
|
82
|
+
or a misconfigured private PKI.
|
|
83
|
+
|
|
84
|
+
## Wildcard scope — CA/B Baseline Requirements §3.2.2
|
|
85
|
+
|
|
86
|
+
CA/Browser Forum BR forbids wildcards at certain scopes:
|
|
87
|
+
|
|
88
|
+
- `*.com`, `*.net`, etc. — public suffix; would cover every site on the
|
|
89
|
+
TLD. Public CAs MUST refuse to issue.
|
|
90
|
+
- `*.example` (single-label) — same reasoning at private-TLD level.
|
|
91
|
+
|
|
92
|
+
Allowed scope: `*.example.com` (covers `api.example.com` but not
|
|
93
|
+
`example.com` itself, and not `x.api.example.com`).
|
|
94
|
+
|
|
95
|
+
A public cert with over-broad wildcard scope means the CA mis-issued
|
|
96
|
+
and may be subject to log-monitor investigation; private-CA wildcards
|
|
97
|
+
at apex-TLD scope are equally dangerous because anyone with the
|
|
98
|
+
private key can MITM any subdomain.
|
|
99
|
+
|
|
100
|
+
## Key Usage extension — RFC 5280 §4.2.1.3
|
|
101
|
+
|
|
102
|
+
The KU extension asserts what cryptographic operations the cert's
|
|
103
|
+
public key is authorized for. TLS server certs need at minimum:
|
|
104
|
+
|
|
105
|
+
- `digitalSignature` — for the server's ServerKeyExchange signature in
|
|
106
|
+
non-static-RSA modes
|
|
107
|
+
- `keyEncipherment` — for static RSA key transport (legacy, rare in
|
|
108
|
+
modern stacks)
|
|
109
|
+
|
|
110
|
+
Missing `digitalSignature` on a TLS server cert is unusual; strict
|
|
111
|
+
clients reject it.
|
|
112
|
+
|
|
113
|
+
## Chain length — operational concern
|
|
114
|
+
|
|
115
|
+
Modern CAs issue 2-cert chains: leaf + one intermediate (the root is
|
|
116
|
+
in client trust stores). Chains of 3+ usually mean:
|
|
117
|
+
|
|
118
|
+
- Cross-signing for backward compatibility (intentional, fine).
|
|
119
|
+
- Misconfiguration including the root (waste, fixable).
|
|
120
|
+
- Vendored chain from a different CA (rare, audit-flagged).
|
|
121
|
+
|
|
122
|
+
>4 certs raises handshake latency noticeably (more bytes, more
|
|
123
|
+
verification ops on the client side); flagged LOW for awareness.
|
|
124
|
+
|
|
125
|
+
## Primary sources
|
|
126
|
+
|
|
127
|
+
- [RFC 5246 — TLS 1.2 §7.4.2](https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.2)
|
|
128
|
+
- [RFC 5280 — Internet X.509 PKIX](https://datatracker.ietf.org/doc/html/rfc5280)
|
|
129
|
+
- [RFC 6066 — TLS Extension Definitions §8 (status_request)](https://datatracker.ietf.org/doc/html/rfc6066#section-8)
|
|
130
|
+
- [RFC 6960 — OCSP](https://datatracker.ietf.org/doc/html/rfc6960)
|
|
131
|
+
- [RFC 6962 — Certificate Transparency](https://datatracker.ietf.org/doc/html/rfc6962)
|
|
132
|
+
- [CA/Browser Forum Baseline Requirements](https://cabforum.org/baseline-requirements-documents/)
|
|
133
|
+
- [Chrome CT Policy](https://googlechrome.github.io/CertificateTransparency/ct_policy.html)
|