You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: spec-v1.0/security_and_privacy.md
+50-1Lines changed: 50 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,6 @@ Implementations of `did:webvh` **MUST** mitigate the following classes of attack
33
33
- Resolvers are advised to require a `Content-Length` header in HTTP responses before processing begins, allowing them to determine file size upfront and reject oversized logs before expending processing resources. The presence of HTTP range request support (`Accept-Ranges: bytes`) is a useful positive signal that a server is serving a static resource rather than dynamically generated content. Regardless of server behavior, since a declared `Content-Length` cannot itself be relied upon as a security guarantee, resolvers are advised to apply the following defensive practices:
34
34
35
35
- Apply a maximum byte limit on log file retrieval, terminating the connection if exceeded regardless of declared `Content-Length`; treat absence of `Content-Length` as grounds for a more conservative limit or outright rejection
36
-
- Commit to a resolution timestamp before beginning to read the log — typically the current time adjusted by an acceptable clock skew delta — and stop processing any log entries with a `versionTime` at or after that timestamp. This establishes a well-defined point-in-time of resolution and ensures that an adversarial server cannot extend processing indefinitely by streaming additional entries beyond that point
37
36
- Apply a hard timeout on the entire fetch-and-process operation for a single resolution request
38
37
- Apply rate limiting on resolution requests, particularly for previously-unseen DIDs
39
38
- Apply concurrency limits to bound the number of simultaneous resolution operations
@@ -87,6 +86,21 @@ A `did:webvh` identifier may include a domain component that was never actually
87
86
88
87
DID resource retrieval endpoints **MUST** be authenticated using TLS server authentication. Self-signed certificates **SHOULD NOT** be used in production. This requirement is not unique to the `did:webvh` method; it applies to all web traffic. While the verifiability of `did:webvh` ensures that any tampering with the contents of individual log entries is detectable, TLS provides additional protection against active network attacks (including truncation or withholding) and ensures the authenticity of the server providing the DID resources.
89
88
89
+
### Resolver Transport Hardening (SSRF and Network Boundary)
90
+
91
+
A `did:webvh` resolver acts as an HTTP client on behalf of an untrusted DID string — a Server-Side Request Forgery vector without explicit safeguards. Resolvers **MUST**:
92
+
93
+
1.**No automatic redirects.** Do not auto-follow HTTP 3xx responses when fetching `did.jsonl` or `did-witness.json`. If redirect-following is an opt-in, re-apply every check below at each target.
94
+
2.**IP-literal rejection.** Reject IPv4/IPv6 literal hosts both (a) after percent-decoding the DID's domain segment, and (b) after DNS resolution. Default deny: loopback (`127.0.0.0/8`, `::1`), private (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`), link-local (`169.254.0.0/16`, `fe80::/10`). Dev opt-ins permitted but off by default.
95
+
3.**Case-insensitive percent-decoding.** Per [[spec:rfc3986]] §2.1, normalise hex case **before** any allow/deny decision. Rejecting `%3A` but accepting `%3a` is non-compliant.
96
+
4.**Re-validate after decoding.** All host/path checks apply to decoded values. Percent-encoded IP literals and traversal sequences (`%2E%2E`, `%2e%2e`) **MUST** be rejected after decoding.
97
+
5.**Response size cap.** Enforce a max body size for both files; check `Content-Length` first; treat absence as grounds for a stricter cap or rejection. Suggested default: 5 MiB.
98
+
6.**Operation timeout.** Enforce a wall-clock timeout on the complete resolution. Suggested default: 30 s.
99
+
7.**HTTPS only.** Reject any non-`https` scheme, including after a redirect.
100
+
8.**No localhost in production.** Do not issue requests to `localhost`, `127.0.0.0/8`, `::1`, or names resolving to them. Test opt-ins off by default.
101
+
102
+
These are standard SSRF defences; stated normatively here because all four reviewed implementations were vulnerable to at least one of (1)–(4).
103
+
90
104
### Network Topology
91
105
92
106
Unlike DLT-based DID methods, `did:webvh` relies on web infrastructure and does not require peer-to-peer networking. However, implementations relying on CDN caching or load balancers **MUST** ensure these intermediaries do not serve stale or tampered DID data.
@@ -130,6 +144,29 @@ and refer to [did:web Security and Privacy Considerations](https://w3c-ccg.githu
130
144
`did:webvh`[[ref: Key Pre-Rotation]] approach provides enough flexibility for "post-quantum safety".
131
145
For guidance on post-quantum attacks mitigation, implementors **SHOULD** refer to [corresponding Implementation Guide section](https://didwebvh.info/latest/implementers-guide/prerotation-keys/#post-quantum-attacks).
132
146
147
+
### Resolver Validation Checklist (informative)
148
+
149
+
The following checklist maps normative resolver requirements to concrete
150
+
validation points, and is intended to assist conformance test suite authors and
151
+
implementers auditing their own resolver implementations. An entry appearing
152
+
here does not restate or replace the normative requirements defined in the
153
+
verification algorithm in this specification.
154
+
155
+
**Transport:** HTTPS only; no auto 3xx; reject IP literals before & after percent-decoding; reject private/loopback/link-local DNS resolutions in production; normalize percent-encoding case; validate path segments after decoding (`.`, `..`, `/`, `\`, NUL, leading/trailing whitespace); enforce max response size with `Content-Length` first; enforce a wall-clock timeout.
156
+
157
+
**Log structure:** unbroken `1, 2, 3, ...` version sequence; strictly increasing UTC ISO8601 `versionTime`; every `versionTime` ≤ now (bounded skew); `entryHash` chain verified for every entry; `method` is an explicitly supported value (never silently downgraded).
158
+
159
+
**SCID & identity:** first entry's `parameters.scid` is the genesis self-hash; every entry's `state.id` parses as a `did:webvh` DID; every entry's `state.id`[[ref: SCID]] equals first entry's `parameters.scid` and [[ref: SCID]] in the DID; requested DID matches at least one entry's `state.id`; `portable: true` only in first entry; [[ref: SCID]] never changes.
160
+
161
+
**Keys & proofs:** every proof has `type: DataIntegrityProof`, the `cryptosuite`
162
+
and `proofPurpose` required by the active `method`; `verificationMethod` key in
163
+
active `updateKeys`; under pre-rotation, `updateKeys` explicit in every entry
164
+
and every key hashes to a value in previous `nextKeyHashes`.
165
+
166
+
**Witnesses:**`threshold` is positive integer ≤ count of distinct `witnesses[].id`; all `witnesses[].id` distinct; threshold met by counting verified proofs from distinct witness identifiers, not total proof count; each accepted proof's `versionId` corresponds to an entry in the `did.jsonl` being verified; proofs verified with key from the `did:key` body; `did:key` DID URL in proofs reference the same key material in body and fragment (multibase values byte-equal).
167
+
168
+
**Failure modes:** unknown parameter values, malformed `witness`, hash algorithm mismatch, and cryptosuite mismatch all **MUST** fail resolution — never silently coerced.
169
+
133
170
## Privacy Considerations
134
171
135
172
This section addresses the privacy considerations in alignment with [[spec:RFC6973]] Section 5 and the [[spec:DID-CORE]] requirements in [DID Core 7.4](https://www.w3.org/TR/did-core/#privacy-requirements).
@@ -144,6 +181,18 @@ Resolution of a `did:webvh` identifier also exposes the resolver’s network act
144
181
145
182
DID data is stored on web servers. A compromise of the hosting infrastructure could allow tampering with DID resources. HTTPS and cryptographic signatures protect integrity, but confidentiality is not provided.
146
183
184
+
### Implementation Hygiene (informative)
185
+
186
+
The following practices are not unique to `did:webvh` but represent recurring
187
+
failure points observed across `did:webvh` DID Method implementations.
188
+
Implementers should treat these as baseline hygiene.
189
+
190
+
-**Dependency currency.** Keep cryptographic and HTTP dependencies on supported, patched versions. Run a vulnerability scanner (`cargo audit`, `pip-audit`, `npm audit`, OWASP Dependency-Check) on every build.
191
+
-**Filesystem permissions.** Private keys and secret-bearing configuration files **SHOULD** be created with owner-only permissions (e.g., `0600` on POSIX). **SHOULD NOT** read secret material from the current working directory or other untrusted locations by default.
192
+
-**CLI tools.****MUST NOT** print private keys, mnemonics, or other long-lived secrets to stdout/stderr or shell history. Where display is necessary, prompt before printing and offer a file-output alternative with restrictive permissions.
193
+
-**HTTPS certificate validation.****MUST NOT** disable certificate validation by default. Certificate pinning is not required (and incompatible with platform hosting), but ecosystems with appropriate trust models **MAY** opt in.
194
+
-**Error messages.** Resolvers **SHOULD NOT** include internal stack traces, file paths, or library versions in `problemDetails` returned to clients.
195
+
147
196
### Unsolicited Traffic
148
197
149
198
Publishing a DID Log does not inherently solicit inbound traffic beyond normal DID resolution. However, public exposure of service endpoints in the DID Document may increase unsolicited interactions. [[ref: DID Controllers]] SHOULD avoid publishing unnecessary endpoints.
0 commit comments