Commit 2d7227c
committed
Fix: Validation gap; high severity; confidence: certain.
=== Affected Locations
`dnscrypt-proxy/oblivious_doh.go:167`
=== Summary
`decryptResponse()` reads a 2-byte length field from decrypted ODoH plaintext without first verifying that the plaintext is at least 2 bytes long. A validly decrypting attacker-controlled response with 0-1 bytes of plaintext causes a slice panic and process denial of service.
=== Provenance
Verified from the reported finding and reproduced against reachable production call sites. Reproduction used a temporary test that built a real decryptable ODoH response and confirmed the panic path. Source report provenance includes Swival Security Scanner: https://swival.dev
=== Preconditions
Attacker controls a decryptable ODoH response plaintext shorter than 2 bytes, which in practice requires operating the ODoH target or otherwise possessing the response secrets.
=== Proof
`dnscrypt-proxy/query_processing.go:175` and `dnscrypt-proxy/serversInfo.go:1060` pass attacker-controlled ODoH replies into `decryptResponse()`.
In `dnscrypt-proxy/oblivious_doh.go:167`, the function executes `binary.BigEndian.Uint16(responsePlaintext[0:2])` immediately after decryption.
No prior check enforces `len(responsePlaintext) >= 2`.
When decryption yields an empty or 1-byte plaintext, `responsePlaintext[0:2]` panics with an out-of-bounds slice, terminating the process.
This was reproduced with a temporary Go test that generated a real ODoH query, reconstructed the matching HPKE server context, returned an AEAD-authenticated response with empty plaintext, and observed the panic during `decryptResponse()`.
=== Why This Is A Real Bug
The input is reachable from production network paths, the panic occurs before any recovery in the affected flow, and a panic in this process is a denial of service. The attacker capability is constrained but realistic for a malicious or compromised ODoH target, matching the product threat surface.
=== Fix Requirement
Reject decrypted ODoH plaintexts shorter than 2 bytes before reading the length field.
=== Patch Rationale
The patch adds a minimum-length check on `responsePlaintext` before slicing `responsePlaintext[0:2]`. This converts the crash condition into normal malformed-response handling while preserving existing behavior for well-formed inputs.
=== Residual Risk
None
=== Patch
`004-short-decrypted-odoh-plaintext-triggers-out-of-bounds-read.patch` adds a guard in `dnscrypt-proxy/oblivious_doh.go` to verify `len(responsePlaintext) >= 2` before calling `binary.BigEndian.Uint16(...)`, returning an error for malformed short plaintexts instead of panicking.1 parent bac7789 commit 2d7227c
1 file changed
+3
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
180 | 180 | | |
181 | 181 | | |
182 | 182 | | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
183 | 186 | | |
184 | 187 | | |
185 | 188 | | |
| |||
0 commit comments